ID_US_1.C 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318
  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. //
  19. // ID Engine
  20. // ID_US_1.c - User Manager - General routines
  21. // v1.1d1
  22. // By Jason Blochowiak
  23. // Hacked up for Catacomb 3D
  24. //
  25. //
  26. // This module handles dealing with user input & feedback
  27. //
  28. // Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
  29. // and Refresh Mgrs, Memory Mgr for background save/restore
  30. //
  31. // Globals:
  32. // ingame - Flag set by game indicating if a game is in progress
  33. // abortgame - Flag set if the current game should be aborted (if a load
  34. // game fails)
  35. // loadedgame - Flag set if a game was loaded
  36. // abortprogram - Normally nil, this points to a terminal error message
  37. // if the program needs to abort
  38. // restartgame - Normally set to gd_Continue, this is set to one of the
  39. // difficulty levels if a new game should be started
  40. // PrintX, PrintY - Where the User Mgr will print (global coords)
  41. // WindowX,WindowY,WindowW,WindowH - The dimensions of the current
  42. // window
  43. //
  44. #include "ID_HEADS.H"
  45. #pragma hdrstop
  46. #pragma warn -pia
  47. // Special imports
  48. extern boolean showscorebox;
  49. #ifdef KEEN
  50. extern boolean oldshooting;
  51. extern ScanCode firescan;
  52. #else
  53. ScanCode firescan;
  54. #endif
  55. // Global variables
  56. char *abortprogram;
  57. boolean NoWait,
  58. HighScoresDirty;
  59. word PrintX,PrintY;
  60. word WindowX,WindowY,WindowW,WindowH;
  61. word MaxX=320,MaxY=200; // MDM (GAMERS EDGE)
  62. // Internal variables
  63. #define ConfigVersion 1
  64. static char *ParmStrings[] = {"TEDLEVEL","NOWAIT"},
  65. *ParmStrings2[] = {"COMP","NOCOMP"};
  66. static boolean US_Started;
  67. boolean Button0,Button1,
  68. CursorBad;
  69. int CursorX,CursorY;
  70. void (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
  71. (*USL_DrawString)(char far *) = VWB_DrawPropString;
  72. boolean (*USL_SaveGame)(int),(*USL_LoadGame)(int);
  73. void (*USL_ResetGame)(void);
  74. SaveGame Games[MaxSaveGames];
  75. HighScore Scores[MaxScores] =
  76. {
  77. {"Sir Lancelot",500,3},
  78. {"",0},
  79. {"",0},
  80. {"",0},
  81. {"",0},
  82. {"",0},
  83. {"",0},
  84. };
  85. // Internal routines
  86. // Public routines
  87. ///////////////////////////////////////////////////////////////////////////
  88. //
  89. // USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
  90. // from DOS.
  91. //
  92. ///////////////////////////////////////////////////////////////////////////
  93. #pragma warn -par
  94. #pragma warn -rch
  95. int
  96. USL_HardError(word errval,int ax,int bp,int si)
  97. {
  98. #define IGNORE 0
  99. #define RETRY 1
  100. #define ABORT 2
  101. extern void ShutdownId(void);
  102. static char buf[32];
  103. static WindowRec wr;
  104. int di;
  105. char c,*s,*t;
  106. di = _DI;
  107. if (ax < 0)
  108. s = "Device Error";
  109. else
  110. {
  111. if ((di & 0x00ff) == 0)
  112. s = "Drive ~ is Write Protected";
  113. else
  114. s = "Error on Drive ~";
  115. for (t = buf;*s;s++,t++) // Can't use sprintf()
  116. if ((*t = *s) == '~')
  117. *t = (ax & 0x00ff) + 'A';
  118. *t = '\0';
  119. s = buf;
  120. }
  121. c = peekb(0x40,0x49); // Get the current screen mode
  122. if ((c < 4) || (c == 7))
  123. goto oh_kill_me;
  124. // DEBUG - handle screen cleanup
  125. US_SaveWindow(&wr);
  126. US_CenterWindow(30,3);
  127. US_CPrint(s);
  128. US_CPrint("(R)etry or (A)bort?");
  129. VW_UpdateScreen();
  130. IN_ClearKeysDown();
  131. asm sti // Let the keyboard interrupts come through
  132. while (true)
  133. {
  134. switch (IN_WaitForASCII())
  135. {
  136. case key_Escape:
  137. case 'a':
  138. case 'A':
  139. goto oh_kill_me;
  140. break;
  141. case key_Return:
  142. case key_Space:
  143. case 'r':
  144. case 'R':
  145. US_ClearWindow();
  146. VW_UpdateScreen();
  147. US_RestoreWindow(&wr);
  148. return(RETRY);
  149. break;
  150. }
  151. }
  152. oh_kill_me:
  153. abortprogram = s;
  154. ShutdownId();
  155. fprintf(stderr,"Terminal Error: %s\n",s);
  156. if (tedlevel)
  157. fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
  158. return(ABORT);
  159. #undef IGNORE
  160. #undef RETRY
  161. #undef ABORT
  162. }
  163. #pragma warn +par
  164. #pragma warn +rch
  165. ///////////////////////////////////////////////////////////////////////////
  166. //
  167. // USL_GiveSaveName() - Returns a pointer to a static buffer that contains
  168. // the filename to use for the specified save game
  169. //
  170. ///////////////////////////////////////////////////////////////////////////
  171. char *
  172. USL_GiveSaveName(word game)
  173. {
  174. static char name[] = "SAVEGAMx."EXT;
  175. name[7] = '0' + game;
  176. return(name);
  177. }
  178. ///////////////////////////////////////////////////////////////////////////
  179. //
  180. // US_SetLoadSaveHooks() - Sets the routines that the User Mgr calls after
  181. // reading or writing the save game headers
  182. //
  183. ///////////////////////////////////////////////////////////////////////////
  184. void
  185. US_SetLoadSaveHooks(boolean (*load)(int),boolean (*save)(int),void (*reset)(void))
  186. {
  187. USL_LoadGame = load;
  188. USL_SaveGame = save;
  189. USL_ResetGame = reset;
  190. }
  191. ///////////////////////////////////////////////////////////////////////////
  192. //
  193. // USL_ReadConfig() - Reads the configuration file, if present, and sets
  194. // things up accordingly. If it's not present, uses defaults. This file
  195. // includes the high scores.
  196. //
  197. ///////////////////////////////////////////////////////////////////////////
  198. static void
  199. USL_ReadConfig(void)
  200. {
  201. boolean gotit;
  202. char sig[sizeof(EXT)];
  203. word version;
  204. int file;
  205. SDMode sd;
  206. SMMode sm;
  207. ControlType ctl;
  208. if ((file = open("CONFIG."EXT,O_BINARY | O_RDONLY)) != -1)
  209. {
  210. read(file,sig,sizeof(EXT));
  211. read(file,&version,sizeof(version));
  212. if (strcmp(sig,EXT) || (version != ConfigVersion))
  213. {
  214. close(file);
  215. goto rcfailed;
  216. }
  217. read(file,Scores,sizeof(HighScore) * MaxScores);
  218. read(file,&sd,sizeof(sd));
  219. read(file,&sm,sizeof(sm));
  220. read(file,&ctl,sizeof(ctl));
  221. read(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));
  222. read(file,&showscorebox,sizeof(showscorebox));
  223. read(file,&compatability,sizeof(compatability));
  224. #ifdef KEEN
  225. read(file,&oldshooting,sizeof(oldshooting));
  226. read(file,&firescan,sizeof(firescan));
  227. #endif
  228. close(file);
  229. HighScoresDirty = false;
  230. gotit = true;
  231. }
  232. else
  233. {
  234. rcfailed:
  235. sd = sdm_Off;
  236. sm = smm_Off;
  237. ctl = ctrl_Keyboard;
  238. showscorebox = true;
  239. #ifdef KEEN
  240. oldshooting = false;
  241. #endif
  242. gotit = false;
  243. HighScoresDirty = true;
  244. }
  245. SD_Default(gotit,sd,sm);
  246. IN_Default(gotit,ctl);
  247. }
  248. ///////////////////////////////////////////////////////////////////////////
  249. //
  250. // USL_WriteConfig() - Writes out the current configuration, including the
  251. // high scores.
  252. //
  253. ///////////////////////////////////////////////////////////////////////////
  254. static void
  255. USL_WriteConfig(void)
  256. {
  257. word version;
  258. int file;
  259. version = ConfigVersion;
  260. file = open("CONFIG."EXT,O_CREAT | O_BINARY | O_WRONLY,
  261. S_IREAD | S_IWRITE | S_IFREG);
  262. if (file != -1)
  263. {
  264. write(file,EXT,sizeof(EXT));
  265. write(file,&version,sizeof(version));
  266. write(file,Scores,sizeof(HighScore) * MaxScores);
  267. write(file,&SoundMode,sizeof(SoundMode));
  268. write(file,&MusicMode,sizeof(MusicMode));
  269. if // Hack
  270. (
  271. (Controls[0] == ctrl_Joystick1)
  272. || (Controls[0] == ctrl_Joystick2)
  273. )
  274. Controls[0] = ctrl_Keyboard;
  275. write(file,&(Controls[0]),sizeof(Controls[0]));
  276. write(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));
  277. write(file,&showscorebox,sizeof(showscorebox));
  278. write(file,&compatability,sizeof(compatability));
  279. #ifdef KEEN
  280. write(file,&oldshooting,sizeof(oldshooting));
  281. write(file,&firescan,sizeof(firescan));
  282. #endif
  283. close(file);
  284. }
  285. }
  286. ///////////////////////////////////////////////////////////////////////////
  287. //
  288. // USL_CheckSavedGames() - Checks to see which saved games are present
  289. // & valid
  290. //
  291. ///////////////////////////////////////////////////////////////////////////
  292. static void
  293. USL_CheckSavedGames(void)
  294. {
  295. boolean ok;
  296. char *filename;
  297. word i;
  298. int file;
  299. SaveGame *game;
  300. USL_SaveGame = 0;
  301. USL_LoadGame = 0;
  302. for (i = 0,game = Games;i < MaxSaveGames;i++,game++)
  303. {
  304. filename = USL_GiveSaveName(i);
  305. ok = false;
  306. if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)
  307. {
  308. if
  309. (
  310. (read(file,game,sizeof(*game)) == sizeof(*game))
  311. && (!strcmp(game->signature,EXT))
  312. && (game->oldtest == &PrintX)
  313. )
  314. ok = true;
  315. close(file);
  316. }
  317. if (ok)
  318. game->present = true;
  319. else
  320. {
  321. strcpy(game->signature,EXT);
  322. game->present = false;
  323. strcpy(game->name,"Empty");
  324. }
  325. }
  326. }
  327. ///////////////////////////////////////////////////////////////////////////
  328. //
  329. // US_Startup() - Starts the User Mgr
  330. //
  331. ///////////////////////////////////////////////////////////////////////////
  332. void
  333. US_Startup(void)
  334. {
  335. int i;
  336. if (US_Started)
  337. return;
  338. harderr(USL_HardError); // Install the fatal error handler
  339. US_InitRndT(true); // Initialize the random number generator
  340. USL_ReadConfig(); // Read config file
  341. for (i = 1;i < _argc;i++)
  342. {
  343. switch (US_CheckParm(_argv[i],ParmStrings2))
  344. {
  345. case 0:
  346. if (grmode == EGAGR)
  347. compatability = true;
  348. break;
  349. case 1:
  350. compatability = false;
  351. break;
  352. }
  353. }
  354. US_Started = true;
  355. }
  356. ///////////////////////////////////////////////////////////////////////////
  357. //
  358. // US_Setup() - Does the disk access part of the User Mgr's startup
  359. //
  360. ///////////////////////////////////////////////////////////////////////////
  361. void
  362. US_Setup(void)
  363. {
  364. USL_CheckSavedGames(); // Check which saved games are present
  365. }
  366. ///////////////////////////////////////////////////////////////////////////
  367. //
  368. // US_Shutdown() - Shuts down the User Mgr
  369. //
  370. ///////////////////////////////////////////////////////////////////////////
  371. void
  372. US_Shutdown(void)
  373. {
  374. if (!US_Started)
  375. return;
  376. if (!abortprogram)
  377. USL_WriteConfig();
  378. US_Started = false;
  379. }
  380. ///////////////////////////////////////////////////////////////////////////
  381. //
  382. // US_CheckParm() - checks to see if a string matches one of a set of
  383. // strings. The check is case insensitive. The routine returns the
  384. // index of the string that matched, or -1 if no matches were found
  385. //
  386. ///////////////////////////////////////////////////////////////////////////
  387. int
  388. US_CheckParm(char *parm,char **strings)
  389. {
  390. char cp,cs,
  391. *p,*s;
  392. int i;
  393. while (!isalpha(*parm)) // Skip non-alphas
  394. parm++;
  395. for (i = 0;*strings && **strings;i++)
  396. {
  397. for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
  398. {
  399. cs = *s++;
  400. if (!cs)
  401. return(i);
  402. cp = *p++;
  403. if (isupper(cs))
  404. cs = tolower(cs);
  405. if (isupper(cp))
  406. cp = tolower(cp);
  407. }
  408. }
  409. return(-1);
  410. }
  411. #if 0
  412. ///////////////////////////////////////////////////////////////////////////
  413. //
  414. // USL_ScreenDraw() - Draws a chunk of the text screen (called only by
  415. // US_TextScreen())
  416. //
  417. ///////////////////////////////////////////////////////////////////////////
  418. static void
  419. USL_ScreenDraw(word x,word y,char *s,byte attr)
  420. {
  421. byte far *screen,far *oscreen;
  422. screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2));
  423. oscreen = (&introscn + 7) + ((x - 1) * 2) + (y * 80 * 2) + 1;
  424. while (*s)
  425. {
  426. *screen++ = *s++;
  427. if (attr != 0xff)
  428. {
  429. *screen++ = (attr & 0x8f) | (*oscreen & 0x70);
  430. oscreen += 2;
  431. }
  432. else
  433. screen++;
  434. }
  435. }
  436. #endif
  437. ///////////////////////////////////////////////////////////////////////////
  438. //
  439. // USL_ClearTextScreen() - Makes sure the screen is in text mode, clears it,
  440. // and moves the cursor to the leftmost column of the bottom line
  441. //
  442. ///////////////////////////////////////////////////////////////////////////
  443. static void
  444. USL_ClearTextScreen(void)
  445. {
  446. // Set to 80x25 color text mode
  447. _AL = 3; // Mode 3
  448. _AH = 0x00;
  449. geninterrupt(0x10);
  450. // Use BIOS to move the cursor to the bottom of the screen
  451. _AH = 0x0f;
  452. geninterrupt(0x10); // Get current video mode into _BH
  453. _DL = 0; // Lefthand side of the screen
  454. _DH = 24; // Bottom row
  455. _AH = 0x02;
  456. geninterrupt(0x10);
  457. }
  458. #if 0
  459. ///////////////////////////////////////////////////////////////////////////
  460. //
  461. // US_TextScreen() - Puts up the startup text screen
  462. // Note: These are the only User Manager functions that can be safely called
  463. // before the User Mgr has been started up
  464. //
  465. ///////////////////////////////////////////////////////////////////////////
  466. void
  467. US_TextScreen(void)
  468. {
  469. word i,n;
  470. USL_ClearTextScreen();
  471. _fmemcpy(MK_FP(0xb800,0),7 + &introscn,80 * 25 * 2);
  472. // Check for TED launching here
  473. for (i = 1;i < _argc;i++)
  474. {
  475. n = US_CheckParm(_argv[i],ParmStrings);
  476. if (n == 0)
  477. {
  478. tedlevelnum = atoi(_argv[i + 1]);
  479. if (tedlevelnum >= 0)
  480. {
  481. tedlevel = true;
  482. return;
  483. }
  484. else
  485. break;
  486. }
  487. else if (n == 1)
  488. {
  489. NoWait = true;
  490. return;
  491. }
  492. }
  493. }
  494. ///////////////////////////////////////////////////////////////////////////
  495. //
  496. // USL_Show() - Changes the appearance of one of the fields on the text
  497. // screen. Possibly adds a checkmark in front of it and highlights it
  498. //
  499. ///////////////////////////////////////////////////////////////////////////
  500. static void
  501. USL_Show(word x,word y,word w,boolean show,boolean hilight)
  502. {
  503. byte far *screen,far *oscreen;
  504. screen = MK_FP(0xb800,((x - 1) * 2) + (y * 80 * 2));
  505. oscreen = (&introscn + 7) + ((x - 1) * 2) + (y * 80 * 2) - 1;
  506. *screen++ = show? 251 : ' '; // Checkmark char or space
  507. // *screen = 0x48;
  508. // *screen = (*oscreen & 0xf0) | 8;
  509. oscreen += 2;
  510. if (show && hilight)
  511. {
  512. for (w++;w--;screen += 2,oscreen += 2)
  513. *screen = (*oscreen & 0xf0) | 0x0f;
  514. }
  515. }
  516. ///////////////////////////////////////////////////////////////////////////
  517. //
  518. // USL_ShowMem() - Right justifies a longword in one of the memory fields on
  519. // the text screen
  520. //
  521. ///////////////////////////////////////////////////////////////////////////
  522. static void
  523. USL_ShowMem(word x,word y,long mem)
  524. {
  525. char buf[16];
  526. word i;
  527. for (i = strlen(ltoa(mem,buf,10));i < 5;i++)
  528. USL_ScreenDraw(x++,y," ",0xff);
  529. USL_ScreenDraw(x,y,buf,0xff);
  530. }
  531. ///////////////////////////////////////////////////////////////////////////
  532. //
  533. // US_UpdateTextScreen() - Called after the ID libraries are started up.
  534. // Displays what hardware is present.
  535. //
  536. ///////////////////////////////////////////////////////////////////////////
  537. void
  538. US_UpdateTextScreen(void)
  539. {
  540. boolean b;
  541. longword totalmem;
  542. // Show video card info
  543. b = (grmode == CGAGR);
  544. USL_Show(21,7,4,(videocard >= CGAcard) && (videocard <= VGAcard),b);
  545. b = (grmode == EGAGR);
  546. USL_Show(21,8,4,(videocard >= EGAcard) && (videocard <= VGAcard),b);
  547. b = (grmode == VGAGR);
  548. USL_Show(21,9,4,videocard == VGAcard,b);
  549. if (compatability)
  550. USL_ScreenDraw(5,10,"SVGA Compatibility Mode Enabled.",0x4f);
  551. // Show input device info
  552. USL_Show(60,7,8,true,true);
  553. USL_Show(60,8,11,JoysPresent[0],true);
  554. USL_Show(60,9,11,JoysPresent[1],true);
  555. USL_Show(60,10,5,MousePresent,true);
  556. // Show sound hardware info
  557. USL_Show(21,14,11,true,SoundMode == sdm_PC);
  558. b = (SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib);
  559. USL_Show(21,15,14,AdLibPresent,b);
  560. if (b && AdLibPresent) // Hack because of two lines
  561. {
  562. byte far *screen,far *oscreen;
  563. word x,y,w;
  564. x = 21;
  565. y = 16;
  566. w = 14;
  567. screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2) - 1);
  568. oscreen = (&introscn + 7) + (x * 2) + (y * 80 * 2) - 1;
  569. oscreen += 2;
  570. for (w++;w--;screen += 2,oscreen += 2)
  571. *screen = (*oscreen & 0xf0) | 0x0f;
  572. }
  573. // Show memory available/used
  574. USL_ShowMem(63,15,mminfo.mainmem / 1024);
  575. USL_Show(53,15,23,true,true);
  576. USL_ShowMem(63,16,mminfo.EMSmem / 1024);
  577. USL_Show(53,16,23,mminfo.EMSmem? true : false,true);
  578. USL_ShowMem(63,17,mminfo.XMSmem / 1024);
  579. USL_Show(53,17,23,mminfo.XMSmem? true : false,true);
  580. totalmem = mminfo.mainmem + mminfo.EMSmem + mminfo.XMSmem;
  581. USL_ShowMem(63,18,totalmem / 1024);
  582. USL_Show(53,18,23,true,true); // DEBUG
  583. USL_ScreenDraw(52,18," ",0xff);
  584. // Change Initializing... to Loading...
  585. USL_ScreenDraw(27,22," Loading... ",0x9c);
  586. }
  587. ///////////////////////////////////////////////////////////////////////////
  588. //
  589. // US_FinishTextScreen() - After the main program has finished its initial
  590. // loading, this routine waits for a keypress and then clears the screen
  591. //
  592. ///////////////////////////////////////////////////////////////////////////
  593. void
  594. US_FinishTextScreen(void)
  595. {
  596. static byte colors[] = {4,6,13,15,15,15,15,15,15};
  597. boolean up;
  598. int i,c;
  599. // Change Loading... to Press a Key
  600. if (!(tedlevel || NoWait))
  601. {
  602. IN_ClearKeysDown();
  603. for (i = 0,up = true;!IN_UserInput(4,true);)
  604. {
  605. c = colors[i];
  606. if (up)
  607. {
  608. if (++i == 9)
  609. i = 8,up = false;
  610. }
  611. else
  612. {
  613. if (--i < 0)
  614. i = 1,up = true;
  615. }
  616. USL_ScreenDraw(29,22," Ready - Press a Key ",0x00 + c);
  617. }
  618. }
  619. else
  620. USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
  621. IN_ClearKeysDown();
  622. USL_ClearTextScreen();
  623. }
  624. #endif
  625. // Window/Printing routines
  626. ///////////////////////////////////////////////////////////////////////////
  627. //
  628. // US_SetPrintRoutines() - Sets the routines used to measure and print
  629. // from within the User Mgr. Primarily provided to allow switching
  630. // between masked and non-masked fonts
  631. //
  632. ///////////////////////////////////////////////////////////////////////////
  633. void
  634. US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))
  635. {
  636. USL_MeasureString = measure;
  637. USL_DrawString = print;
  638. }
  639. ///////////////////////////////////////////////////////////////////////////
  640. //
  641. // US_Print() - Prints a string in the current window. Newlines are
  642. // supported.
  643. //
  644. ///////////////////////////////////////////////////////////////////////////
  645. void
  646. US_Print(char *s)
  647. {
  648. char c,*se;
  649. word w,h;
  650. while (*s)
  651. {
  652. se = s;
  653. while ((c = *se) && (c != '\n'))
  654. se++;
  655. *se = '\0';
  656. USL_MeasureString(s,&w,&h);
  657. px = PrintX;
  658. py = PrintY;
  659. USL_DrawString(s);
  660. s = se;
  661. if (c)
  662. {
  663. *se = c;
  664. s++;
  665. PrintX = WindowX;
  666. PrintY += h;
  667. }
  668. else
  669. PrintX += w;
  670. }
  671. }
  672. // MDM - (GAMERS EDGE) begin
  673. ///////////////////////////////////////////////////////////////////////////
  674. //
  675. // US_Printxy()
  676. //
  677. void US_Printxy(word x, word y, char *text)
  678. {
  679. word orgx, orgy;
  680. orgx = PrintX;
  681. orgy = PrintY;
  682. // PrintX = WindowX+x;
  683. // PrintY = WindowY+y;
  684. PrintX = x;
  685. PrintY = y;
  686. US_Print(text);
  687. PrintX = orgx;
  688. PrintY = orgy;
  689. }
  690. // MDM - (GAMERS EDGE) end
  691. ///////////////////////////////////////////////////////////////////////////
  692. //
  693. // US_PrintUnsigned() - Prints an unsigned long
  694. //
  695. ///////////////////////////////////////////////////////////////////////////
  696. void
  697. US_PrintUnsigned(longword n)
  698. {
  699. char buffer[32];
  700. US_Print(ultoa(n,buffer,10));
  701. }
  702. ///////////////////////////////////////////////////////////////////////////
  703. //
  704. // US_PrintSigned() - Prints a signed long
  705. //
  706. ///////////////////////////////////////////////////////////////////////////
  707. void
  708. US_PrintSigned(long n)
  709. {
  710. char buffer[32];
  711. US_Print(ltoa(n,buffer,10));
  712. }
  713. ///////////////////////////////////////////////////////////////////////////
  714. //
  715. // USL_PrintInCenter() - Prints a string in the center of the given rect
  716. //
  717. ///////////////////////////////////////////////////////////////////////////
  718. void
  719. USL_PrintInCenter(char *s,Rect r)
  720. {
  721. word w,h,
  722. rw,rh;
  723. USL_MeasureString(s,&w,&h);
  724. rw = r.lr.x - r.ul.x;
  725. rh = r.lr.y - r.ul.y;
  726. px = r.ul.x + ((rw - w) / 2);
  727. py = r.ul.y + ((rh - h) / 2);
  728. USL_DrawString(s);
  729. }
  730. ///////////////////////////////////////////////////////////////////////////
  731. //
  732. // US_PrintCentered() - Prints a string centered in the current window.
  733. //
  734. ///////////////////////////////////////////////////////////////////////////
  735. void
  736. US_PrintCentered(char *s)
  737. {
  738. Rect r;
  739. r.ul.x = WindowX;
  740. r.ul.y = WindowY;
  741. r.lr.x = r.ul.x + WindowW;
  742. r.lr.y = r.ul.y + WindowH;
  743. USL_PrintInCenter(s,r);
  744. }
  745. ///////////////////////////////////////////////////////////////////////////
  746. //
  747. // US_CPrintLine() - Prints a string centered on the current line and
  748. // advances to the next line. Newlines are not supported.
  749. //
  750. ///////////////////////////////////////////////////////////////////////////
  751. void
  752. US_CPrintLine(char *s)
  753. {
  754. word w,h;
  755. USL_MeasureString(s,&w,&h);
  756. if (w > WindowW)
  757. Quit("US_CPrintLine() - String exceeds width");
  758. px = WindowX + ((WindowW - w) / 2);
  759. py = PrintY;
  760. USL_DrawString(s);
  761. PrintY += h;
  762. }
  763. ///////////////////////////////////////////////////////////////////////////
  764. //
  765. // US_CPrint() - Prints a string in the current window. Newlines are
  766. // supported.
  767. //
  768. ///////////////////////////////////////////////////////////////////////////
  769. void
  770. US_CPrint(char *s)
  771. {
  772. char c,*se;
  773. while (*s)
  774. {
  775. se = s;
  776. while ((c = *se) && (c != '\n'))
  777. se++;
  778. *se = '\0';
  779. US_CPrintLine(s);
  780. s = se;
  781. if (c)
  782. {
  783. *se = c;
  784. s++;
  785. }
  786. }
  787. }
  788. ///////////////////////////////////////////////////////////////////////////
  789. //
  790. // US_ClearWindow() - Clears the current window to white and homes the
  791. // cursor
  792. //
  793. ///////////////////////////////////////////////////////////////////////////
  794. void
  795. US_ClearWindow(void)
  796. {
  797. VWB_Bar(WindowX,WindowY,WindowW,WindowH,LT_GREY);
  798. PrintX = WindowX;
  799. PrintY = WindowY;
  800. }
  801. ///////////////////////////////////////////////////////////////////////////
  802. //
  803. // US_DrawWindow() - Draws a frame and sets the current window parms
  804. //
  805. ///////////////////////////////////////////////////////////////////////////
  806. void
  807. US_DrawWindow(word x,word y,word w,word h)
  808. {
  809. word i,
  810. sx,sy,sw,sh;
  811. WindowX = x * 8;
  812. WindowY = y * 8;
  813. WindowW = w * 8;
  814. WindowH = h * 8;
  815. PrintX = WindowX;
  816. PrintY = WindowY;
  817. sx = (x - 1) * 8;
  818. sy = (y - 1) * 8;
  819. sw = (w + 1) * 8;
  820. sh = (h + 1) * 8;
  821. US_ClearWindow();
  822. VWB_DrawTile8M(sx,sy,0),VWB_DrawTile8M(sx,sy + sh,6);
  823. for (i = sx + 8;i <= sx + sw - 8;i += 8)
  824. VWB_DrawTile8M(i,sy,1),VWB_DrawTile8M(i,sy + sh,7);
  825. VWB_DrawTile8M(i,sy,2),VWB_DrawTile8M(i,sy + sh,8);
  826. for (i = sy + 8;i <= sy + sh - 8;i += 8)
  827. VWB_DrawTile8M(sx,i,3),VWB_DrawTile8M(sx + sw,i,5);
  828. }
  829. ///////////////////////////////////////////////////////////////////////////
  830. //
  831. // US_CenterWindow() - Generates a window of a given width & height in the
  832. // middle of the screen
  833. //
  834. ///////////////////////////////////////////////////////////////////////////
  835. void
  836. US_CenterWindow(word w,word h)
  837. {
  838. US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
  839. }
  840. ///////////////////////////////////////////////////////////////////////////
  841. //
  842. // US_CenterSaveWindow() - Generates a window of a given width & height in
  843. // the middle of the screen, saving the background
  844. //
  845. ///////////////////////////////////////////////////////////////////////////
  846. void
  847. US_CenterSaveWindow(word w,word h,memptr *save)
  848. {
  849. word x,y,
  850. screen;
  851. x = ((MaxX / 8) - w) / 2;
  852. y = ((MaxY / 8) - h) / 2;
  853. MM_GetPtr(save,(w * h) * CHARWIDTH);
  854. screen = bufferofs + panadjust + ylookup[y] + (x * CHARWIDTH);
  855. VW_ScreenToMem(screen,*save,w * CHARWIDTH,h);
  856. US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
  857. }
  858. ///////////////////////////////////////////////////////////////////////////
  859. //
  860. // US_RestoreSaveWindow() - Restores the background of the size of the
  861. // current window from the memory specified by save
  862. //
  863. ///////////////////////////////////////////////////////////////////////////
  864. void
  865. US_RestoreSaveWindow(memptr *save)
  866. {
  867. word screen;
  868. screen = bufferofs + panadjust + ylookup[WindowY] + (WindowX * CHARWIDTH);
  869. VW_MemToScreen(*save,screen,WindowW * CHARWIDTH,WindowH);
  870. MM_FreePtr(save);
  871. }
  872. ///////////////////////////////////////////////////////////////////////////
  873. //
  874. // US_SaveWindow() - Saves the current window parms into a record for
  875. // later restoration
  876. //
  877. ///////////////////////////////////////////////////////////////////////////
  878. void
  879. US_SaveWindow(WindowRec *win)
  880. {
  881. win->x = WindowX;
  882. win->y = WindowY;
  883. win->w = WindowW;
  884. win->h = WindowH;
  885. win->px = PrintX;
  886. win->py = PrintY;
  887. }
  888. ///////////////////////////////////////////////////////////////////////////
  889. //
  890. // US_RestoreWindow() - Sets the current window parms to those held in the
  891. // record
  892. //
  893. ///////////////////////////////////////////////////////////////////////////
  894. void
  895. US_RestoreWindow(WindowRec *win)
  896. {
  897. WindowX = win->x;
  898. WindowY = win->y;
  899. WindowW = win->w;
  900. WindowH = win->h;
  901. PrintX = win->px;
  902. PrintY = win->py;
  903. }
  904. // Cursor routines
  905. #if 0
  906. ///////////////////////////////////////////////////////////////////////////
  907. //
  908. // US_StartCursor() - Sets up the cursor for User Mgr use
  909. //
  910. ///////////////////////////////////////////////////////////////////////////
  911. void
  912. US_StartCursor(void)
  913. {
  914. CursorInfo info;
  915. VW_SetCursor(CURSORARROWSPR);
  916. CursorX = MaxX / 2;
  917. CursorY = MaxY / 2;
  918. VW_MoveCursor(CursorX,CursorY);
  919. VW_ShowCursor();
  920. IN_ReadCursor(&info); // Dispose of any accumulated movement
  921. }
  922. ///////////////////////////////////////////////////////////////////////////
  923. //
  924. // US_ShutCursor() - Cleans up after US_StartCursor()
  925. //
  926. ///////////////////////////////////////////////////////////////////////////
  927. void
  928. US_ShutCursor(void)
  929. {
  930. VW_HideCursor();
  931. }
  932. ///////////////////////////////////////////////////////////////////////////
  933. //
  934. // US_UpdateCursor() - Gets the new cursor position & button states from
  935. // the Input Mgr and tells the View Mgr where the cursor is
  936. //
  937. ///////////////////////////////////////////////////////////////////////////
  938. boolean
  939. US_UpdateCursor(void)
  940. {
  941. CursorInfo info;
  942. IN_ReadCursor(&info);
  943. if (info.x || info.y || CursorBad)
  944. {
  945. CursorX += info.x;
  946. if (CursorX >= MaxX)
  947. CursorX = MaxX - 1;
  948. else if (CursorX < 0)
  949. CursorX = 0;
  950. CursorY += info.y;
  951. if (CursorY >= MaxY)
  952. CursorY = MaxY - 1;
  953. else if (CursorY < 0)
  954. CursorY = 0;
  955. VW_MoveCursor(CursorX,CursorY);
  956. CursorBad = false;
  957. }
  958. Button0 = info.button0;
  959. Button1 = info.button1;
  960. return(Button0 || Button1);
  961. }
  962. #endif
  963. // Input routines
  964. ///////////////////////////////////////////////////////////////////////////
  965. //
  966. // USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
  967. //
  968. ///////////////////////////////////////////////////////////////////////////
  969. static void
  970. USL_XORICursor(int x,int y,char *s,word cursor)
  971. {
  972. char buf[MaxString];
  973. word w,h;
  974. strcpy(buf,s);
  975. buf[cursor] = '\0';
  976. USL_MeasureString(buf,&w,&h);
  977. px = x + w - 1;
  978. py = y;
  979. USL_DrawString("\x80");
  980. }
  981. ///////////////////////////////////////////////////////////////////////////
  982. //
  983. // US_LineInput() - Gets a line of user input at (x,y), the string defaults
  984. // to whatever is pointed at by def. Input is restricted to maxchars
  985. // chars or maxwidth pixels wide. If the user hits escape (and escok is
  986. // true), nothing is copied into buf, and false is returned. If the
  987. // user hits return, the current string is copied into buf, and true is
  988. // returned
  989. //
  990. ///////////////////////////////////////////////////////////////////////////
  991. boolean
  992. US_LineInput(int x,int y,char *buf,char *def,boolean escok,
  993. int maxchars,int maxwidth)
  994. {
  995. boolean redraw,
  996. cursorvis,cursormoved,
  997. done,result;
  998. ScanCode sc;
  999. char c,
  1000. s[MaxString],olds[MaxString];
  1001. word i,
  1002. cursor,
  1003. w,h,
  1004. len;
  1005. longword lasttime;
  1006. VW_HideCursor();
  1007. if (def)
  1008. strcpy(s,def);
  1009. else
  1010. *s = '\0';
  1011. *olds = '\0';
  1012. cursor = strlen(s);
  1013. cursormoved = redraw = true;
  1014. cursorvis = done = false;
  1015. lasttime = TimeCount;
  1016. LastASCII = key_None;
  1017. LastScan = sc_None;
  1018. while (!done)
  1019. {
  1020. if (cursorvis)
  1021. USL_XORICursor(x,y,s,cursor);
  1022. asm pushf
  1023. asm cli
  1024. sc = LastScan;
  1025. LastScan = sc_None;
  1026. c = LastASCII;
  1027. LastASCII = key_None;
  1028. asm popf
  1029. switch (sc)
  1030. {
  1031. case sc_LeftArrow:
  1032. if (cursor)
  1033. cursor--;
  1034. c = key_None;
  1035. cursormoved = true;
  1036. break;
  1037. case sc_RightArrow:
  1038. if (s[cursor])
  1039. cursor++;
  1040. c = key_None;
  1041. cursormoved = true;
  1042. break;
  1043. case sc_Home:
  1044. cursor = 0;
  1045. c = key_None;
  1046. cursormoved = true;
  1047. break;
  1048. case sc_End:
  1049. cursor = strlen(s);
  1050. c = key_None;
  1051. cursormoved = true;
  1052. break;
  1053. case sc_Return:
  1054. strcpy(buf,s);
  1055. done = true;
  1056. result = true;
  1057. c = key_None;
  1058. break;
  1059. case sc_Escape:
  1060. if (escok)
  1061. {
  1062. done = true;
  1063. result = false;
  1064. }
  1065. c = key_None;
  1066. break;
  1067. case sc_BackSpace:
  1068. if (cursor)
  1069. {
  1070. strcpy(s + cursor - 1,s + cursor);
  1071. cursor--;
  1072. redraw = true;
  1073. }
  1074. c = key_None;
  1075. cursormoved = true;
  1076. break;
  1077. case sc_Delete:
  1078. if (s[cursor])
  1079. {
  1080. strcpy(s + cursor,s + cursor + 1);
  1081. redraw = true;
  1082. }
  1083. c = key_None;
  1084. cursormoved = true;
  1085. break;
  1086. case 0x4c: // Keypad 5
  1087. case sc_UpArrow:
  1088. case sc_DownArrow:
  1089. case sc_PgUp:
  1090. case sc_PgDn:
  1091. case sc_Insert:
  1092. c = key_None;
  1093. break;
  1094. }
  1095. if (c)
  1096. {
  1097. len = strlen(s);
  1098. USL_MeasureString(s,&w,&h);
  1099. if
  1100. (
  1101. isprint(c)
  1102. && (len < MaxString - 1)
  1103. && ((!maxchars) || (len < maxchars))
  1104. && ((!maxwidth) || (w < maxwidth))
  1105. )
  1106. {
  1107. for (i = len + 1;i > cursor;i--)
  1108. s[i] = s[i - 1];
  1109. s[cursor++] = c;
  1110. redraw = true;
  1111. }
  1112. }
  1113. if (redraw)
  1114. {
  1115. px = x;
  1116. py = y;
  1117. USL_DrawString(olds);
  1118. strcpy(olds,s);
  1119. px = x;
  1120. py = y;
  1121. USL_DrawString(s);
  1122. redraw = false;
  1123. }
  1124. if (cursormoved)
  1125. {
  1126. cursorvis = false;
  1127. lasttime = TimeCount - TickBase;
  1128. cursormoved = false;
  1129. }
  1130. if (TimeCount - lasttime > TickBase / 2)
  1131. {
  1132. lasttime = TimeCount;
  1133. cursorvis ^= true;
  1134. }
  1135. if (cursorvis)
  1136. USL_XORICursor(x,y,s,cursor);
  1137. VW_UpdateScreen();
  1138. }
  1139. if (cursorvis)
  1140. USL_XORICursor(x,y,s,cursor);
  1141. if (!result)
  1142. {
  1143. px = x;
  1144. py = y;
  1145. USL_DrawString(olds);
  1146. }
  1147. VW_ShowCursor();
  1148. VW_UpdateScreen();
  1149. IN_ClearKeysDown();
  1150. return(result);
  1151. }