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