GELIB.C 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877
  1. /* Catacomb Apocalypse Source Code
  2. * Copyright (C) 1993-2014 Flat Rock Software
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along
  15. * with this program; if not, write to the Free Software Foundation, Inc.,
  16. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  17. */
  18. #include <dos.h>
  19. #include <conio.h>
  20. #include <stdio.h>
  21. #include <dir.h>
  22. #include "mem.h"
  23. #include "string.h"
  24. #include "time.h"
  25. #include "stdarg.h"
  26. #include "io.h"
  27. #include "DEF.H"
  28. #include "gelib.h"
  29. #include "sl_file.h"
  30. #define MAX_GAMELIST_NAMES 20
  31. #define FNAME_LEN 9
  32. ////////////////////////////////////////////////////////////////////////////
  33. //
  34. // Global variables
  35. //
  36. boolean InLoadSaveGame = false;
  37. //AudioDeviceType ge_DigiMode;
  38. boolean ConserveMemory = false;
  39. char GameListNames[MAX_GAMELIST_NAMES+1][FNAME_LEN],current_disk=1;
  40. short NumGames;
  41. short PPT_LeftEdge=0,PPT_RightEdge=320;
  42. boolean LeaveDriveOn=false,ge_textmode=true;
  43. char Filename[FILENAME_LEN+1], ID[sizeof(GAMENAME)], VER[sizeof(SAVEVER_DATA)];
  44. short wall_anim_delay,wall_anim_time = 7;
  45. BufferedIO lzwBIO;
  46. ////////////////////////////////////////////////////////////////////////////
  47. //
  48. // CalibrateJoystick()
  49. //
  50. void CalibrateJoystick(short joynum)
  51. {
  52. word minx,maxx,
  53. miny,maxy;
  54. IN_ClearKeysDown();
  55. VW_HideCursor();
  56. VW_FixRefreshBuffer();
  57. CenterWindow(30,8);
  58. US_Print("\n");
  59. US_CPrintLine("Move joystick to the upper-left");
  60. US_CPrintLine("and press one of the buttons.");
  61. VW_UpdateScreen();
  62. while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joynum));
  63. if (LastScan == sc_Escape)
  64. return;
  65. IN_GetJoyAbs(joynum,&minx,&miny);
  66. while (IN_GetJoyButtonsDB(joynum));
  67. US_Print("\n");
  68. US_CPrintLine("Move joystick to the lower-right");
  69. US_CPrintLine("and press one of the buttons.");
  70. VW_UpdateScreen();
  71. while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joynum));
  72. if (LastScan == sc_Escape)
  73. return;
  74. IN_GetJoyAbs(joynum,&maxx,&maxy);
  75. if ((minx == maxx) && (miny == maxy))
  76. return;
  77. IN_SetupJoy(joynum,minx,maxx,miny,maxy);
  78. while (IN_GetJoyButtonsDB(joynum));
  79. if (LastScan)
  80. IN_ClearKeysDown();
  81. JoystickCalibrated = true;
  82. }
  83. ////////////////////////////////////////////////////////////////////////////
  84. //
  85. // WaitKeyVBL()
  86. //
  87. void WaitKeyVBL(short key, short vbls)
  88. {
  89. while (vbls--)
  90. {
  91. VW_WaitVBL(1);
  92. IN_ReadControl(0,&control);
  93. if ((control.button0|control.button1)||(Keyboard[key]))
  94. break;
  95. }
  96. }
  97. ////////////////////////////////////////////////////////////////////////////
  98. //
  99. // MoveScreen()
  100. //
  101. // panadjust must be saved and restored if MoveScreen is being called from
  102. // inside a level.
  103. //
  104. void MoveScreen(short x, short y)
  105. {
  106. unsigned address;
  107. address = (y*linewidth)+(x/8);
  108. VW_SetScreen(address,0);
  109. bufferofs = displayofs = address;
  110. panadjust=0;
  111. }
  112. ////////////////////////////////////////////////////////////////////////////
  113. //
  114. // MoveGfxDst()
  115. //
  116. void MoveGfxDst(short x, short y)
  117. {
  118. unsigned address;
  119. address = (y*linewidth)+(x/8);
  120. bufferofs = displayofs = address;
  121. }
  122. #if 0
  123. #if GRAPHIC_PIRATE
  124. ///////////////////////////////////////////////////////////////////////////
  125. //
  126. // DoPiracy() - Graphics piracy code...
  127. //
  128. void DoPiracy()
  129. {
  130. struct Shape Pirate1Shp;
  131. struct Shape Pirate2Shp;
  132. VW_SetScreenMode (EGA320GR);
  133. VW_ClearVideo(BLACK);
  134. // Load shapes...
  135. //
  136. if (LoadShape("PIRATE1E."EXT,&Pirate1Shp))
  137. TrashProg("Can't load PIRATE1E.BIO");
  138. if (LoadShape("PIRATE2E."EXT,&Pirate2Shp))
  139. TrashProg("Can't load PIRATE2E.BIO");
  140. // Deal with shapes...
  141. //
  142. VW_SetLineWidth(40);
  143. VW_FadeOut();
  144. MoveScreen(0,0);
  145. UnpackEGAShapeToScreen(&Pirate1Shp,(linewidth-Pirate1Shp.BPR)<<2,0);
  146. MoveScreen(0,200);
  147. UnpackEGAShapeToScreen(&Pirate2Shp,(linewidth-Pirate2Shp.BPR)<<2,0);
  148. MoveScreen(0,0);
  149. VW_FadeIn();
  150. WaitKeyVBL(57,200);
  151. while (Keyboard[57]);
  152. SD_PlaySound(GOOD_PICKSND);
  153. MoveScreen(0,200);
  154. WaitKeyVBL(57,300);
  155. while (Keyboard[57]);
  156. VW_FadeOut();
  157. FreeShape(&Pirate1Shp);
  158. FreeShape(&Pirate2Shp);
  159. }
  160. #else
  161. ///////////////////////////////////////////////////////////////////////////
  162. //
  163. // DoPiracy() - Text-based piracy code...
  164. //
  165. void DoPiracy()
  166. {
  167. }
  168. #endif
  169. #endif
  170. //--------------------------------------------------------------------------
  171. // BlackPalette()
  172. //--------------------------------------------------------------------------
  173. void BlackPalette()
  174. {
  175. extern char colors[7][17];
  176. _ES=FP_SEG(&colors[0]);
  177. _DX=FP_OFF(&colors[0]);
  178. _AX=0x1002;
  179. geninterrupt(0x10);
  180. screenfaded = true;
  181. }
  182. //--------------------------------------------------------------------------
  183. // ColoredPalette()
  184. //--------------------------------------------------------------------------
  185. void ColoredPalette()
  186. {
  187. extern char colors[7][17];
  188. _ES=FP_SEG(&colors[3]);
  189. _DX=FP_OFF(&colors[3]);
  190. _AX=0x1002;
  191. geninterrupt(0x10);
  192. screenfaded = false;
  193. }
  194. ////////////////////////////////////////////////////////////////////////////
  195. //
  196. // Verify()
  197. //
  198. long Verify(char *filename)
  199. {
  200. int handle;
  201. long size;
  202. if ((handle=open(filename,O_BINARY))==-1)
  203. return (0);
  204. size=filelength(handle);
  205. close(handle);
  206. return(size);
  207. }
  208. ///////////////////////////////////////////////////////////////////////////
  209. //
  210. // GE_SaveGame
  211. //
  212. // Handles user i/o for saving a game
  213. //
  214. ///////////////////////////////////////////////////////////////////////////
  215. void GE_SaveGame()
  216. {
  217. boolean GettingFilename=true;
  218. // char Filename[FILENAME_LEN+1]; //, ID[sizeof(GAMENAME)], VER[sizeof(SAVEVER_DATA)];
  219. int handle;
  220. struct dfree dfree;
  221. long davail;
  222. VW_FixRefreshBuffer();
  223. ReadGameList();
  224. while (GettingFilename)
  225. {
  226. DisplayGameList(2,7,3,10);
  227. US_DrawWindow(5,1,30,3);
  228. memset(Filename,0,sizeof(Filename));
  229. US_CPrint("Enter name to SAVE this game:");
  230. VW_UpdateScreen();
  231. if (screenfaded)
  232. VW_FadeIn();
  233. if (!US_LineInput((linewidth<<2)-32,20,Filename,"",true,8,0))
  234. goto EXIT_FUNC;
  235. if (!strlen(Filename))
  236. goto EXIT_FUNC;
  237. getdfree(getdisk()+1,&dfree);
  238. davail = (long)dfree.df_avail*(long)dfree.df_bsec*(long)dfree.df_sclus;
  239. if (davail < 10000)
  240. {
  241. US_CenterWindow(22,4);
  242. US_Print("\n");
  243. US_CPrintLine("Disk Full: Can't save game.");
  244. US_CPrintLine("Try inserting another disk.");
  245. VW_UpdateScreen();
  246. IN_Ack();
  247. }
  248. else
  249. {
  250. strcat(Filename,".SAV");
  251. GettingFilename = false;
  252. if (Verify(Filename)) // FILE EXISTS
  253. {
  254. US_CenterWindow(22,4);
  255. US_CPrintLine("That file already exists...");
  256. US_CPrintLine("Overwrite it ????");
  257. US_CPrintLine("(Y)es or (N)o?");
  258. VW_UpdateScreen();
  259. while((!Keyboard[21]) && (!Keyboard[49]) && !Keyboard[27]);
  260. if (Keyboard[27])
  261. goto EXIT_FUNC;
  262. if (Keyboard[49])
  263. {
  264. GettingFilename = true;
  265. VW_UpdateScreen();
  266. }
  267. }
  268. }
  269. }
  270. handle = open(Filename,O_RDWR|O_CREAT|O_BINARY,S_IREAD|S_IWRITE);
  271. if (handle==-1)
  272. goto EXIT_FUNC;
  273. if ((!CA_FarWrite(handle,(void far *)GAMENAME,sizeof(GAMENAME))) || (!CA_FarWrite(handle,(void far *)SAVEVER_DATA,sizeof(SAVEVER_DATA))))
  274. {
  275. if (!screenfaded)
  276. VW_FadeOut();
  277. return;
  278. }
  279. if (!USL_SaveGame(handle))
  280. Quit("Save game error");
  281. EXIT_FUNC:;
  282. if (handle!=-1)
  283. close(handle);
  284. if (handle==-1)
  285. {
  286. remove(Filename);
  287. US_CenterWindow(22,6);
  288. US_CPrintLine("DISK ERROR");
  289. US_CPrintLine("Check: Write protect...");
  290. US_CPrintLine("File name...");
  291. US_CPrintLine("Bytes free on disk...");
  292. US_CPrintLine("Press SPACE to continue.");
  293. VW_UpdateScreen();
  294. while (!Keyboard[57]);
  295. while (Keyboard[57]);
  296. }
  297. while (Keyboard[1]);
  298. if (!screenfaded)
  299. VW_FadeOut();
  300. }
  301. ///////////////////////////////////////////////////////////////////////////
  302. //
  303. // GE_LoadGame
  304. //
  305. // Handles user i/o for loading a game
  306. //
  307. ///////////////////////////////////////////////////////////////////////////
  308. boolean GE_LoadGame()
  309. {
  310. boolean GettingFilename=true,rt_code=false;
  311. int handle;
  312. IN_ClearKeysDown();
  313. memset(ID,0,sizeof(ID));
  314. memset(VER,0,sizeof(VER));
  315. VW_FixRefreshBuffer();
  316. ReadGameList();
  317. while (GettingFilename)
  318. {
  319. DisplayGameList(2,7,3,10);
  320. US_DrawWindow(5,1,30,3);
  321. memset(Filename,0,sizeof(Filename));
  322. US_CPrint("Enter name of game to RESTORE:");
  323. VW_UpdateScreen();
  324. if (screenfaded)
  325. VW_FadeIn();
  326. if (!US_LineInput((linewidth<<2)-32,20,Filename,"",true,8,0))
  327. goto EXIT_FUNC;
  328. strcat(Filename,".SAV");
  329. GettingFilename = false;
  330. if (!Verify(Filename)) // FILE DOESN'T EXIST
  331. {
  332. US_CenterWindow(22,3);
  333. US_CPrintLine(" That file doesn't exist....");
  334. US_CPrintLine("Press SPACE to try again.");
  335. VW_UpdateScreen();
  336. while (!Keyboard[57]);
  337. while (Keyboard[57]);
  338. GettingFilename = true;
  339. }
  340. }
  341. handle = open(Filename,O_RDWR|O_BINARY);
  342. if (handle==-1)
  343. goto EXIT_FUNC;
  344. if ((!CA_FarRead(handle,(void far *)&ID,sizeof(ID))) || (!CA_FarRead(handle,(void far *)&VER,sizeof(VER))))
  345. return(false);
  346. if ((strcmp(ID,GAMENAME)) || (strcmp(VER,SAVEVER_DATA)))
  347. {
  348. US_CenterWindow(32,4);
  349. US_CPrintLine("That isn't a "GAMENAME);
  350. US_CPrintLine(".SAV file.");
  351. US_CPrintLine("Press SPACE to continue.");
  352. VW_UpdateScreen();
  353. while (!Keyboard[57]);
  354. while (Keyboard[57]);
  355. if (!screenfaded)
  356. VW_FadeOut();
  357. return(false);
  358. }
  359. if (!USL_LoadGame(handle))
  360. Quit("Load game error.");
  361. rt_code = true;
  362. EXIT_FUNC:;
  363. if (handle==-1)
  364. {
  365. US_CenterWindow(22,3);
  366. US_CPrintLine("DISK ERROR ** LOAD **");
  367. US_CPrintLine("Press SPACE to continue.");
  368. while (!Keyboard[57]);
  369. while (Keyboard[57]);
  370. }
  371. else
  372. close(handle);
  373. if (!screenfaded)
  374. VW_FadeOut();
  375. return(rt_code);
  376. }
  377. ///////////////////////////////////////////////////////////////////////////
  378. //
  379. // GE_HardError() - Handles the Abort/Retry/Fail sort of errors passed
  380. // from DOS. Hard coded to ignore if during Load/Save Game.
  381. //
  382. ///////////////////////////////////////////////////////////////////////////
  383. #pragma warn -par
  384. #pragma warn -rch
  385. int GE_HardError(word errval,int ax,int bp,int si)
  386. {
  387. #define IGNORE 0
  388. #define RETRY 1
  389. #define ABORT 2
  390. extern void ShutdownId(void);
  391. static char buf[32];
  392. static WindowRec wr;
  393. static boolean oldleavedriveon;
  394. int di;
  395. char c,*s,*t;
  396. boolean holdscreenfaded;
  397. if (InLoadSaveGame)
  398. hardresume(IGNORE);
  399. di = _DI;
  400. oldleavedriveon = LeaveDriveOn;
  401. LeaveDriveOn = false;
  402. if (ax < 0)
  403. s = "Device Error";
  404. else
  405. {
  406. if ((di & 0x00ff) == 0)
  407. s = "Drive ~ is Write Protected";
  408. else
  409. s = "Error on Drive ~";
  410. for (t = buf;*s;s++,t++) // Can't use sprintf()
  411. if ((*t = *s) == '~')
  412. *t = (ax & 0x00ff) + 'A';
  413. *t = '\0';
  414. s = buf;
  415. }
  416. c = peekb(0x40,0x49); // Get the current screen mode
  417. if ((c < 4) || (c == 7))
  418. goto oh_kill_me;
  419. // DEBUG - handle screen cleanup
  420. holdscreenfaded=screenfaded;
  421. US_SaveWindow(&wr);
  422. VW_ClearVideo(0); ////////////// added for exiting
  423. US_CenterWindow(30,3);
  424. US_CPrint(s);
  425. US_CPrint("(R)etry or (A)bort?");
  426. VW_UpdateScreen();
  427. if (holdscreenfaded)
  428. VW_FadeIn();
  429. IN_ClearKeysDown();
  430. asm sti // Let the keyboard interrupts come through
  431. while (true)
  432. {
  433. switch (IN_WaitForASCII())
  434. {
  435. case key_Escape:
  436. case 'a':
  437. case 'A':
  438. goto oh_kill_me;
  439. break;
  440. case key_Return:
  441. case key_Space:
  442. case 'r':
  443. case 'R':
  444. if (holdscreenfaded)
  445. VW_FadeOut();
  446. US_ClearWindow();
  447. VW_UpdateScreen();
  448. US_RestoreWindow(&wr);
  449. LeaveDriveOn = oldleavedriveon;
  450. return(RETRY);
  451. break;
  452. }
  453. }
  454. oh_kill_me:
  455. abortprogram = s;
  456. TrashProg("Terminal Error: %s\n",s);
  457. // if (tedlevel)
  458. // fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
  459. return(ABORT);
  460. #undef IGNORE
  461. #undef RETRY
  462. #undef ABORT
  463. }
  464. #pragma warn +par
  465. #pragma warn +rch
  466. //--------------------------------------------------------------------------
  467. //
  468. //
  469. // B O B ROUTINES
  470. //
  471. //
  472. //--------------------------------------------------------------------------
  473. #ifdef BOBLIST
  474. ////////////////////////////////////////////////////////////////////////////
  475. //
  476. // UpdateBOBList() - Adds a sprite to an objects BOBlist. The BOB List
  477. // must already be allocated and have an available slot.
  478. //
  479. // RETURNS : true = Success adding Sprite / false = Failure.
  480. //
  481. // NOTE : This also sets the users 'needtoreact' flag to true.
  482. //
  483. boolean UpdateBOBList(objtype *obj,struct Simple_Shape *Shape,shapeclass Class, short priority, spriteflags sprflags)
  484. {
  485. struct BOB_Shape *CurBOBShape = NULL;
  486. #pragma warn -pia
  487. if (CurBOBShape = obj->nextshape)
  488. {
  489. // Treverse down BOBList looking for a sprite with the same class
  490. // OR an empty shape struct to store the new shape.
  491. while ((CurBOBShape->class != Class) && (CurBOBShape->class) && CurBOBShape)
  492. {
  493. CurBOBShape = CurBOBShape->nextshape;
  494. }
  495. if (CurBOBShape)
  496. {
  497. RF_RemoveSprite(&CurBOBShape->sprite);
  498. CurBOBShape->shapenum = Shape->shapenum;
  499. CurBOBShape->x_offset = Shape->x_offset;
  500. CurBOBShape->y_offset = Shape->y_offset;
  501. CurBOBShape->priority = priority;
  502. CurBOBShape->sprflags = sprflags;
  503. CurBOBShape->class = Class;
  504. return(true);
  505. }
  506. }
  507. return(false);
  508. #pragma warn +pia
  509. }
  510. /////////////////////////////////////////////////////////////////////////////
  511. //
  512. // RemoveBOBShape() - Removes a sprite from a BOBList.
  513. //
  514. // RETURNS : true = Success / false = Failure (shape not found)
  515. //
  516. boolean RemoveBOBShape(objtype *obj, shapeclass Class)
  517. {
  518. struct BOB_Shape *CurBOBShape = NULL;
  519. #pragma warn -pia
  520. if (CurBOBShape = obj->nextshape)
  521. {
  522. while ((CurBOBShape->class != Class) && (!CurBOBShape->class) && CurBOBShape)
  523. {
  524. CurBOBShape = CurBOBShape->nextshape;
  525. }
  526. if (CurBOBShape)
  527. {
  528. CurBOBShape->class = noshape;
  529. return(true);
  530. }
  531. }
  532. return(false);
  533. #pragma warn +pia
  534. }
  535. /////////////////////////////////////////////////////////////////////////////
  536. //
  537. // RemoveBOBList() - Removes an entire BOBList attached to an object.
  538. //
  539. //
  540. void RemoveBOBList(objtype *obj)
  541. {
  542. struct BOB_Shape *CurBOBShape;
  543. #pragma warn -pia
  544. if (CurBOBShape = obj->nextshape)
  545. {
  546. // Treverse down BOBList looking for a sprite with the same class
  547. // OR an empty shape struct to store the new shape.
  548. while (CurBOBShape)
  549. {
  550. if (CurBOBShape->class)
  551. {
  552. CurBOBShape->class = noshape;
  553. RF_RemoveSprite (&CurBOBShape->sprite);
  554. }
  555. CurBOBShape = CurBOBShape->nextshape;
  556. }
  557. }
  558. #pragma warn +pia
  559. }
  560. /////////////////////////////////////////////////////////////////////////////
  561. //
  562. // InitBOBList() -- This initializes a BOB list for all the possible shapes
  563. // attached at one time. This is done with an array of
  564. // BOB_Shape structs and links the 'nextshape' pointer to
  565. // to the next element.
  566. //
  567. //
  568. void InitBOBList(objtype *obj, struct BOB_Shape *BOB_Shape, short NumElements)
  569. {
  570. struct BOB_Shape *CurShape;
  571. short loop;
  572. obj->nextshape = BOB_Shape;
  573. for (loop=1;loop<NumElements;loop++)
  574. {
  575. CurShape = BOB_Shape++;
  576. CurShape->nextshape = BOB_Shape;
  577. }
  578. BOB_Shape->nextshape = NULL;
  579. }
  580. ////////////////////////////////////////////////////////////////////////////
  581. //
  582. // RefreshBOBList() -- This routine updates all sprites attached to the
  583. // BOBList and refreshes there position in the sprite
  584. // list.
  585. //
  586. void RefreshBOBList(objtype *obj)
  587. {
  588. struct BOB_Shape *Shape;
  589. Shape = obj->nextshape;
  590. while (Shape)
  591. {
  592. if (Shape->class)
  593. RF_PlaceSprite(&Shape->sprite,obj->x+Shape->x_offset,obj->y+Shape->y_offset, Shape->shapenum, spritedraw,Shape->priority,Shape->sprflags);
  594. Shape = Shape->nextshape;
  595. }
  596. }
  597. #endif
  598. //--------------------------------------------------------------------------
  599. // InitBufferedIO()
  600. //--------------------------------------------------------------------------
  601. memptr InitBufferedIO(int handle, BufferedIO *bio)
  602. {
  603. bio->handle = handle;
  604. bio->offset = BIO_BUFFER_LEN;
  605. bio->status = 0;
  606. MM_GetPtr(&bio->buffer,BIO_BUFFER_LEN);
  607. return(bio->buffer);
  608. }
  609. //--------------------------------------------------------------------------
  610. // FreeBufferedIO()
  611. //--------------------------------------------------------------------------
  612. void FreeBufferedIO(BufferedIO *bio)
  613. {
  614. if (bio->buffer)
  615. MM_FreePtr(&bio->buffer);
  616. }
  617. //--------------------------------------------------------------------------
  618. // bio_readch()
  619. //--------------------------------------------------------------------------
  620. byte bio_readch(BufferedIO *bio)
  621. {
  622. byte far *buffer;
  623. if (bio->offset == BIO_BUFFER_LEN)
  624. {
  625. bio->offset = 0;
  626. bio_fillbuffer(bio);
  627. }
  628. buffer = MK_FP(bio->buffer,bio->offset++);
  629. return(*buffer);
  630. }
  631. //--------------------------------------------------------------------------
  632. // bio_fillbuffer()
  633. //
  634. // BUGS (Not really bugs... More like RULES!)
  635. //
  636. // 1) This code assumes BIO_BUFFER_LEN is no smaller than
  637. // NEAR_BUFFER_LEN!!
  638. //
  639. // 2) BufferedIO.status should be altered by this code to report
  640. // read errors, end of file, etc... If you know how big the file
  641. // is you're reading, determining EOF should be no problem.
  642. //
  643. //--------------------------------------------------------------------------
  644. void bio_fillbuffer(BufferedIO *bio)
  645. {
  646. #define NEAR_BUFFER_LEN (64)
  647. byte near_buffer[NEAR_BUFFER_LEN];
  648. short bio_length,bytes_read,bytes_requested;
  649. bytes_read = 0;
  650. bio_length = BIO_BUFFER_LEN;
  651. while (bio_length)
  652. {
  653. if (bio_length > NEAR_BUFFER_LEN-1)
  654. bytes_requested = NEAR_BUFFER_LEN;
  655. else
  656. bytes_requested = bio_length;
  657. read(bio->handle,near_buffer,bytes_requested);
  658. _fmemcpy(MK_FP(bio->buffer,bytes_read),near_buffer,bytes_requested);
  659. bio_length -= bytes_requested;
  660. bytes_read += bytes_requested;
  661. }
  662. }
  663. ///////////////////////////////////////////////////////////////////////////
  664. //
  665. // SwapLong()
  666. //
  667. void SwapLong(long far *Var)
  668. {
  669. asm les bx,Var
  670. asm mov ax,[es:bx]
  671. asm xchg ah,al
  672. asm xchg ax,[es:bx+2]
  673. asm xchg ah,al
  674. asm mov [es:bx],ax
  675. }
  676. ///////////////////////////////////////////////////////////////////////////
  677. //
  678. // SwapWord()
  679. //
  680. void SwapWord(unsigned int far *Var)
  681. {
  682. asm les bx,Var
  683. asm mov ax,[es:bx]
  684. asm xchg ah,al
  685. asm mov [es:bx],ax
  686. }
  687. #if 0
  688. ////////////////////////////////////////////////////////////////////////////
  689. //
  690. // LoadShape()
  691. //
  692. int LoadShape(char *Filename,struct Shape *SHP)
  693. {
  694. #define CHUNK(Name) (*ptr == *Name) && \
  695. (*(ptr+1) == *(Name+1)) && \
  696. (*(ptr+2) == *(Name+2)) && \
  697. (*(ptr+3) == *(Name+3))
  698. int RT_CODE;
  699. // struct ffblk ffblk;
  700. FILE *fp;
  701. char CHUNK[5];
  702. char far *ptr;
  703. memptr IFFfile = NULL;
  704. unsigned long FileLen, size, ChunkLen;
  705. int loop;
  706. RT_CODE = 1;
  707. // Decompress to ram and return ptr to data and return len of data in
  708. // passed variable...
  709. if (!(FileLen = BLoad(Filename,&IFFfile)))
  710. TrashProg("Can't load Compressed Shape - Possibly corrupt file!");
  711. // Evaluate the file
  712. //
  713. ptr = MK_FP(IFFfile,0);
  714. if (!CHUNK("FORM"))
  715. goto EXIT_FUNC;
  716. ptr += 4;
  717. FileLen = *(long far *)ptr;
  718. SwapLong((long far *)&FileLen);
  719. ptr += 4;
  720. if (!CHUNK("ILBM"))
  721. goto EXIT_FUNC;
  722. ptr += 4;
  723. FileLen += 4;
  724. while (FileLen)
  725. {
  726. ChunkLen = *(long far *)(ptr+4);
  727. SwapLong((long far *)&ChunkLen);
  728. ChunkLen = (ChunkLen+1) & 0xFFFFFFFE;
  729. if (CHUNK("BMHD"))
  730. {
  731. ptr += 8;
  732. SHP->bmHdr.w = ((struct BitMapHeader far *)ptr)->w;
  733. SHP->bmHdr.h = ((struct BitMapHeader far *)ptr)->h;
  734. SHP->bmHdr.x = ((struct BitMapHeader far *)ptr)->x;
  735. SHP->bmHdr.y = ((struct BitMapHeader far *)ptr)->y;
  736. SHP->bmHdr.d = ((struct BitMapHeader far *)ptr)->d;
  737. SHP->bmHdr.trans = ((struct BitMapHeader far *)ptr)->trans;
  738. SHP->bmHdr.comp = ((struct BitMapHeader far *)ptr)->comp;
  739. SHP->bmHdr.pad = ((struct BitMapHeader far *)ptr)->pad;
  740. SwapWord(&SHP->bmHdr.w);
  741. SwapWord(&SHP->bmHdr.h);
  742. SwapWord(&SHP->bmHdr.x);
  743. SwapWord(&SHP->bmHdr.y);
  744. ptr += ChunkLen;
  745. }
  746. else
  747. if (CHUNK("BODY"))
  748. {
  749. ptr += 4;
  750. size = *((long far *)ptr);
  751. ptr += 4;
  752. SwapLong((long far *)&size);
  753. SHP->BPR = (SHP->bmHdr.w+7) >> 3;
  754. MM_GetPtr(&SHP->Data,size);
  755. if (!SHP->Data)
  756. goto EXIT_FUNC;
  757. movedata(FP_SEG(ptr),FP_OFF(ptr),FP_SEG(SHP->Data),0,size);
  758. ptr += ChunkLen;
  759. break;
  760. }
  761. else
  762. ptr += ChunkLen+8;
  763. FileLen -= ChunkLen+8;
  764. }
  765. RT_CODE = 0;
  766. EXIT_FUNC:;
  767. if (IFFfile)
  768. {
  769. // segptr = (memptr)FP_SEG(IFFfile);
  770. MM_FreePtr(&IFFfile);
  771. }
  772. return (RT_CODE);
  773. }
  774. #endif
  775. ////////////////////////////////////////////////////////////////////////////
  776. //
  777. // FreeShape()
  778. //
  779. void FreeShape(struct Shape *shape)
  780. {
  781. if (shape->Data)
  782. MM_FreePtr(&shape->Data);
  783. }
  784. ////////////////////////////////////////////////////////////////////////////
  785. //
  786. // UnpackEGAShapeToScreen()
  787. //
  788. int UnpackEGAShapeToScreen(struct Shape *SHP,int startx,int starty)
  789. {
  790. int currenty;
  791. signed char n, Rep, far *Src, far *Dst[8], loop, Plane;
  792. unsigned int BPR, Height;
  793. boolean NotWordAligned;
  794. NotWordAligned = SHP->BPR & 1;
  795. startx>>=3;
  796. Src = MK_FP(SHP->Data,0);
  797. currenty = starty;
  798. Plane = 0;
  799. Height = SHP->bmHdr.h;
  800. while (Height--)
  801. {
  802. Dst[0] = (MK_FP(0xA000,displayofs));
  803. Dst[0] += ylookup[currenty];
  804. Dst[0] += startx;
  805. for (loop=1; loop<SHP->bmHdr.d; loop++)
  806. Dst[loop] = Dst[0];
  807. for (Plane=0; Plane<SHP->bmHdr.d; Plane++)
  808. {
  809. outport(0x3c4,((1<<Plane)<<8)|2);
  810. BPR = ((SHP->BPR+1) >> 1) << 1; // IGNORE WORD ALIGN
  811. while (BPR)
  812. {
  813. if (SHP->bmHdr.comp)
  814. n = *Src++;
  815. else
  816. n = BPR-1;
  817. if (n < 0)
  818. {
  819. if (n != -128)
  820. {
  821. n = (-n)+1;
  822. BPR -= n;
  823. Rep = *Src++;
  824. if ((!BPR) && (NotWordAligned)) // IGNORE WORD ALIGN
  825. n--;
  826. while (n--)
  827. *Dst[Plane]++ = Rep;
  828. }
  829. else
  830. BPR--;
  831. }
  832. else
  833. {
  834. n++;
  835. BPR -= n;
  836. if ((!BPR) && (NotWordAligned)) // IGNORE WORD ALIGN
  837. n--;
  838. while (n--)
  839. *Dst[Plane]++ = *Src++;
  840. if ((!BPR) && (NotWordAligned)) // IGNORE WORD ALIGN
  841. Src++;
  842. }
  843. }
  844. }
  845. currenty++;
  846. }
  847. return(0);
  848. }
  849. ////////////////////////////////////////////////////////////////////////////
  850. //
  851. // GetKeyChoice()
  852. //
  853. char GetKeyChoice(char *choices,boolean clear)
  854. {
  855. extern void DoEvents(void);
  856. boolean waiting;
  857. char *s,*ss;
  858. IN_ClearKeysDown();
  859. waiting = true;
  860. while (waiting)
  861. {
  862. s = choices;
  863. while (*s)
  864. {
  865. if (Keyboard[*s++])
  866. {
  867. waiting=false;
  868. break;
  869. }
  870. }
  871. }
  872. IN_ClearKeysDown();
  873. return(*(--s));
  874. }
  875. #if 0
  876. ////////////////////////////////////////////////////////////////////////////
  877. //
  878. // AnimateObj()
  879. //
  880. boolean AnimateObj(objtype *obj)
  881. {
  882. boolean Done;
  883. Done = false;
  884. if (obj->animtype == at_NONE) // Animation finished?
  885. return(true); // YEP!
  886. if (obj->animdelay) // Check animation delay.
  887. {
  888. obj->animdelay -= tics;
  889. if (obj->animdelay < 0)
  890. obj->animdelay = 0;
  891. return(false);
  892. }
  893. switch (obj->animtype) // Animate this object!
  894. {
  895. case at_ONCE:
  896. case at_CYCLE:
  897. switch (obj->animdir)
  898. {
  899. case at_FWD:
  900. if (obj->curframe < obj->maxframe)
  901. AdvanceAnimFWD(obj);
  902. else
  903. if (obj->animtype == at_CYCLE)
  904. {
  905. obj->curframe = 0; // RESET CYCLE ANIMATION
  906. obj->animdelay=1;
  907. }
  908. else
  909. {
  910. obj->animtype = at_NONE; // TERMINATE ONCE ANIM
  911. Done = true;
  912. }
  913. break;
  914. case at_REV:
  915. if (obj->curframe > 0)
  916. AdvanceAnimREV(obj);
  917. else
  918. if (obj->animtype == at_CYCLE)
  919. {
  920. obj->curframe = obj->maxframe; // RESET CYCLE ANIMATION
  921. obj->animdelay = 1;
  922. }
  923. else
  924. {
  925. obj->animtype = at_NONE; // TERMINATE ONCE ANIM
  926. Done = true;
  927. }
  928. break; // REV
  929. }
  930. break;
  931. case at_REBOUND:
  932. switch (obj->animdir)
  933. {
  934. case at_FWD:
  935. if (obj->curframe < obj->maxframe)
  936. AdvanceAnimFWD(obj);
  937. else
  938. {
  939. obj->animdir = at_REV;
  940. obj->animdelay = 1;
  941. }
  942. break;
  943. case at_REV:
  944. if (obj->curframe > 0)
  945. AdvanceAnimREV(obj);
  946. else
  947. {
  948. obj->animdir = at_FWD;
  949. obj->animdelay = 1;
  950. Done = true;
  951. }
  952. break;
  953. }
  954. break; /* REBOUND */
  955. case at_WAIT:
  956. Done = true;
  957. break;
  958. }
  959. return(Done);
  960. }
  961. void AdvanceAnimFWD(objtype *obj) // Advances a Frame of ANIM for ONCE,CYCLE, REBOUND
  962. {
  963. obj->curframe++; // INC frames
  964. obj->animdelay = obj->maxdelay; // Init Delay Counter.
  965. obj->needtoreact = true;
  966. }
  967. void AdvanceAnimREV(objtype *obj) // Advances a Frame of ANIM for ONCE,CYCLE, REBOUND
  968. {
  969. obj->curframe--; // DEC frames
  970. obj->animdelay = obj->maxdelay; // Init Delay Counter.
  971. obj->needtoreact = true;
  972. }
  973. #endif
  974. #if 0
  975. ///////////////////////////////////////////////////////////////////////////
  976. //
  977. // LoadASArray() - Load an array of audio samples in FAR memory.
  978. //
  979. void LoadASArray(struct Sample *ASArray)
  980. {
  981. int loop = 0;
  982. while (ASArray[loop].filename)
  983. {
  984. if (!BLoad(ASArray[loop].filename,(memptr *)&ASArray[loop].data))
  985. TrashProg("Unable to load sample in LoadASArray()");
  986. loop++;
  987. }
  988. }
  989. ////////////////////////////////////////////////////////////////////////////
  990. //
  991. // FreeASArray() - Frees an ASArray from memory that has been loaded with
  992. // LoadASArray()
  993. //
  994. void FreeASArray(struct Sample *ASArray)
  995. {
  996. unsigned loop = 0;
  997. while (ASArray[loop].data)
  998. {
  999. MM_SetPurge((memptr *)&ASArray[loop++].data,3);
  1000. MM_FreePtr((memptr *)&ASArray[loop++].data);
  1001. }
  1002. }
  1003. ///////////////////////////////////////////////////////////////////////////
  1004. //
  1005. // GE_LoadAllDigiSounds() - This is a hook that CA_LoadAllSounds()
  1006. // calls to load all of the Digitized sounds for
  1007. // Sound Blaster & Sound Source.
  1008. //
  1009. // NOTE : This stub would do any other necessary routines for DigiSounds
  1010. // specific to GAMERS EDGE code. (Keeping seperate from ID's)
  1011. //
  1012. void GE_LoadAllDigiSounds()
  1013. {
  1014. LoadASArray(DigiSounds);
  1015. }
  1016. /////////////////////////////////////////////////////////////////////////
  1017. //
  1018. // GE_FreeAllDigiSounds() -- This is a hook that CA_LoadAllSounds()
  1019. // calls to free all digitized sounds for
  1020. // which ever hardware and allow for any necessary
  1021. // clean up.
  1022. //
  1023. //
  1024. // NOTE : This stub would do any other necessary routines for DigiSounds
  1025. // specific to GAMERS EDGE code. (Keeping seperate from ID's)
  1026. //
  1027. void GE_FreeAllDigiSounds()
  1028. {
  1029. FreeASArray(DigiSounds);
  1030. }
  1031. ///////////////////////////////////////////////////////////////////////////
  1032. //
  1033. // GE_LoadAllSounds() - Loads ALL sounds needed for detected hardware.
  1034. //
  1035. void GE_LoadAllSounds()
  1036. {
  1037. unsigned i,start;
  1038. start = STARTPCSOUNDS;
  1039. for (i=0;i<NUMSOUNDS;i++,start++)
  1040. CA_CacheAudioChunk (start);
  1041. if (AdLibPresent)
  1042. {
  1043. start = STARTADLIBSOUNDS;
  1044. for (i=0;i<NUMSOUNDS;i++,start++)
  1045. CA_CacheAudioChunk (start);
  1046. }
  1047. if (SoundBlasterPresent)
  1048. LoadASArray(DigiSounds);
  1049. }
  1050. //////////////////////////////////////////////////////////////////////////
  1051. //
  1052. // GE_PurgeAllSounds() - Frees all sounds that were loaded.
  1053. //
  1054. void GE_PurgeAllSounds()
  1055. {
  1056. unsigned start,i;
  1057. start = STARTPCSOUNDS;
  1058. for (i=0;i<NUMSOUNDS;i++,start++)
  1059. if (audiosegs[start])
  1060. MM_SetPurge (&(memptr)audiosegs[start],3); // make purgable
  1061. if (AdLibPresent)
  1062. {
  1063. start = STARTADLIBSOUNDS;
  1064. for (i=0;i<NUMSOUNDS;i++,start++)
  1065. if (audiosegs[start])
  1066. MM_SetPurge (&(memptr)audiosegs[start],3); // make purgable
  1067. }
  1068. if (SoundBlasterPresent)
  1069. GE_FreeAllDigiSounds();
  1070. }
  1071. /////////////////////////////////////////////////////////////////////////////
  1072. //
  1073. // PlaySample() -- Plays a DIGITIZED sample using SoundBlaster OR SoundSource
  1074. //
  1075. // PARAMETERS : Sample Number (Corresponding to ASArray "DigiSounds[]".
  1076. //
  1077. void PlaySample(unsigned SampleNum)
  1078. {
  1079. if (!DigiSounds[SampleNum].data)
  1080. TrashProg("PlaySample - Trying to play an unloaded digi sound!");
  1081. switch (SoundMode) // external variable in ID_SD for sound mode..
  1082. {
  1083. case sdm_SoundBlaster:
  1084. case sdm_SoundBlasterAdLib:
  1085. SDL_SBPlaySample(MK_FP(DigiSounds[SampleNum].data,0));
  1086. break;
  1087. default:
  1088. TrashProg("PlaySample() - incorrect SoundMode for PlaySample()");
  1089. break;
  1090. }
  1091. }
  1092. /////////////////////////////////////////////////////////////////////////////
  1093. //
  1094. // SelectDigiAudio() -- This routine intergrates multi sound hardware with
  1095. // id's routines.
  1096. //
  1097. void SelectDigiAudio(AudioDeviceType Device)
  1098. {
  1099. switch (Device)
  1100. {
  1101. case ged_SoundSource:
  1102. case ged_SoundBlaster:
  1103. break;
  1104. }
  1105. }
  1106. #endif
  1107. ///////////////////////////////////////////////////////////////////////////
  1108. //
  1109. // DisplayGameList()
  1110. //
  1111. void DisplayGameList(short winx, short winy, short list_width, short list_height)
  1112. {
  1113. #define SPACES 2
  1114. short width,col,row,orgcol,games_printed=0,h;
  1115. // Possibly shrink window.
  1116. //
  1117. h = (NumGames / list_width) + ((NumGames % list_width) > 0);
  1118. if (h < list_height)
  1119. list_height = h;
  1120. // Open window and print header...
  1121. //
  1122. US_DrawWindow(winx,winy,list_width*(8+SPACES*2),list_height+3);
  1123. US_CPrintLine("LIST OF SAVED GAMES");
  1124. US_Print("\n");
  1125. col = orgcol = PrintX;
  1126. row = PrintY;
  1127. // Display as many 'save game' files as can fit in the window.
  1128. //
  1129. width = list_width;
  1130. while ((games_printed<NumGames) && (list_height))
  1131. {
  1132. // Print filename and padding spaces.
  1133. //
  1134. US_Printxy(col+(SPACES*8),row,GameListNames[games_printed]);
  1135. col += 8*((SPACES*2)+8);
  1136. // Check for end-of-line or end-of-window.
  1137. //
  1138. width--;
  1139. if (!width)
  1140. {
  1141. col = orgcol;
  1142. row += 8;
  1143. width = list_width;
  1144. list_height--;
  1145. US_Print("\n");
  1146. }
  1147. games_printed++;
  1148. }
  1149. }
  1150. ////////////////////////////////////////////////////////////////////////////
  1151. //
  1152. // ReadGameList()
  1153. //
  1154. void ReadGameList()
  1155. {
  1156. struct ffblk ffblk;
  1157. short done,len;
  1158. NumGames = -1;
  1159. done = findfirst("*.sav",&ffblk,0);
  1160. while (!done)
  1161. {
  1162. if (NumGames == MAX_GAMELIST_NAMES)
  1163. memcpy(GameListNames,GameListNames[1],MAX_GAMELIST_NAMES*sizeof(GameListNames[0]));
  1164. else
  1165. NumGames++;
  1166. fnsplit(ffblk.ff_name,NULL,NULL,GameListNames[NumGames],NULL);
  1167. done=findnext(&ffblk);
  1168. }
  1169. NumGames++;
  1170. }
  1171. #if 0
  1172. ////////////////////////////////////////////////////////////////////////////
  1173. //
  1174. // CenterObj()
  1175. //
  1176. void CenterObj(objtype *obj, unsigned x, unsigned y)
  1177. {
  1178. spritetabletype far *sprite;
  1179. unsigned width, height;
  1180. sprite=&spritetable[obj->baseshape+obj->curframe-STARTSPRITES];
  1181. width = (sprite->xh-sprite->xl+(1<<G_P_SHIFT)) >> 1;
  1182. if (obj->sprflags&sf_vertflip)
  1183. {
  1184. height = (sprite->yl-(sprite->height<<G_P_SHIFT) + sprite->yh+(1<<G_P_SHIFT)) >> 1;
  1185. }
  1186. else
  1187. height = (sprite->yh-sprite->yl+(1<<G_P_SHIFT)) >> 1;
  1188. obj->x = x-width;
  1189. obj->y = y-height;
  1190. }
  1191. #endif
  1192. #if 0
  1193. //-------------------------------------------------------------------------
  1194. // cacheout()
  1195. //-------------------------------------------------------------------------
  1196. void cacheout(short s,short e)
  1197. {
  1198. short i;
  1199. for(i=(s);i<=(e);i++)
  1200. {
  1201. grneeded[i]&=~ca_levelbit;
  1202. if (grsegs[i])
  1203. MM_SetPurge(&grsegs[i],3);
  1204. }
  1205. }
  1206. //-------------------------------------------------------------------------
  1207. // cachein()
  1208. //-------------------------------------------------------------------------
  1209. void cachein(short s,short e)
  1210. {
  1211. short i;
  1212. for(i=(s);i<=(e);i++)
  1213. {
  1214. CA_MarkGrChunk(i);
  1215. if (grsegs[i])
  1216. MM_SetPurge(&grsegs[i],0);
  1217. }
  1218. }
  1219. #endif
  1220. #if 0
  1221. ////////////////////////////////////////////////////////////////////////////
  1222. //
  1223. // SetUpdateBlock()
  1224. //
  1225. void SetUpdateBlock(unsigned x,unsigned y,unsigned width,unsigned height,char refresh)
  1226. {
  1227. eraseblocktype *erase;
  1228. #if 0 //SP unsure if this is needed
  1229. x = (x+((MAPBORDER+MAPXLEFTOFFSET)<<4))>>3;
  1230. y += ((MAPBORDER+MAPYTOPOFFSET)<<4);
  1231. #else
  1232. x = (x+(MAPBORDER<<4))>>3;
  1233. y += (MAPBORDER<<4);
  1234. #endif
  1235. width >>= 3;
  1236. if (refresh & 1)
  1237. {
  1238. erase = eraselistptr[0]++;
  1239. erase->screenx=x;
  1240. erase->screeny=y;
  1241. erase->width=width;
  1242. erase->height=height;
  1243. }
  1244. if (refresh & 2)
  1245. {
  1246. erase = eraselistptr[1]++;
  1247. erase->screenx=x;
  1248. erase->screeny=y;
  1249. erase->width=width;
  1250. erase->height=height;
  1251. }
  1252. }
  1253. ////////////////////////////////////////////////////////////////////////////
  1254. //
  1255. // ObjHeight
  1256. //
  1257. unsigned ObjHeight(objtype *obj)
  1258. {
  1259. spritetabletype far *sprite;
  1260. sprite=&spritetable[obj->baseshape+obj->curframe-STARTSPRITES];
  1261. if (obj->sprflags&sf_vertflip)
  1262. {
  1263. return((sprite->yl-(sprite->height<<G_P_SHIFT) + sprite->yh+(1<<G_P_SHIFT)) >> 1);
  1264. }
  1265. else
  1266. return((sprite->yh-sprite->yl+(1<<G_P_SHIFT)) >> 1);
  1267. }
  1268. ////////////////////////////////////////////////////////////////////////////
  1269. //
  1270. // ObjWidth
  1271. //
  1272. unsigned ObjWidth(objtype *obj)
  1273. {
  1274. spritetabletype far *sprite;
  1275. sprite=&spritetable[obj->baseshape+obj->curframe-STARTSPRITES];
  1276. return((sprite->xh-sprite->xl+(1<<G_P_SHIFT)) >> 1);
  1277. }
  1278. #endif
  1279. #if 0
  1280. //--------------------------------------------------------------------------
  1281. // visible_on()
  1282. //--------------------------------------------------------------------------
  1283. boolean visible_on(objtype *obj)
  1284. {
  1285. if (!(obj->flags & of_visible))
  1286. {
  1287. obj->needtoreact=true;
  1288. obj->flags |= of_visible;
  1289. return(true);
  1290. }
  1291. return(false);
  1292. }
  1293. //--------------------------------------------------------------------------
  1294. // visible_off()
  1295. //--------------------------------------------------------------------------
  1296. boolean visible_off(objtype *obj)
  1297. {
  1298. if (obj->flags & of_visible)
  1299. {
  1300. obj->needtoreact=true;
  1301. obj->flags &= ~of_visible;
  1302. return(true);
  1303. }
  1304. return(false);
  1305. }
  1306. #endif
  1307. /*
  1308. ===================
  1309. =
  1310. = FizzleFade
  1311. =
  1312. ===================
  1313. */
  1314. #define PIXPERFRAME 10000
  1315. void FizzleFade (unsigned source, unsigned dest,
  1316. unsigned width,unsigned height, boolean abortable)
  1317. {
  1318. unsigned drawofs,pagedelta;
  1319. unsigned char maskb[8] = {1,2,4,8,16,32,64,128};
  1320. unsigned x,y,p,frame;
  1321. long rndval;
  1322. ScanCode lastLastScan=LastScan=0;
  1323. width--;
  1324. height--;
  1325. pagedelta = dest-source;
  1326. // VW_SetScreen (dest,0);
  1327. rndval = 1;
  1328. y = 0;
  1329. asm mov es,[screenseg]
  1330. asm mov dx,SC_INDEX
  1331. asm mov al,SC_MAPMASK
  1332. asm out dx,al
  1333. TimeCount=frame=0;
  1334. do // while (1)
  1335. {
  1336. if ((abortable) || (Flags & FL_QUICK))
  1337. {
  1338. IN_ReadControl(0,&control);
  1339. if (control.button0 || control.button1 || (lastLastScan != LastScan)
  1340. || Keyboard[sc_Escape] || (Flags & FL_QUICK))
  1341. {
  1342. VW_ScreenToScreen (source,dest,(width+1)/8,height+1);
  1343. goto exitfunc;
  1344. }
  1345. }
  1346. for (p=0;p<PIXPERFRAME;p++)
  1347. {
  1348. //
  1349. // seperate random value into x/y pair
  1350. //
  1351. asm mov ax,[WORD PTR rndval]
  1352. asm mov dx,[WORD PTR rndval+2]
  1353. asm mov bx,ax
  1354. asm dec bl
  1355. asm mov [BYTE PTR y],bl // low 8 bits - 1 = y xoordinate
  1356. asm mov bx,ax
  1357. asm mov cx,dx
  1358. asm shr cx,1
  1359. asm rcr bx,1
  1360. asm shr bx,1
  1361. asm shr bx,1
  1362. asm shr bx,1
  1363. asm shr bx,1
  1364. asm shr bx,1
  1365. asm shr bx,1
  1366. asm shr bx,1
  1367. asm mov [x],bx // next 9 bits = x xoordinate
  1368. //
  1369. // advance to next random element
  1370. //
  1371. asm shr dx,1
  1372. asm rcr ax,1
  1373. asm jnc noxor
  1374. asm xor dx,0x0001
  1375. asm xor ax,0x2000
  1376. noxor:
  1377. asm mov [WORD PTR rndval],ax
  1378. asm mov [WORD PTR rndval+2],dx
  1379. if (x>width || y>height)
  1380. continue;
  1381. drawofs = source+ylookup[y];
  1382. asm mov cx,[x]
  1383. asm mov si,cx
  1384. asm and si,7
  1385. asm mov dx,GC_INDEX
  1386. asm mov al,GC_BITMASK
  1387. asm mov ah,BYTE PTR [maskb+si]
  1388. asm out dx,ax
  1389. asm mov si,[drawofs]
  1390. asm shr cx,1
  1391. asm shr cx,1
  1392. asm shr cx,1
  1393. asm add si,cx
  1394. asm mov di,si
  1395. asm add di,[pagedelta]
  1396. asm mov dx,GC_INDEX
  1397. asm mov al,GC_READMAP // leave GC_INDEX set to READMAP
  1398. asm out dx,al
  1399. asm mov dx,SC_INDEX+1
  1400. asm mov al,1
  1401. asm out dx,al
  1402. asm mov dx,GC_INDEX+1
  1403. asm mov al,0
  1404. asm out dx,al
  1405. asm mov bl,[es:si]
  1406. asm xchg [es:di],bl
  1407. asm mov dx,SC_INDEX+1
  1408. asm mov al,2
  1409. asm out dx,al
  1410. asm mov dx,GC_INDEX+1
  1411. asm mov al,1
  1412. asm out dx,al
  1413. asm mov bl,[es:si]
  1414. asm xchg [es:di],bl
  1415. asm mov dx,SC_INDEX+1
  1416. asm mov al,4
  1417. asm out dx,al
  1418. asm mov dx,GC_INDEX+1
  1419. asm mov al,2
  1420. asm out dx,al
  1421. asm mov bl,[es:si]
  1422. asm xchg [es:di],bl
  1423. asm mov dx,SC_INDEX+1
  1424. asm mov al,8
  1425. asm out dx,al
  1426. asm mov dx,GC_INDEX+1
  1427. asm mov al,3
  1428. asm out dx,al
  1429. asm mov bl,[es:si]
  1430. asm xchg [es:di],bl
  1431. if (rndval == 1) // entire sequence has been completed
  1432. goto exitfunc;
  1433. }
  1434. // frame++;
  1435. // while (TimeCount<frame); // don't go too fast
  1436. } while (1);
  1437. exitfunc:;
  1438. EGABITMASK(255);
  1439. EGAMAPMASK(15);
  1440. return;
  1441. }
  1442. #if 0
  1443. //-------------------------------------------------------------------------
  1444. // mprintf()
  1445. //-------------------------------------------------------------------------
  1446. void mprintf(char *msg, ...)
  1447. {
  1448. static char x=0;
  1449. static char y=0;
  1450. static char far *video = MK_FP(0xb000,0x0000);
  1451. char buffer[100],*ptr;
  1452. va_list(ap);
  1453. va_start(ap,msg);
  1454. vsprintf(buffer,msg,ap);
  1455. ptr = buffer;
  1456. while (*ptr)
  1457. {
  1458. switch (*ptr)
  1459. {
  1460. case '\n':
  1461. if (y >= 23)
  1462. {
  1463. video -= (x<<1);
  1464. _fmemcpy(MK_FP(0xb000,0x0000),MK_FP(0xb000,0x00a0),3840);
  1465. }
  1466. else
  1467. {
  1468. y++;
  1469. video += ((80-x)<<1);
  1470. }
  1471. x=0;
  1472. break;
  1473. default:
  1474. *video = *ptr;
  1475. video[1] = 15;
  1476. video += 2;
  1477. x++;
  1478. break;
  1479. }
  1480. ptr++;
  1481. }
  1482. va_end(ap);
  1483. }
  1484. #endif
  1485. #if 0
  1486. //--------------------------------------------------------------------------
  1487. // FULL SCREEN REFRESH/ANIM MANAGERS
  1488. //--------------------------------------------------------------------------
  1489. ///////////////////////////////////////////////////////////////////////////
  1490. //
  1491. // InitLatchRefresh() -- Loads an ILBM (JAMPAK'd) into the Master Latch
  1492. // to be used as the background refresh screen...
  1493. //
  1494. void InitLatchRefresh(char *filename)
  1495. {
  1496. struct Shape RefreshShp;
  1497. short yofs;
  1498. VW_ClearVideo(0);
  1499. if (LoadShape(filename,&RefreshShp))
  1500. TrashProg("Can't load %s",filename);
  1501. VW_SetLineWidth(RefreshShp.BPR);
  1502. yofs = masterswap/SCREENWIDTH;
  1503. MoveGfxDst(0,yofs); // Handle title screen
  1504. UnpackEGAShapeToScreen(&RefreshShp,0,0);
  1505. FreeShape(&RefreshShp);
  1506. MoveScreen(0,0);
  1507. VW_InitDoubleBuffer();
  1508. RF_NewPosition(0,0);
  1509. RF_Refresh();
  1510. SetUpdateBlock(0,0,RefreshShp.bmHdr.w,RefreshShp.bmHdr.h,3);
  1511. }
  1512. ////////////////////////////////////////////////////////////////////////////
  1513. //
  1514. // InitFullScreenAnim() -- Initialize ALL necessary functions for full screen
  1515. // animation types.
  1516. //
  1517. // filename - filename for background lbm.
  1518. // SpawnAll - spawn function to call to spawn all inital objects..
  1519. //
  1520. void InitFullScreenAnim(char *filename, void (*SpawnAll)())
  1521. {
  1522. unsigned old_flags;
  1523. old_flags = GE_SystemFlags.flags;
  1524. GE_SystemFlags.flags &= ~(GEsf_Tiles | GEsf_Panning | GEsf_RefreshVec);
  1525. CA_ClearMarks();
  1526. RFL_InitSpriteList();
  1527. InitObjArray();
  1528. if (SpawnAll)
  1529. SpawnAll();
  1530. CA_CacheMarks(NULL);
  1531. CalcInactivate();
  1532. CalcSprites();
  1533. InitLatchRefresh(filename);
  1534. RF_ForceRefresh();
  1535. RF_ForceRefresh();
  1536. GE_SystemFlags.flags = old_flags;
  1537. }
  1538. ///////////////////////////////////////////////////////////////////////////
  1539. //
  1540. // DoFullScreenAnim() -- a General "Do-Every-Thing" function that
  1541. // displays a full screen animation...
  1542. //
  1543. // filename - Filename of background lbm
  1544. // SpawnAll - Function to call to spawn all inital objects (REQUIRED)
  1545. // CheckKey - Function to call every cycle - The function called must
  1546. // return a value of greater than zero (0) to terminate the
  1547. // animation cycle. (REQUIRED)
  1548. // CleanUp - Function to call upon exiting the animation. (OPTIONAL)
  1549. //
  1550. void DoFullScreenAnim(char *filename, void (*SpawnAll)(), short (*CheckKey)(),void (*CleanUp)())
  1551. {
  1552. unsigned old_flags;
  1553. boolean ExitAnim = false;
  1554. // Save off the current system flags....
  1555. old_flags = GE_SystemFlags.flags;
  1556. GE_SystemFlags.flags &= ~(GEsf_Tiles | GEsf_Panning);
  1557. // randomize();
  1558. // Init refresh latch screen, initalize all object, and setup video mode.
  1559. InitFullScreenAnim(filename,SpawnAll);
  1560. VW_FadeIn();
  1561. while (!ExitAnim)
  1562. {
  1563. CalcInactivate();
  1564. CalcSprites();
  1565. RF_Refresh();
  1566. ExitAnim = (boolean)CheckKey();
  1567. }
  1568. // RemoveBOBList(player);
  1569. // CalcInactivate();
  1570. if (CleanUp)
  1571. CleanUp();
  1572. // Restore old system flags...
  1573. GE_SystemFlags.flags = old_flags;
  1574. }
  1575. #endif
  1576. //--------------------------------------------------------------------------
  1577. // FindFile()
  1578. //--------------------------------------------------------------------------
  1579. boolean FindFile(char *filename,char *disktext,char disknum)
  1580. {
  1581. extern boolean splitscreen;
  1582. char command[100];
  1583. char choices[]={sc_Escape,sc_Space,0},drive[2];
  1584. boolean fadeitout=false,rt_code=2;
  1585. if (!disktext)
  1586. disktext = GAMENAME;
  1587. drive[0] = getdisk() + 'A';
  1588. drive[1] = 0;
  1589. while (rt_code == 2)
  1590. {
  1591. if (Verify(filename))
  1592. rt_code = true;
  1593. else
  1594. {
  1595. if (ge_textmode)
  1596. {
  1597. clrscr();
  1598. gotoxy(1,1);
  1599. printf("\nInsert %s disk %d into drive %s.\n",disktext,disknum,drive);
  1600. printf("Press SPACE to continue, ESC to abort.\n");
  1601. }
  1602. else
  1603. {
  1604. if (splitscreen)
  1605. {
  1606. bufferofs = displayofs = screenloc[screenpage];
  1607. CenterWindow(38,5);
  1608. }
  1609. else
  1610. {
  1611. bufferofs = displayofs = 0;
  1612. US_CenterWindow(38,5);
  1613. }
  1614. strcpy(command,"\nInsert ");
  1615. strcat(command,disktext);
  1616. strcat(command," disk");
  1617. if (disknum != -1)
  1618. {
  1619. strcat(command," ");
  1620. itoa(disknum,command+strlen(command),10);
  1621. }
  1622. strcat(command," into drive ");
  1623. strcat(command,drive);
  1624. strcat(command,".");
  1625. US_CPrint(command);
  1626. US_CPrint("Press SPACE to continue, ESC to abort.");
  1627. }
  1628. sound(300);
  1629. VW_WaitVBL(20);
  1630. nosound();
  1631. if (!ge_textmode)
  1632. {
  1633. if (screenfaded)
  1634. {
  1635. VW_FadeIn();
  1636. fadeitout=true;
  1637. }
  1638. }
  1639. if (GetKeyChoice(choices,true) == sc_Escape)
  1640. rt_code = false;
  1641. }
  1642. }
  1643. if (!ge_textmode)
  1644. if (fadeitout)
  1645. VW_FadeOut();
  1646. return(rt_code);
  1647. }
  1648. #if 0
  1649. //--------------------------------------------------------------------------
  1650. // CacheAll()
  1651. //--------------------------------------------------------------------------
  1652. void CacheAV(char *title)
  1653. {
  1654. if (Verify("EGAGRAPH."EXT))
  1655. {
  1656. CA_CacheMarks(title);
  1657. if (!FindFile("EGAGRAPH."EXT,AUDIO_DISK))
  1658. TrashProg("Can't find graphics files.");
  1659. // cache in audio
  1660. current_disk = AUDIO_DISK;
  1661. }
  1662. else
  1663. {
  1664. // cache in audio
  1665. if (!FindFile("EGAGRAPH."EXT,VIDEO_DISK))
  1666. TrashProg("Can't find audio files.");
  1667. CA_CacheMarks(title);
  1668. current_disk = VIDEO_DISK;
  1669. }
  1670. }
  1671. #endif
  1672. #ifdef TEXT_PRESENTER
  1673. //--------------------------------------------------------------------------
  1674. //
  1675. // TEXT PRESENTER CODE
  1676. //
  1677. //--------------------------------------------------------------------------
  1678. typedef enum pi_stype {pis_pic2x,pis_latch_pic} pi_stype;
  1679. typedef struct { // 4 bytes
  1680. unsigned shapenum;
  1681. pi_stype shape_type;
  1682. } pi_shape_info;
  1683. #define pia_active 0x01
  1684. typedef struct { // 10 bytes
  1685. char baseshape;
  1686. char frame;
  1687. char maxframes;
  1688. short delay;
  1689. short maxdelay;
  1690. short x,y;
  1691. } pi_anim_info;
  1692. #define PI_CASE_SENSITIVE
  1693. #define PI_RETURN_CHAR '\n'
  1694. #define PI_CONTROL_CHAR '^'
  1695. #define PI_CNVT_CODE(c1,c2) ((c1)|(c2<<8))
  1696. // shape table provides a way for the presenter to access and
  1697. // display any shape.
  1698. //
  1699. pi_shape_info far pi_shape_table[] = {
  1700. {BOLTOBJPIC,pis_pic2x}, // 0
  1701. {NUKEOBJPIC,pis_pic2x},
  1702. {SKELETON_1PIC,pis_pic2x},
  1703. {EYE_WALK1PIC,pis_pic2x},
  1704. {ZOMB_WALK1PIC,pis_pic2x},
  1705. {TIMEOBJ1PIC,pis_pic2x}, // 5
  1706. {POTIONOBJPIC,pis_pic2x},
  1707. {RKEYOBJPIC,pis_pic2x},
  1708. {YKEYOBJPIC,pis_pic2x},
  1709. {GKEYOBJPIC,pis_pic2x},
  1710. {BKEYOBJPIC,pis_pic2x}, // 10
  1711. {RGEM1PIC,pis_pic2x},
  1712. {GGEM1PIC,pis_pic2x},
  1713. {BGEM1PIC,pis_pic2x},
  1714. {YGEM1PIC,pis_pic2x},
  1715. {PGEM1PIC,pis_pic2x}, // 15
  1716. {CHESTOBJPIC,pis_pic2x},
  1717. {PSHOT1PIC,pis_pic2x},
  1718. {RED_DEMON1PIC,pis_pic2x},
  1719. {MAGE1PIC,pis_pic2x},
  1720. {BAT1PIC,pis_pic2x}, // 20
  1721. {GREL1PIC,pis_pic2x},
  1722. {GODESS_WALK1PIC,pis_pic2x},
  1723. {ANT_WALK1PIC,pis_pic2x},
  1724. {FATDEMON_WALK1PIC,pis_pic2x},
  1725. {SUCCUBUS_WALK1PIC,pis_pic2x}, //25
  1726. {TREE_WALK1PIC,pis_pic2x},
  1727. {DRAGON_WALK1PIC,pis_pic2x},
  1728. {BUNNY_LEFT1PIC,pis_pic2x},
  1729. };
  1730. // anim table holds info about each different animation.
  1731. //
  1732. pi_anim_info far pi_anim_table[] = {{0,0,3,0,10}, // 0 BOLT
  1733. {1,0,3,0,10}, // NUKE
  1734. {2,0,4,0,10}, // SKELETON
  1735. {3,0,3,0,10}, // EYE
  1736. {4,0,3,0,10}, // ZOMBIE
  1737. {5,0,2,0,10}, // 5 FREEZE TIME
  1738. {11,0,2,0,10}, // RED GEM
  1739. {12,0,2,0,10}, // GREEN GEM
  1740. {13,0,2,0,10}, // BLUE GEM
  1741. {14,0,2,0,10}, // YELLOW GEM
  1742. {15,0,2,0,10}, // 10 PURPLE GEM
  1743. {17,0,2,0,10}, // PLAYER'S SHOT
  1744. {18,0,3,0,10}, // RED DEMON
  1745. {19,0,2,0,10}, // MAGE
  1746. {20,0,4,0,10}, // BAT
  1747. {21,0,2,0,10}, // 15 GRELMINAR
  1748. {22,0,3,0,10}, // GODESS
  1749. {23,0,3,0,10}, // ANT
  1750. {24,0,4,0,10}, // FAT DEMON
  1751. {25,0,4,0,10}, // SUCCUBUS
  1752. {26,0,2,0,10}, // 20 TREE
  1753. {27,0,3,0,10}, // DRAGON
  1754. {28,0,2,0,10}, // BUNNY
  1755. };
  1756. // anim list is created on the fly from the anim table...
  1757. // this allows a single animation to be display in more than
  1758. // one place...
  1759. //
  1760. pi_anim_info far pi_anim_list[PI_MAX_ANIMS];
  1761. boolean pi_recursing=false;
  1762. //--------------------------------------------------------------------------
  1763. // Presenter() - DANGEROUS DAVE "Presenter()" is more up-to-date than this.
  1764. //
  1765. //
  1766. // Active control codes:
  1767. //
  1768. // ^CE - center text between 'left margin' and 'right margin'
  1769. // ^FCn - set font color
  1770. // ^LMnnn - set left margin (if 'nnn' == "fff" uses current x)
  1771. // ^RMnnn - set right margin (if 'nnn' == "fff" uses current x)
  1772. // ^EP - end of page (waits for up/down arrow)
  1773. // ^PXnnn - move x to coordinate 'n'
  1774. // ^PYnnn - move y to coordinate 'n'
  1775. // ^XX - exit presenter
  1776. // ^LJ - left justify --\ ^RJ doesn't handle imbedded control
  1777. // ^RJ - right justify --/ codes properly. Use with caution.
  1778. // ^BGn - set background color
  1779. // ^ANnn - define animation
  1780. // ^SHnnn - display shape 'n' at current x,y
  1781. //
  1782. //
  1783. // Future control codes:
  1784. //
  1785. // ^OBnnn - activate object 'n'
  1786. // ^FL - flush to edges (whatever it's called)
  1787. //
  1788. //
  1789. // Other info:
  1790. //
  1791. // All 'n' values are hex numbers (0 - f), case insensitive.
  1792. // The number of N's listed is the number of digits REQUIRED by that control
  1793. // code. (IE: ^LMnnn MUST have 3 values! --> 003, 1a2, 01f, etc...)
  1794. //
  1795. // If a line consists only of control codes, the cursor is NOT advanced
  1796. // to the next line (the ending <CR><LF> is skipped). If just ONE non-control
  1797. // code is added, the number "8" for example, then the "8" is displayed
  1798. // and the cursor is advanced to the next line.
  1799. //
  1800. // ^CE must be on the same line as the text it should center!
  1801. //
  1802. //--------------------------------------------------------------------------
  1803. void Presenter(PresenterInfo *pi)
  1804. {
  1805. #ifdef AMIGA
  1806. XBitMap **font = pi->font;
  1807. #define ch_width(ch) font[ch]->pad
  1808. char font_height = font[0]->Rows;
  1809. #else
  1810. fontstruct _seg *font = (fontstruct _seg *)grsegs[STARTFONT];
  1811. #define MAX_PB 150
  1812. #define ch_width(ch) font->width[ch]
  1813. char font_height = font->height-1; // "-1" squeezes font vertically
  1814. char pb[MAX_PB];
  1815. short length;
  1816. #endif
  1817. enum {jm_left,jm_right,jm_flush};
  1818. char justify_mode = jm_left;
  1819. boolean centering=false;
  1820. short bgcolor = pi->bgcolor;
  1821. short xl=pi->xl,yl=pi->yl,xh=pi->xh,yh=pi->yh;
  1822. short cur_x = xl, cur_y = yl;
  1823. char far *first_ch = pi->script[0];
  1824. char far *scan_ch,temp;
  1825. short scan_x,PageNum=0,numanims=0;
  1826. boolean up_released=true,dn_released=true;
  1827. boolean presenting=true,start_of_line=true;
  1828. // if set background is first thing in file, make sure initial screen
  1829. // clear uses this color.
  1830. //
  1831. if (!_fstrncmp(first_ch,"^BG",3))
  1832. bgcolor = PI_VALUE(first_ch+3,1);
  1833. if (!pi_recursing)
  1834. {
  1835. PurgeAllGfx();
  1836. CachePage(first_ch);
  1837. }
  1838. VW_Bar(xl,yl,xh-xl+1,yh-yl+1,bgcolor);
  1839. while (presenting)
  1840. {
  1841. //
  1842. // HANDLE WORD-WRAPPING TEXT
  1843. //
  1844. if (*first_ch != PI_CONTROL_CHAR)
  1845. {
  1846. start_of_line = false;
  1847. // Parse script until one of the following:
  1848. //
  1849. // 1) text extends beyond right margin
  1850. // 2) NULL termination is reached
  1851. // 3) PI_RETURN_CHAR is reached
  1852. // 4) PI_CONTROL_CHAR is reached
  1853. //
  1854. scan_x = cur_x;
  1855. scan_ch = first_ch;
  1856. while ((scan_x+ch_width(*scan_ch) <= xh) && (*scan_ch) &&
  1857. (*scan_ch != PI_RETURN_CHAR) && (*scan_ch != PI_CONTROL_CHAR))
  1858. scan_x += ch_width(*scan_ch++);
  1859. // if 'text extends beyond right margin', scan backwards for
  1860. // a SPACE
  1861. //
  1862. if (scan_x+ch_width(*scan_ch) > xh)
  1863. {
  1864. short last_x = scan_x;
  1865. char far *last_ch = scan_ch;
  1866. while ((scan_ch != first_ch) && (*scan_ch != ' ') && (*scan_ch != PI_RETURN_CHAR))
  1867. scan_x -= ch_width(*scan_ch--);
  1868. if (scan_ch == first_ch)
  1869. scan_ch = last_ch, scan_x = last_x;
  1870. }
  1871. // print current line
  1872. //
  1873. #ifdef AMIGA
  1874. while (first_ch < scan_ch)
  1875. {
  1876. qBlit(font[*first_ch++],pi->dst,cur_x,cur_y);
  1877. // qBlit(font[*first_ch],pi->dst,cur_x,cur_y);
  1878. // cur_x += ch_width(*first_ch++);
  1879. }
  1880. #else
  1881. temp = *scan_ch;
  1882. *scan_ch = 0;
  1883. if ((justify_mode == jm_right)&&(!centering))
  1884. {
  1885. unsigned width,height;
  1886. VWL_MeasureString(first_ch,&width,&height,font);
  1887. cur_x = xh-width;
  1888. if (cur_x < xl)
  1889. cur_x = xl;
  1890. }
  1891. px = cur_x;
  1892. py = cur_y;
  1893. length = scan_ch-first_ch+1; // USL_DrawString only works with
  1894. if (length > MAX_PB)
  1895. Quit("Presenter(): Print buffer string too long!");
  1896. _fmemcpy(pb,first_ch,length); // near pointers...
  1897. if (*first_ch != '\n')
  1898. USL_DrawString(pb);
  1899. *scan_ch = temp;
  1900. first_ch = scan_ch;
  1901. #endif
  1902. cur_x = scan_x;
  1903. centering = false;
  1904. // skip SPACES / RETURNS at end of line
  1905. //
  1906. if ((*first_ch==' ') || (*first_ch==PI_RETURN_CHAR))
  1907. first_ch++;
  1908. // PI_CONTROL_CHARs don't advance to next character line
  1909. //
  1910. if (*scan_ch != PI_CONTROL_CHAR)
  1911. {
  1912. cur_x = xl;
  1913. cur_y += font_height;
  1914. }
  1915. }
  1916. else
  1917. //
  1918. // HANDLE CONTROL CODES
  1919. //
  1920. {
  1921. PresenterInfo endmsg;
  1922. pi_anim_info far *anim;
  1923. pi_shape_info far *shape_info;
  1924. unsigned shapenum;
  1925. short length;
  1926. char far *s;
  1927. if (first_ch[-1] == '\n')
  1928. start_of_line = true;
  1929. first_ch++;
  1930. #ifndef PI_CASE_SENSITIVE
  1931. *first_ch=toupper(*first_ch);
  1932. *(first_ch+1)=toupper(*(first_ch+1));
  1933. #endif
  1934. switch (*((unsigned far *)first_ch)++)
  1935. {
  1936. // CENTER TEXT ------------------------------------------------------
  1937. //
  1938. case PI_CNVT_CODE('C','E'):
  1939. length = 0;
  1940. s = first_ch;
  1941. while (*s && (*s != PI_RETURN_CHAR))
  1942. {
  1943. switch (*s)
  1944. {
  1945. case PI_CONTROL_CHAR:
  1946. s++;
  1947. switch (*((unsigned *)s)++)
  1948. {
  1949. #ifndef AMIGA
  1950. case PI_CNVT_CODE('F','C'):
  1951. case PI_CNVT_CODE('B','G'):
  1952. s++;
  1953. break;
  1954. #endif
  1955. case PI_CNVT_CODE('L','M'):
  1956. case PI_CNVT_CODE('R','M'):
  1957. case PI_CNVT_CODE('S','H'):
  1958. case PI_CNVT_CODE('P','X'):
  1959. case PI_CNVT_CODE('P','Y'):
  1960. s += 3;
  1961. break;
  1962. case PI_CNVT_CODE('L','J'):
  1963. case PI_CNVT_CODE('R','J'):
  1964. // No parameters to pass over!
  1965. break;
  1966. }
  1967. break;
  1968. default:
  1969. length += ch_width(*s++);
  1970. break;
  1971. }
  1972. }
  1973. cur_x = ((xh-xl+1)-length)/2;
  1974. centering = true;
  1975. break;
  1976. // DRAW SHAPE -------------------------------------------------------
  1977. //
  1978. case PI_CNVT_CODE('S','H'):
  1979. shapenum = PI_VALUE(first_ch,3);
  1980. first_ch += 3;
  1981. shape_info = &pi_shape_table[shapenum];
  1982. switch (shape_info->shape_type)
  1983. {
  1984. short width;
  1985. case pis_pic2x:
  1986. cur_x = ((cur_x+2) + 7) & 0xFFF8;
  1987. width=BoxAroundPic(cur_x-2,cur_y-1,shape_info->shapenum,pi);
  1988. VW_DrawPic2x(cur_x>>3,cur_y,shape_info->shapenum);
  1989. cur_x += width;
  1990. break;
  1991. }
  1992. break;
  1993. // INIT ANIMATION ---------------------------------------------------
  1994. //
  1995. case PI_CNVT_CODE('A','N'):
  1996. shapenum = PI_VALUE(first_ch,2);
  1997. first_ch += 2;
  1998. _fmemcpy(&pi_anim_list[numanims],&pi_anim_table[shapenum],sizeof(pi_anim_info));
  1999. anim = &pi_anim_list[numanims++];
  2000. shape_info = &pi_shape_table[anim->baseshape+anim->frame];
  2001. switch (shape_info->shape_type)
  2002. {
  2003. short width;
  2004. case pis_pic2x:
  2005. cur_x = ((cur_x+2) + 7) & 0xFFF8;
  2006. width=BoxAroundPic(cur_x-2,cur_y-1,shape_info->shapenum,pi);
  2007. VW_DrawPic2x(cur_x>>3,cur_y,shape_info->shapenum);
  2008. anim->x = cur_x>>3;
  2009. anim->y = cur_y;
  2010. cur_x += width;
  2011. break;
  2012. }
  2013. break;
  2014. #ifndef AMIGA
  2015. // FONT COLOR -------------------------------------------------------
  2016. //
  2017. case PI_CNVT_CODE('F','C'):
  2018. fontcolor = bgcolor ^ PI_VALUE(first_ch++,1);
  2019. break;
  2020. #endif
  2021. // BACKGROUND COLOR -------------------------------------------------
  2022. //
  2023. case PI_CNVT_CODE('B','G'):
  2024. bgcolor = PI_VALUE(first_ch++,1);
  2025. break;
  2026. // LEFT MARGIN ------------------------------------------------------
  2027. //
  2028. case PI_CNVT_CODE('L','M'):
  2029. shapenum = PI_VALUE(first_ch,3);
  2030. first_ch += 3;
  2031. if (shapenum == 0xfff)
  2032. xl = cur_x;
  2033. else
  2034. xl = shapenum;
  2035. break;
  2036. // RIGHT MARGIN -----------------------------------------------------
  2037. //
  2038. case PI_CNVT_CODE('R','M'):
  2039. shapenum = PI_VALUE(first_ch,3);
  2040. first_ch += 3;
  2041. if (shapenum == 0xfff)
  2042. xh = cur_x;
  2043. else
  2044. xh = shapenum;
  2045. break;
  2046. // SET X COORDINATE -------------------------------------------------
  2047. //
  2048. case PI_CNVT_CODE('P','X'):
  2049. cur_x = PI_VALUE(first_ch,3);
  2050. first_ch += 3;
  2051. break;
  2052. // SET Y COORDINATE -------------------------------------------------
  2053. //
  2054. case PI_CNVT_CODE('P','Y'):
  2055. cur_y = PI_VALUE(first_ch,3);
  2056. first_ch += 3;
  2057. break;
  2058. // LEFT JUSTIFY -----------------------------------------------------
  2059. //
  2060. case PI_CNVT_CODE('L','J'):
  2061. justify_mode = jm_left;
  2062. break;
  2063. // RIGHT JUSTIFY ----------------------------------------------------
  2064. //
  2065. case PI_CNVT_CODE('R','J'):
  2066. justify_mode = jm_right;
  2067. break;
  2068. // END OF PAGE ------------------------------------------------------
  2069. //
  2070. case PI_CNVT_CODE('E','P'):
  2071. if (pi_recursing)
  2072. Quit("Presenter(): Can't use ^EP when recursing!");
  2073. endmsg.xl = cur_x;
  2074. endmsg.yl = yh-(font_height+2);
  2075. endmsg.xh = xh;
  2076. endmsg.yh = yh;
  2077. endmsg.bgcolor = bgcolor;
  2078. endmsg.ltcolor = pi->ltcolor;
  2079. endmsg.dkcolor = pi->dkcolor;
  2080. endmsg.script[0] = (char far *)"^CE^FC8- ^FC0ESC ^FC8to return to play, or ^FC0ARROW KEYS ^FC8to page through more Help -^XX";
  2081. pi_recursing = true;
  2082. Presenter(&endmsg);
  2083. pi_recursing = false;
  2084. #ifndef AMIGA
  2085. if (screenfaded)
  2086. VW_FadeIn();
  2087. VW_ColorBorder(8 | 56);
  2088. #endif
  2089. while (1)
  2090. {
  2091. #ifndef AMIGA
  2092. long newtime;
  2093. VW_WaitVBL(1);
  2094. newtime = TimeCount;
  2095. realtics = tics = newtime-lasttimecount;
  2096. lasttimecount = newtime;
  2097. #else
  2098. WaitVBL(1);
  2099. CALC_TICS;
  2100. #endif
  2101. AnimatePage(numanims);
  2102. IN_ReadControl(0,&control);
  2103. if (control.button1 || Keyboard[1])
  2104. {
  2105. presenting=false;
  2106. break;
  2107. }
  2108. else
  2109. {
  2110. if (ControlTypeUsed != ctrl_Keyboard)
  2111. control.dir = dir_None;
  2112. if (((control.dir == dir_North) || (control.dir == dir_West)) && (PageNum))
  2113. {
  2114. if (up_released)
  2115. {
  2116. PageNum--;
  2117. up_released = false;
  2118. break;
  2119. }
  2120. }
  2121. else
  2122. {
  2123. up_released = true;
  2124. if (((control.dir == dir_South) || (control.dir == dir_East)) && (PageNum < pi->numpages-1))
  2125. {
  2126. if (dn_released)
  2127. {
  2128. PageNum++;
  2129. dn_released = false;
  2130. break;
  2131. }
  2132. }
  2133. else
  2134. dn_released = true;
  2135. }
  2136. }
  2137. }
  2138. cur_x = xl;
  2139. cur_y = yl;
  2140. if (cur_y+font_height > yh)
  2141. cur_y = yh-font_height;
  2142. first_ch = pi->script[PageNum];
  2143. numanims = 0;
  2144. PurgeAllGfx();
  2145. CachePage(first_ch);
  2146. VW_Bar(xl,yl,xh-xl+1,yh-yl+1,bgcolor);
  2147. break;
  2148. // EXIT PRESENTER ---------------------------------------------------
  2149. //
  2150. case PI_CNVT_CODE('X','X'):
  2151. presenting=false;
  2152. break;
  2153. }
  2154. if ((first_ch[0] == ' ') && (first_ch[1] == '\n') && start_of_line)
  2155. first_ch += 2;
  2156. }
  2157. }
  2158. }
  2159. //--------------------------------------------------------------------------
  2160. // ResetAnims()
  2161. //--------------------------------------------------------------------------
  2162. void ResetAnims()
  2163. {
  2164. pi_anim_list[0].baseshape = -1;
  2165. }
  2166. //--------------------------------------------------------------------------
  2167. // AnimatePage()
  2168. //--------------------------------------------------------------------------
  2169. void AnimatePage(short numanims)
  2170. {
  2171. pi_anim_info far *anim=pi_anim_list;
  2172. pi_shape_info far *shape_info;
  2173. while (numanims--)
  2174. {
  2175. anim->delay += tics;
  2176. if (anim->delay >= anim->maxdelay)
  2177. {
  2178. anim->delay = 0;
  2179. anim->frame++;
  2180. if (anim->frame == anim->maxframes)
  2181. anim->frame = 0;
  2182. #if ANIM_USES_SHAPETABLE
  2183. shape_info = &pi_shape_table[anim->baseshape+anim->frame];
  2184. #else
  2185. shape_info = &pi_shape_table[anim->baseshape];
  2186. #endif
  2187. switch (shape_info->shape_type)
  2188. {
  2189. case pis_pic2x:
  2190. #if ANIM_USES_SHAPETABLE
  2191. VW_DrawPic2x(anim->x,anim->y,shape_info->shapenum);
  2192. #else
  2193. VW_DrawPic2x(anim->x,anim->y,shape_info->shapenum+anim->frame);
  2194. #endif
  2195. break;
  2196. }
  2197. }
  2198. anim++;
  2199. }
  2200. }
  2201. //--------------------------------------------------------------------------
  2202. // BoxAroundPic()
  2203. //--------------------------------------------------------------------------
  2204. short BoxAroundPic(short x1, short y1, unsigned picnum, PresenterInfo *pi)
  2205. {
  2206. short x2,y2;
  2207. x2 = x1+(pictable[picnum-STARTPICS].width<<4)+2;
  2208. y2 = y1+(pictable[picnum-STARTPICS].height)+1;
  2209. VWB_Hlin(x1,x2,y1,pi->ltcolor);
  2210. VWB_Hlin(x1,x2,y2,pi->dkcolor);
  2211. VWB_Vlin(y1,y2,x1,pi->ltcolor);
  2212. VWB_Vlin(y1,y2,x1+1,pi->ltcolor);
  2213. VWB_Vlin(y1,y2,x2,pi->dkcolor);
  2214. VWB_Vlin(y1,y2,x2+1,pi->dkcolor);
  2215. return(x2-x1+1);
  2216. }
  2217. //--------------------------------------------------------------------------
  2218. // PurgeAllGfx()
  2219. //--------------------------------------------------------------------------
  2220. void PurgeAllGfx()
  2221. {
  2222. ResetAnims();
  2223. FreeUpMemory();
  2224. }
  2225. //--------------------------------------------------------------------------
  2226. // CachePage()
  2227. //--------------------------------------------------------------------------
  2228. void CachePage(char far *script)
  2229. {
  2230. pi_anim_info far *anim;
  2231. short loop;
  2232. unsigned shapenum;
  2233. boolean end_of_page=false;
  2234. short numanims=0;
  2235. while (!end_of_page)
  2236. {
  2237. switch (*script++)
  2238. {
  2239. case PI_CONTROL_CHAR:
  2240. #ifndef PI_CASE_SENSITIVE
  2241. *script=toupper(*script);
  2242. *(script+1)=toupper(*(script+1));
  2243. #endif
  2244. switch (*((unsigned far *)script)++)
  2245. {
  2246. case PI_CNVT_CODE('S','H'):
  2247. shapenum = PI_VALUE(script,3);
  2248. script += 3;
  2249. CA_MarkGrChunk(pi_shape_table[shapenum].shapenum);
  2250. break;
  2251. case PI_CNVT_CODE('A','N'):
  2252. shapenum = PI_VALUE(script,2);
  2253. script += 2;
  2254. if (numanims++ == PI_MAX_ANIMS)
  2255. Quit("CachePage(): Too many anims on one page.");
  2256. anim = &pi_anim_table[shapenum];
  2257. #if ANIM_USES_SHAPETABLE
  2258. for (loop=anim->baseshape;loop < anim->baseshape+anim->maxframes; loop++)
  2259. CA_MarkGrChunk(pi_shape_table[loop].shapenum);
  2260. #else
  2261. shapenum = pi_shape_table[anim->baseshape].shapenum;
  2262. for (loop=0; loop<anim->maxframes; loop++)
  2263. CA_MarkGrChunk(shapenum+loop);
  2264. #endif
  2265. break;
  2266. case PI_CNVT_CODE('X','X'):
  2267. case PI_CNVT_CODE('E','P'):
  2268. end_of_page = true;
  2269. break;
  2270. }
  2271. break;
  2272. }
  2273. }
  2274. CA_CacheMarks(NULL);
  2275. }
  2276. //--------------------------------------------------------------------------
  2277. // PI_VALUE()
  2278. //--------------------------------------------------------------------------
  2279. unsigned PI_VALUE(char far *ptr,char num_nybbles)
  2280. {
  2281. char ch,nybble,shift;
  2282. unsigned value=0;
  2283. for (nybble=0; nybble<num_nybbles; nybble++)
  2284. {
  2285. shift = 4*(num_nybbles-nybble-1);
  2286. ch = *ptr++;
  2287. if (isxdigit(ch))
  2288. if (isalpha(ch))
  2289. value |= (toupper(ch)-'A'+10)<<shift;
  2290. else
  2291. value |= (ch-'0')<<shift;
  2292. }
  2293. return(value);
  2294. }
  2295. //--------------------------------------------------------------------------
  2296. // LoadPresenterScript()
  2297. //--------------------------------------------------------------------------
  2298. long LoadPresenterScript(char *filename,PresenterInfo *pi)
  2299. {
  2300. #pragma warn -pia
  2301. long size;
  2302. if (!(size=BLoad(filename,&pi->scriptstart)))
  2303. return(0);
  2304. pi->script[0] = MK_FP(pi->scriptstart,0);
  2305. pi->script[0][size-1] = 0; // Last byte is trashed!
  2306. InitPresenterScript(pi);
  2307. return(size);
  2308. #pragma warn +pia
  2309. }
  2310. //-------------------------------------------------------------------------
  2311. // FreePresenterScript()
  2312. //-------------------------------------------------------------------------
  2313. void FreePresenterScript(PresenterInfo *pi)
  2314. {
  2315. if (pi->script)
  2316. MM_FreePtr(&pi->scriptstart);
  2317. }
  2318. //-------------------------------------------------------------------------
  2319. // InitPresenterScript()
  2320. //-------------------------------------------------------------------------
  2321. void InitPresenterScript(PresenterInfo *pi)
  2322. {
  2323. char far *script = pi->script[0];
  2324. pi->numpages = 1; // Assume at least 1 page
  2325. while (*script)
  2326. {
  2327. switch (*script++)
  2328. {
  2329. case PI_CONTROL_CHAR:
  2330. #ifndef PI_CASE_SENSITIVE
  2331. *script=toupper(*script);
  2332. *(script+1)=toupper(*(script+1));
  2333. #endif
  2334. switch (*((unsigned far *)script)++)
  2335. {
  2336. case PI_CNVT_CODE('E','P'):
  2337. if (pi->numpages < PI_MAX_PAGES)
  2338. pi->script[pi->numpages++] = script;
  2339. else
  2340. TrashProg("GE ERROR: Too many Presenter() pages. --> %d",pi->numpages);
  2341. break;
  2342. }
  2343. break;
  2344. case '\r':
  2345. if (*script == '\n')
  2346. {
  2347. *(script-1) = ' ';
  2348. script++;
  2349. }
  2350. break;
  2351. }
  2352. }
  2353. pi->numpages--; // Last page defined is not a real page.
  2354. }
  2355. #endif
  2356. //-------------------------------------------------------------------------
  2357. // AnimateWallList()
  2358. //-------------------------------------------------------------------------
  2359. void AnimateWallList(void)
  2360. {
  2361. walltype *wall, *check;
  2362. unsigned i;
  2363. int tile,org_tile;
  2364. if (wall_anim_delay>0)
  2365. {
  2366. wall_anim_delay-=realtics;
  2367. return;
  2368. }
  2369. //
  2370. // Re-Init our counter...
  2371. //
  2372. wall_anim_delay = wall_anim_time;
  2373. //
  2374. // Clear all previous flags marking animation being DONE.
  2375. //
  2376. for (i=0;i<NUMFLOORS;i++)
  2377. TILE_FLAGS(i) &= ~tf_MARKED;
  2378. //
  2379. // Run though wall list updating only then needed animations
  2380. //
  2381. for (wall=&walls[1];wall<rightwall;wall++)
  2382. {
  2383. org_tile = tile = wall->color + wall_anim_pos[wall->color];
  2384. if (ANIM_FLAGS(tile))
  2385. {
  2386. do
  2387. {
  2388. if (!(TILE_FLAGS(tile) & tf_MARKED))
  2389. {
  2390. //
  2391. // update our offset table (0-NUMANIMS)
  2392. //
  2393. wall_anim_pos[tile] += (char signed)ANIM_FLAGS(tile+(char signed)wall_anim_pos[tile]);
  2394. //
  2395. // Mark tile as being already updated..
  2396. //
  2397. TILE_FLAGS(tile) |= tf_MARKED;
  2398. }
  2399. //
  2400. // Check rest of tiles in this animation string...
  2401. //
  2402. tile += (char signed)ANIM_FLAGS(tile);
  2403. } while (tile != org_tile);
  2404. }
  2405. }
  2406. }