quad.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. PROGRAM Quad;
  2. {A demo which loads some graphics etc. Nice. Don't forget to distribute
  3. quaddata.inc!
  4. The sources for this game was found on a site that claims to only have
  5. PD stuff with the below header(which was only reindented), and the webmaster
  6. said that everything he published was sent to him with that purpose. We tried
  7. to contact the authors mentioned below via mail over internet, but that
  8. failed. If there is somebody that claims authorship of these programs,
  9. please mail [email protected], and the sources will be removed from our
  10. websites.
  11. ------------------------------------------------------------------------
  12. ORIGINAL Header:
  13. Programmed by: Justin Pierce
  14. Graphics by: Whitney Pierce
  15. Inspired by: Jos Dickman''s triple memory!
  16. -----
  17. Old version requires egavga.bgi. FPC doesn't require BGI's (VGA and VESA
  18. support are built in the Graph, others are ignored).}
  19. Uses Crt,Dos,Graph,
  20. GameUnit; {Supplied with FPC demoes package. Wrapper for
  21. mousesupport (via msmouse or api), and contains
  22. highscore routines}
  23. Const nox = 10;
  24. noy = 8;
  25. card_border = red;
  26. PicBufferSize = 64000; {Buffersize for deRLE'ed picture data}
  27. ComprBufferSize = 20000; {Buffer for diskread- RLE'ed data}
  28. PicsFilename = 'quaddata.dat'; {Name of picturesfile}
  29. ScoreFileName = 'quad.scr';
  30. Type
  31. pByte = ^Byte; {BufferTypes}
  32. Card = Record
  33. exposed: boolean;
  34. pic: byte;
  35. End;
  36. {Assigns an enumeration to each picture}
  37. PictureEnum= (zero,one,two,three,four,five,six,seven,eight,nine,colon,
  38. back,score,exit_b,score_b,chunk,p1,p2,p3,p4,p5,p6,p7,p8,
  39. p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20);
  40. {A pictures definition;
  41. x and y dimensions and offset in PicData buffer}
  42. Picture = packed Record
  43. start: longint;
  44. x,y: byte;
  45. End;
  46. {All pictures. This array, and the data in PicData is all pic info.}
  47. PictureArray= ARRAY[zero..p20] OF Picture;
  48. selected = Record
  49. x,y: byte;
  50. pic: byte;
  51. End;
  52. time_record = Record
  53. o_hr,o_min,o_sec,o_sec100: word;
  54. hr,min,sec,sec100: word;
  55. a_sec,a_min: word;
  56. End;
  57. Var b : array[1..nox,1..noy] Of card;
  58. Pics : PictureArray;
  59. PicData : PByte;
  60. s : array[1..4] Of selected;
  61. os : byte;
  62. turns : integer;
  63. off,ok,exit1: boolean;
  64. opened : byte;
  65. bgidirec : string;
  66. time : time_record;
  67. {
  68. Procedure fatal(fcall:String);
  69. Begin
  70. textmode(CO80);
  71. clrscr;
  72. Writeln('A fatal error has occured');
  73. Writeln('Error: ',fcall);
  74. Writeln;
  75. Write('Hit enter to halt program--');
  76. readln;
  77. halt;
  78. End;
  79. }
  80. Procedure ginit640x480x16(direc:String);
  81. Var grd,grmode: integer;
  82. Begin
  83. closegraph;
  84. grd := 9;{ detect;}
  85. grmode := 2;{ m800x600x16;}
  86. initgraph(grd,grmode,direc);
  87. setgraphmode(2);
  88. End;
  89. Procedure clean_board;
  90. Var x,y: byte;
  91. Begin
  92. y := 1;
  93. Repeat
  94. x := 1;
  95. Repeat
  96. b[x,y].pic := 0;
  97. b[x,y].exposed := false;
  98. inc(x);
  99. Until x>nox;
  100. inc(y);
  101. Until y>noy
  102. End;
  103. Procedure showpic(xp,yp:integer; tp:pictureenum);
  104. Var x,y,x1,y1: byte;
  105. tx: integer;
  106. Begin
  107. x := pics[tp].x; {mb[tp.start];}
  108. y := pics[tp].y; {mb[tp.start+1];}
  109. y1 := 1;
  110. tx := 0;
  111. Repeat
  112. x1 := 1;
  113. Repeat
  114. putpixel(xp+(x1-1),yp+(y1-1),picdata[pics[tp].start-1+tx]);
  115. inc(x1);
  116. inc(tx);
  117. Until x1>x;
  118. inc(y1);
  119. Until y1>y;
  120. End;
  121. Procedure NumberOutput(X,Y,Number:LONGINT;RightY:BOOLEAN);
  122. Var num: string;
  123. plc: byte;
  124. Begin
  125. str(number,num);
  126. If length(num)=1 Then
  127. insert('0',num,0);
  128. IF RightY THEN
  129. dec (x,length(num)*11);
  130. plc := 1;
  131. Repeat
  132. IF (Num[plc]>CHR(47)) AND (Num[plc]<CHR(58)) THEN
  133. showpic(((plc-1)*11)+X,Y,pictureenum(ORD(Zero)+ORD(Num[plc])-48));
  134. inc(plc);
  135. Until plc>length(num);
  136. End;
  137. Procedure update_secs;
  138. Begin
  139. showpic(605,453,colon);
  140. NumberOutput(615,453,time.a_sec,FALSE);
  141. End;
  142. Procedure showturn(x,y:integer);
  143. Begin
  144. hidemouse;
  145. If (x=0) And (y=0) Then
  146. NumberOutput(4,453,Turns,FALSE)
  147. ELSE
  148. NumberOutput(x,y,Turns,FALSE);
  149. showmouse;
  150. End;
  151. Procedure get_original_time;
  152. Begin
  153. With time Do
  154. Begin
  155. a_sec := 0;
  156. a_min := 0;
  157. gettime(o_hr,o_min,o_sec,o_sec100);
  158. gettime(hr,min,sec,sec100);
  159. End;
  160. End;
  161. Procedure update_time(ForcedUpdate:BOOLEAN);
  162. Begin
  163. With time Do
  164. Begin
  165. gettime(hr,min,sec,sec100);
  166. If sec<>o_sec Then
  167. Begin
  168. inc(a_sec);
  169. If a_sec<=60 Then update_secs;
  170. End;
  171. If a_sec>60 Then
  172. Begin
  173. a_sec := 0;
  174. inc(a_min);
  175. ForcedUpdate:=TRUE;
  176. End;
  177. IF ForcedUpdate THEN
  178. BEGIN
  179. Update_secs;
  180. showpic(606,453,colon);
  181. NumberOutput(606,453,time.a_min,TRUE);
  182. END;
  183. o_hr := hr;
  184. o_min := min;
  185. o_sec := sec;
  186. o_sec100 := sec;
  187. End;
  188. End;
  189. Procedure makecard(x,y:byte);
  190. Var xp,yp: integer;
  191. Begin
  192. hidemouse;
  193. xp := ((x-1)*63);
  194. yp := ((y-1)*56);
  195. setcolor(card_border);
  196. setfillstyle(1,0);
  197. bar(xp+1,yp+1,xp+62,yp+55);
  198. rectangle(xp,yp,xp+63,yp+56);
  199. If b[x,y].exposed=false Then
  200. Begin
  201. showpic(xp+1,yp+1,back);
  202. End;
  203. showmouse;
  204. If b[x,y].exposed=true Then
  205. Begin
  206. hidemouse;
  207. showpic(xp+7,yp+4,pictureenum(ORD(b[x,y].pic)+ORD(p1)-1));
  208. showmouse;
  209. End;
  210. End;
  211. Function used(pic:byte): byte;
  212. Var cx,cy,u: byte;
  213. Begin
  214. used := 0;
  215. u := 0;
  216. cy := 1;
  217. Repeat
  218. cx := 1;
  219. Repeat
  220. If b[cx,cy].pic=pic Then inc(u);
  221. inc(cx);
  222. Until cx>nox;
  223. inc(cy);
  224. Until cy>noy;
  225. used := u;
  226. End;
  227. Procedure set_board;
  228. CONST Outstr=#219+#219+#219+#219+#219+#219+#219+#219+#219+#219+#219+#219+#219+
  229. #219+#219+#219+#219+#219+#219+#219+#219+#219+#219+#219+#219+
  230. #219+#219+#219+#219;
  231. Var cx,cy,pic: byte;
  232. Begin
  233. setcolor(0);
  234. outtextxy(0,470,OutStr);
  235. setcolor(green);
  236. outtextxy(0,470,'Dealing board, please wait...');
  237. Delay(1000);
  238. cy := 1;
  239. Repeat
  240. cx := 1;
  241. Repeat
  242. Repeat
  243. pic := random(20)+1;
  244. Until used(pic)<4;
  245. b[cx,cy].pic := pic;
  246. makecard(cx,cy);
  247. inc(cx);
  248. Until cx>nox;
  249. inc(cy);
  250. Until cy>noy;
  251. setcolor(0);
  252. outtextxy(0,470,OutStr);
  253. End;
  254. Procedure fire_works;
  255. Const
  256. nof = 30;
  257. Type
  258. fires = Record
  259. x,y: Longint;
  260. direct: longint;
  261. speed: Longint;
  262. explode: boolean;
  263. color: byte;
  264. oex: longint;
  265. End;
  266. Var fire: array[1..nof] Of fires;
  267. Procedure clean_fires;
  268. Var c: longint;
  269. Begin
  270. c := 1;
  271. Repeat
  272. fire[c].direct := random(2)+1;
  273. fire[c].color := random(15)+1;
  274. fire[c].x := random(639);
  275. fire[c].y := 479;
  276. fire[c].explode := false;
  277. fire[c].speed := random(20)+15;
  278. fire[c].oex := 1;
  279. inc(c);
  280. Until c>nof;
  281. End;
  282. Procedure inact;
  283. Var c: longint;
  284. Begin
  285. c := 1;
  286. Repeat
  287. If fire[c].explode=false Then
  288. Begin
  289. setcolor(fire[c].color);
  290. circle(fire[c].x,fire[c].y,1);
  291. End;
  292. If (fire[c].explode=true) And (fire[c].oex<10) Then
  293. Begin
  294. setcolor(fire[c].color);
  295. circle(fire[c].x,fire[c].y,fire[c].oex);
  296. setcolor(random(15)+1);
  297. circle(fire[c].x,fire[c].y,fire[c].oex-1);
  298. End;
  299. inc(c);
  300. Until c>nof;
  301. delay(75);
  302. gotoxy(1,1);
  303. c := 1;
  304. Repeat
  305. setcolor(0);
  306. circle(fire[c].x,fire[c].y,1);
  307. If (fire[c].explode=true) And (fire[c].oex<10) Then
  308. Begin
  309. circle(fire[c].x,fire[c].y,fire[c].oex);
  310. circle(fire[c].x,fire[c].y,fire[c].oex-1);
  311. inc(fire[c].oex);
  312. End;
  313. If fire[c].explode=false Then
  314. Begin
  315. dec(fire[c].speed,1);
  316. dec(fire[c].y,fire[c].speed);
  317. If fire[c].direct=1 Then inc(fire[c].x,2);
  318. If fire[c].direct=2 Then dec(fire[c].x,2);
  319. If fire[c].speed<=(-1*LONGINT(random(11))) Then
  320. fire[c].explode := true;
  321. End;
  322. inc(c);
  323. Until c>nof;
  324. c := 1;
  325. End;
  326. Function exploded: boolean;
  327. Var c: longint;
  328. m: boolean;
  329. Begin
  330. c := 1;
  331. m := true;
  332. Repeat
  333. If fire[c].oex<6 Then m := false;
  334. inc(c);
  335. Until (c>nof);
  336. exploded := m;
  337. End;
  338. Begin
  339. cleardevice;
  340. Repeat
  341. clean_fires;
  342. Repeat
  343. inact;
  344. Until (exploded=true) Or (keypressed);
  345. Until keypressed;
  346. End;
  347. Procedure win;
  348. Var m,s: string;
  349. I,J : LONGINT;
  350. Begin
  351. hidemouse;
  352. fire_works;
  353. cleardevice;
  354. closegraph;
  355. textmode(co80+font8x8);
  356. clrscr;
  357. I:=SlipInScore(Turns);
  358. GotoXY(1,23);
  359. Writeln('Game Over, turns needed = ',Turns);
  360. FOR J:=9 TO 22 DO
  361. BEGIN
  362. GotoXY(20,J);
  363. Write(' ':38);
  364. END;
  365. IF I<>0 THEN
  366. BEGIN
  367. ShowHighScore;
  368. {$IFDEF USEGRAPHICS}
  369. GrInputStr(S,20,21-I,16,12,10,FALSE,AlfaBeta);
  370. {$ELSE}
  371. InputStr(S,20,21-I,10,FALSE,AlfaBeta);
  372. {$ENDIF}
  373. IF Length(S)<12 THEN
  374. BEGIN
  375. str(time.a_min,m);
  376. S:=S+'['+m+':';
  377. str(time.a_sec,m);
  378. S:=S+'m'+']';
  379. END;
  380. HighScore[I-1].Name:=S;
  381. END;
  382. ShowHighScore;
  383. ginit640x480x16(bgidirec);
  384. off := false;
  385. clean_board;
  386. set_board;
  387. turns := 0;
  388. showpic(0,450,score);
  389. showpic(80,450,score_b);
  390. showpic(150,450,exit_b);
  391. showpic(569,450,score);
  392. showturn(0,0);
  393. exit1 := false;
  394. get_original_time;
  395. update_time(True);
  396. SetMousePosition(0,0);
  397. showmouse;
  398. End;
  399. Procedure show_scores;
  400. Var x,y,c: byte;
  401. Begin
  402. hidemouse;
  403. y := 1;
  404. Repeat
  405. x := 1;
  406. showpic(x+135,(y-1)*21,score);
  407. showpic(x,(y-1)*21,score);
  408. showpic(x+204,(y-1)*21,score);
  409. Repeat
  410. showpic(((x-1)*10)+3,(y-1)*21,chunk);
  411. inc(x);
  412. Until x>20;
  413. inc(y);
  414. Until y>10;
  415. c := 0;
  416. Repeat
  417. If HighScore[c].name<>'' Then
  418. Begin
  419. setcolor(white);
  420. outtextxy(4,7+(c*21),HighScore[c].name);
  421. turns := HighScore[c].Score;
  422. showturn(211,3+(c*21));
  423. End;
  424. inc(c);
  425. Until c>9;
  426. turns := 0;
  427. gotoxy(1,1);
  428. readln;
  429. off := false;
  430. clean_board;
  431. set_board;
  432. turns := 0;
  433. showpic(0,450,score);
  434. showpic(80,450,score_b);
  435. showpic(150,450,exit_b);
  436. showpic(569,450,score);
  437. showturn(0,0);
  438. exit1 := false;
  439. get_original_time;
  440. update_time(True);
  441. SetMousePosition(0,0);
  442. showmouse;
  443. End;
  444. Procedure interpret;
  445. Var mpx,mpy: byte;
  446. ms_mx,ms_my,ms_but : LONGINT;
  447. Begin
  448. GetMouseState(ms_mx,ms_my,ms_but);
  449. ms_mx:=ms_mx shr 1;;
  450. If ms_but=0 Then off := false;
  451. If ((ms_but AND 1)=1) And (off=false) Then
  452. Begin
  453. off := true;
  454. mpx := ms_mx*2 Div 63;
  455. mpy := (ms_my) Div 56;
  456. If (ms_mx*2>=80) And (ms_mx*2<=129) And (ms_my>=450) And (ms_my<=466)
  457. And (ok=true) Then show_scores;
  458. If (ms_mx*2>=150) And (ms_mx*2<=199) And (ms_my>=450) And (ms_my<=466)
  459. Then
  460. Begin
  461. exit1 := true;
  462. End;
  463. inc(mpx);
  464. inc(mpy);
  465. If (b[mpx,mpy].exposed=false) And (mpx>=1) And (mpy>=1) And (mpx<=10) And (mpy<=8)
  466. Then
  467. Begin
  468. setfillstyle(1,0);
  469. bar(80,450,130,466);
  470. ok := false;
  471. b[mpx,mpy].exposed := true;
  472. makecard(mpx,mpy);
  473. inc(os);
  474. s[os].x := mpx;
  475. s[os].y := mpy;
  476. s[os].pic := b[mpx,mpy].pic;
  477. End;
  478. End;
  479. If os=4 Then
  480. Begin
  481. inc(turns);
  482. showturn(0,0);
  483. os := 0;
  484. delay(700);
  485. inc(opened);
  486. If Not((s[1].pic=s[2].pic) And (s[1].pic=s[3].pic) And (s[1].pic=s[4].pic)) Then
  487. Begin
  488. dec(opened);
  489. b[s[1].x,s[1].y].exposed := false;
  490. b[s[2].x,s[2].y].exposed := false;
  491. b[s[3].x,s[3].y].exposed := false;
  492. b[s[4].x,s[4].y].exposed := false;
  493. makecard(s[1].x,s[1].y);
  494. makecard(s[2].x,s[2].y);
  495. makecard(s[3].x,s[3].y);
  496. makecard(s[4].x,s[4].y);
  497. End;
  498. If opened=20 Then win;
  499. End;
  500. If NOT ok Then
  501. update_time(FALSE);
  502. End;
  503. Procedure load_pics(PicBuf:PByte);
  504. {loads picture structures from disc}
  505. VAR F : File;
  506. Buf1Ind,
  507. I,J,K : LONGINT;
  508. TData : PByte;
  509. Begin
  510. GetMem(TData,ComprBufferSize); { allocate buffer}
  511. Assign(F,Picsfilename); { Open file}
  512. {$I-}
  513. Reset(F,1);
  514. {$I+}
  515. If ioresult<>0 Then
  516. BEGIN
  517. TextMode(CO80);
  518. Writeln('Fatal error, couldn''t find graphics data file quaddata.dat');
  519. HALT;
  520. END;
  521. {Read the array with picture information; (X,Y dimensions and offset in
  522. binary data)}
  523. BlockRead(F,pics,SIZEOF(Picture)*(ORD(p20)-ORD(zero)+1),I);
  524. {Read some slackspace which shouldn't be in the file ;-)}
  525. blockread(F,TData[0],6,Buf1ind);
  526. {Read the real, RLE'ed graphics data}
  527. BlockRead(F,TData[0],ComprBufferSize,Buf1Ind);
  528. Close(F);
  529. {Expand the RLE data. Of each byte, the high nibble is the count-1, low
  530. nibble is the value}
  531. I:=0; J:=0;
  532. REPEAT
  533. K:=(TData[I] SHR 4) +1;
  534. FillChar(PicBuf[J],K,TData [I] AND 15);
  535. INC(J,K);
  536. INC(I);
  537. UNTIL I>=Buf1Ind;
  538. {Release the temporary buffer (the compressed data isn't necesary anymore)}
  539. Freemem(TData,ComprBufferSize);
  540. End;
  541. Procedure clean;
  542. VAR I : LONGINT;
  543. Begin
  544. Randomize; {Initialize random generator}
  545. Negative:=TRUE; {Higher highscore is worse}
  546. HighX:=20; HighY:=9; {coordinates for highscores}
  547. GetMem(PicData,PicBufferSize); {Allocate room for pictures}
  548. load_pics(PicData); {Load picture data from file}
  549. FOR I:=0 TO 9 DO {Create default scores}
  550. HighScore[I].Score:=-100*I; {Negative, because then the
  551. "highest" score is best}
  552. LoadHighScore(ScoreFileName); {Try to load highscore file}
  553. closegraph;
  554. bgidirec := 'd:\prog\bp\bgi';
  555. ginit640x480x16(bgidirec);
  556. setcolor(card_border);
  557. ok := true;
  558. opened := 0;
  559. os := 0;
  560. s[1].x := 0;
  561. s[2].x := 0;
  562. s[3].x := 0;
  563. off := false;
  564. clean_board;
  565. set_board;
  566. turns := 0;
  567. showpic(0,450,score); showpic(80,450,score_b);
  568. showpic(150,450,exit_b); showpic(569,450,score);
  569. showturn(0,0);
  570. exit1 := false;
  571. SetMousePosition(0,0);
  572. get_original_time;
  573. update_time(True);
  574. showmouse;
  575. End;
  576. Begin
  577. clean;
  578. Repeat
  579. interpret;
  580. Until exit1=true;
  581. closegraph;
  582. textmode(co80);
  583. Freemem(PicData,PicBufferSize);
  584. clrscr;
  585. SaveHighScore;
  586. Writeln('Thanks for playing Quadruple Memory');
  587. Writeln('Feel free to distribute this software.');
  588. Writeln;
  589. Writeln('Programmed by: Justin Pierce');
  590. Writeln('Graphics by: Whitney Pierce');
  591. Writeln('Inspired by: Jos Dickman''s triple memory!');
  592. Writeln('FPC conversion and cleanup by Marco van de Voort');
  593. Writeln;
  594. End.
  595. $Log$
  596. Revision 1.2 2000-07-13 11:33:08 michael
  597. + removed logs
  598. }