1 /* Reconstructed Commander Keen 4-6 Source Code
\r
2 * Copyright (C) 2021 K1n9_Duk3
\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
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
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
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
25 // ID_US_1.c - User Manager - General routines
\r
27 // By Jason Blochowiak
\r
28 // Hacked up for Catacomb 3D
\r
32 // This module handles dealing with user input & feedback
\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
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
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
51 #include "ID_HEADS.H"
\r
59 extern boolean showscorebox;
\r
61 extern boolean jerk;
\r
62 extern boolean oldshooting;
\r
63 extern ScanCode firescan;
\r
73 word WindowX,WindowY,WindowW,WindowH;
\r
75 // Internal variables
\r
76 #define ConfigVersion 4
\r
78 static char *ParmStrings[] = {"TEDLEVEL","NOWAIT"},
\r
79 *ParmStrings2[] = {"COMP","NOCOMP"};
\r
80 static boolean US_Started;
\r
82 boolean Button0,Button1,
\r
84 int CursorX,CursorY;
\r
86 void (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
\r
87 (*USL_DrawString)(char far *) = VWB_DrawPropString;
\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
95 {"Sir Lancelot",500,3},
\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
112 {"Id Software - '91",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
123 // Internal routines
\r
127 ///////////////////////////////////////////////////////////////////////////
\r
129 // USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
\r
132 ///////////////////////////////////////////////////////////////////////////
\r
136 USL_HardError(word errval,int ax,int bp,int si)
\r
141 extern void ShutdownId(void);
\r
143 static char buf[32];
\r
144 static WindowRec wr;
\r
152 s = "Device Error";
\r
155 if ((di & 0x00ff) == 0)
\r
156 s = "Drive ~ is Write Protected";
\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
166 c = peekb(0x40,0x49); // Get the current screen mode
\r
167 if ((c < 4) || (c == 7))
\r
170 // DEBUG - handle screen cleanup
\r
172 US_SaveWindow(&wr);
\r
173 US_CenterWindow(30,3);
\r
175 US_CPrint("(R)etry or (A)bort?");
\r
177 IN_ClearKeysDown();
\r
179 asm sti // Let the keyboard interrupts come through
\r
183 switch (IN_WaitForASCII())
\r
196 US_RestoreWindow(&wr);
\r
205 fprintf(stderr,"Terminal Error: %s\n",s);
\r
207 fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
\r
217 ///////////////////////////////////////////////////////////////////////////
\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
222 ///////////////////////////////////////////////////////////////////////////
\r
224 USL_GiveSaveName(word game)
\r
226 static char name[] = "SAVEGAMx."EXTENSION;
\r
228 name[7] = '0' + game;
\r
232 ///////////////////////////////////////////////////////////////////////////
\r
234 // US_SetLoadSaveHooks() - Sets the routines that the User Mgr calls after
\r
235 // reading or writing the save game headers
\r
237 ///////////////////////////////////////////////////////////////////////////
\r
239 US_SetLoadSaveHooks(boolean (*load)(int),boolean (*save)(int),void (*reset)(void))
\r
241 USL_LoadGame = load;
\r
242 USL_SaveGame = save;
\r
243 USL_ResetGame = reset;
\r
246 ///////////////////////////////////////////////////////////////////////////
\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
252 ///////////////////////////////////////////////////////////////////////////
\r
254 USL_ReadConfig(void)
\r
256 boolean gotit, hadAdLib;
\r
257 char sig[sizeof(EXTENSION)];
\r
264 if ((file = open("CONFIG."EXTENSION,O_BINARY | O_RDONLY)) != -1)
\r
266 read(file,sig,sizeof(EXTENSION));
\r
267 read(file,&version,sizeof(version));
\r
268 if (strcmp(sig,EXTENSION) || (version != ConfigVersion))
\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
284 read(file,&oldshooting,sizeof(oldshooting));
\r
285 read(file,&firescan,sizeof(firescan));
\r
287 read(file,&GravisGamepad,sizeof(GravisGamepad));
\r
288 read(file,&GravisMap,sizeof(GravisMap));
\r
291 HighScoresDirty = false;
\r
299 ctl = ctrl_Keyboard;
\r
300 showscorebox = true;
\r
302 oldshooting = false;
\r
306 HighScoresDirty = true;
\r
309 SD_Default(gotit? (hadAdLib==AdLibPresent) : false, sd,sm);
\r
310 IN_Default(gotit,ctl);
\r
313 ///////////////////////////////////////////////////////////////////////////
\r
315 // USL_WriteConfig() - Writes out the current configuration, including the
\r
318 ///////////////////////////////////////////////////////////////////////////
\r
320 USL_WriteConfig(void)
\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
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
338 (Controls[0] == ctrl_Joystick1)
\r
339 || (Controls[0] == ctrl_Joystick2)
\r
341 Controls[0] = ctrl_Keyboard;
\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
351 write(file,&oldshooting,sizeof(oldshooting));
\r
352 write(file,&firescan,sizeof(firescan));
\r
354 write(file,&GravisGamepad,sizeof(GravisGamepad));
\r
355 write(file,&GravisMap,sizeof(GravisMap));
\r
360 ///////////////////////////////////////////////////////////////////////////
\r
362 // USL_CheckSavedGames() - Checks to see which saved games are present
\r
365 ///////////////////////////////////////////////////////////////////////////
\r
371 USL_CheckSavedGames(void)
\r
384 for (i = 0,game = Games;i < MaxSaveGames;i++,game++)
\r
386 filename = USL_GiveSaveName(i);
\r
388 if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)
\r
392 (read(file,game,sizeof(*game)) == sizeof(*game))
\r
393 && (!strcmp(game->signature,EXTENSION))
\r
394 && (game->oldtest == &PrintX)
\r
402 game->present = true;
\r
405 strcpy(game->signature,EXTENSION);
\r
406 game->present = false;
\r
407 strcpy(game->name,"Empty");
\r
412 ///////////////////////////////////////////////////////////////////////////
\r
414 // US_Startup() - Starts the User Mgr
\r
416 ///////////////////////////////////////////////////////////////////////////
\r
425 harderr(USL_HardError); // Install the fatal error handler
\r
427 US_InitRndT(true); // Initialize the random number generator
\r
429 USL_ReadConfig(); // Read config file
\r
431 for (i = 1;i < _argc;i++)
\r
433 switch (US_CheckParm(_argv[i],ParmStrings2))
\r
436 if (grmode == EGAGR)
\r
437 compatability = true;
\r
440 compatability = false;
\r
448 ///////////////////////////////////////////////////////////////////////////
\r
450 // US_Setup() - Does the disk access part of the User Mgr's startup
\r
452 ///////////////////////////////////////////////////////////////////////////
\r
460 USL_CheckSavedGames(); // Check which saved games are present
\r
463 ///////////////////////////////////////////////////////////////////////////
\r
465 // US_Shutdown() - Shuts down the User Mgr
\r
467 ///////////////////////////////////////////////////////////////////////////
\r
477 US_Started = false;
\r
480 ///////////////////////////////////////////////////////////////////////////
\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
486 ///////////////////////////////////////////////////////////////////////////
\r
488 US_CheckParm(char *parm,char **strings)
\r
494 while (!isalpha(*parm)) // Skip non-alphas
\r
497 for (i = 0;*strings && **strings;i++)
\r
499 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
\r
515 ///////////////////////////////////////////////////////////////////////////
\r
517 // US_ParmPresent() - checks if a given string was passed as a command
\r
518 // line parameter at startup
\r
520 ///////////////////////////////////////////////////////////////////////////
\r
522 US_ParmPresent(char *arg)
\r
530 for (i=1; i<_argc; i++)
\r
532 if (US_CheckParm(_argv[i], strings) != -1)
\r
538 ///////////////////////////////////////////////////////////////////////////
\r
540 // USL_ScreenDraw() - Draws a chunk of the text screen (called only by
\r
541 // US_TextScreen())
\r
543 ///////////////////////////////////////////////////////////////////////////
\r
545 USL_ScreenDraw(word x,word y,char *s,byte attr)
\r
547 byte far *screen,far *oscreen;
\r
549 screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2));
\r
550 oscreen = (&introscn + 7) + ((x - 1) * 2) + (y * 80 * 2) + 1;
\r
556 *screen++ = (attr & 0x8f) | (*oscreen & 0x70);
\r
564 ///////////////////////////////////////////////////////////////////////////
\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
569 ///////////////////////////////////////////////////////////////////////////
\r
571 USL_ClearTextScreen(void)
\r
573 // Set to 80x25 color text mode
\r
576 geninterrupt(0x10);
\r
578 // Use BIOS to move the cursor to the bottom of the screen
\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
584 geninterrupt(0x10);
\r
587 ///////////////////////////////////////////////////////////////////////////
\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
593 ///////////////////////////////////////////////////////////////////////////
\r
595 US_TextScreen(void)
\r
599 USL_ClearTextScreen();
\r
601 _fmemcpy(MK_FP(0xb800,0),7 + &introscn,80 * 25 * 2);
\r
603 // Check for TED launching here
\r
604 for (i = 1;i < _argc;i++)
\r
606 n = US_CheckParm(_argv[i],ParmStrings);
\r
609 tedlevelnum = atoi(_argv[i + 1]);
\r
610 if (tedlevelnum >= 0)
\r
626 ///////////////////////////////////////////////////////////////////////////
\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
631 ///////////////////////////////////////////////////////////////////////////
\r
633 USL_Show(word x,word y,word w,boolean show,boolean hilight)
\r
635 byte far *screen,far *oscreen;
\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
641 // *screen = (*oscreen & 0xf0) | 8;
\r
643 if (show && hilight)
\r
645 for (w++;w--;screen += 2,oscreen += 2)
\r
646 *screen = (*oscreen & 0xf0) | 0x0f;
\r
650 ///////////////////////////////////////////////////////////////////////////
\r
652 // USL_ShowMem() - Right justifies a longword in one of the memory fields on
\r
655 ///////////////////////////////////////////////////////////////////////////
\r
657 USL_ShowMem(word x,word y,long mem)
\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
667 ///////////////////////////////////////////////////////////////////////////
\r
669 // US_UpdateTextScreen() - Called after the ID libraries are started up.
\r
670 // Displays what hardware is present.
\r
672 ///////////////////////////////////////////////////////////////////////////
\r
674 US_UpdateTextScreen(void)
\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
688 USL_ScreenDraw(5,10,"SVGA Compatibility Mode Enabled.",0x4f);
\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
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
703 byte far *screen,far *oscreen;
\r
709 screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2) - 1);
\r
710 oscreen = (&introscn + 7) + (x * 2) + (y * 80 * 2) - 1;
\r
712 for (w++;w--;screen += 2,oscreen += 2)
\r
713 *screen = (*oscreen & 0xf0) | 0x0f;
\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
728 // Change Initializing... to Loading...
\r
729 USL_ScreenDraw(27,22," Loading... ",0x9c);
\r
732 ///////////////////////////////////////////////////////////////////////////
\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
737 ///////////////////////////////////////////////////////////////////////////
\r
739 US_FinishTextScreen(void)
\r
741 static byte colors[] = {4,6,13,15,15,15,15,15,15};
\r
745 // Change Loading... to Press a Key
\r
747 if (!(tedlevel || NoWait))
\r
749 IN_ClearKeysDown();
\r
750 for (i = 0,up = true;!IN_UserInput(4,true);)
\r
764 USL_ScreenDraw(29,22," Ready - Press a Key ",0x00 + c);
\r
768 USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
\r
770 IN_ClearKeysDown();
\r
772 USL_ClearTextScreen();
\r
775 // Window/Printing routines
\r
777 ///////////////////////////////////////////////////////////////////////////
\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
783 ///////////////////////////////////////////////////////////////////////////
\r
785 US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))
\r
787 USL_MeasureString = measure;
\r
788 USL_DrawString = print;
\r
791 ///////////////////////////////////////////////////////////////////////////
\r
793 // US_Print() - Prints a string in the current window. Newlines are
\r
796 ///////////////////////////////////////////////////////////////////////////
\r
806 while ((c = *se) && (c != '\n'))
\r
810 USL_MeasureString(s,&w,&h);
\r
829 ///////////////////////////////////////////////////////////////////////////
\r
831 // US_PrintUnsigned() - Prints an unsigned long
\r
833 ///////////////////////////////////////////////////////////////////////////
\r
835 US_PrintUnsigned(longword n)
\r
839 US_Print(ultoa(n,buffer,10));
\r
842 ///////////////////////////////////////////////////////////////////////////
\r
844 // US_PrintSigned() - Prints a signed long
\r
846 ///////////////////////////////////////////////////////////////////////////
\r
848 US_PrintSigned(long n)
\r
852 US_Print(ltoa(n,buffer,10));
\r
855 ///////////////////////////////////////////////////////////////////////////
\r
857 // USL_PrintInCenter() - Prints a string in the center of the given rect
\r
859 ///////////////////////////////////////////////////////////////////////////
\r
861 USL_PrintInCenter(char *s,Rect r)
\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
870 px = r.ul.x + ((rw - w) / 2);
\r
871 py = r.ul.y + ((rh - h) / 2);
\r
875 ///////////////////////////////////////////////////////////////////////////
\r
877 // US_PrintCentered() - Prints a string centered in the current window.
\r
879 ///////////////////////////////////////////////////////////////////////////
\r
881 US_PrintCentered(char *s)
\r
887 r.lr.x = r.ul.x + WindowW;
\r
888 r.lr.y = r.ul.y + WindowH;
\r
890 USL_PrintInCenter(s,r);
\r
893 ///////////////////////////////////////////////////////////////////////////
\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
898 ///////////////////////////////////////////////////////////////////////////
\r
900 US_CPrintLine(char *s)
\r
904 USL_MeasureString(s,&w,&h);
\r
907 Quit("US_CPrintLine() - String exceeds width");
\r
908 px = WindowX + ((WindowW - w) / 2);
\r
914 ///////////////////////////////////////////////////////////////////////////
\r
916 // US_CPrint() - Prints a string in the current window. Newlines are
\r
919 ///////////////////////////////////////////////////////////////////////////
\r
928 while ((c = *se) && (c != '\n'))
\r
943 ///////////////////////////////////////////////////////////////////////////
\r
945 // US_ClearWindow() - Clears the current window to white and homes the
\r
948 ///////////////////////////////////////////////////////////////////////////
\r
950 US_ClearWindow(void)
\r
952 VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
\r
957 ///////////////////////////////////////////////////////////////////////////
\r
959 // US_DrawWindow() - Draws a frame and sets the current window parms
\r
961 ///////////////////////////////////////////////////////////////////////////
\r
963 US_DrawWindow(word x,word y,word w,word h)
\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
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
992 ///////////////////////////////////////////////////////////////////////////
\r
994 // US_CenterWindow() - Generates a window of a given width & height in the
\r
995 // middle of the screen
\r
997 ///////////////////////////////////////////////////////////////////////////
\r
999 US_CenterWindow(word w,word h)
\r
1001 US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
\r
1004 ///////////////////////////////////////////////////////////////////////////
\r
1006 // US_CenterSaveWindow() - Generates a window of a given width & height in
\r
1007 // the middle of the screen, saving the background
\r
1009 ///////////////////////////////////////////////////////////////////////////
\r
1011 US_CenterSaveWindow(word w,word h,memptr *save)
\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
1024 ///////////////////////////////////////////////////////////////////////////
\r
1026 // US_RestoreSaveWindow() - Restores the background of the size of the
\r
1027 // current window from the memory specified by save
\r
1029 ///////////////////////////////////////////////////////////////////////////
\r
1031 US_RestoreSaveWindow(memptr *save)
\r
1035 screen = bufferofs + panadjust + ylookup[WindowY] + (WindowX * CHARWIDTH);
\r
1036 VW_MemToScreen(*save,screen,WindowW * CHARWIDTH,WindowH);
\r
1040 ///////////////////////////////////////////////////////////////////////////
\r
1042 // US_SaveWindow() - Saves the current window parms into a record for
\r
1043 // later restoration
\r
1045 ///////////////////////////////////////////////////////////////////////////
\r
1047 US_SaveWindow(WindowRec *win)
\r
1058 ///////////////////////////////////////////////////////////////////////////
\r
1060 // US_RestoreWindow() - Sets the current window parms to those held in the
\r
1063 ///////////////////////////////////////////////////////////////////////////
\r
1065 US_RestoreWindow(WindowRec *win)
\r
1076 // Cursor routines
\r
1079 ///////////////////////////////////////////////////////////////////////////
\r
1081 // US_StartCursor() - Sets up the cursor for User Mgr use
\r
1083 ///////////////////////////////////////////////////////////////////////////
\r
1085 US_StartCursor(void)
\r
1089 VW_SetCursor(CURSORARROWSPR);
\r
1090 CursorX = MaxX / 2;
\r
1091 CursorY = MaxY / 2;
\r
1092 VW_MoveCursor(CursorX,CursorY);
\r
1095 IN_ReadCursor(&info); // Dispose of any accumulated movement
\r
1098 ///////////////////////////////////////////////////////////////////////////
\r
1100 // US_ShutCursor() - Cleans up after US_StartCursor()
\r
1102 ///////////////////////////////////////////////////////////////////////////
\r
1104 US_ShutCursor(void)
\r
1109 ///////////////////////////////////////////////////////////////////////////
\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
1114 ///////////////////////////////////////////////////////////////////////////
\r
1116 US_UpdateCursor(void)
\r
1120 IN_ReadCursor(&info);
\r
1121 if (info.x || info.y || CursorBad)
\r
1123 CursorX += info.x;
\r
1124 if (CursorX >= MaxX)
\r
1125 CursorX = MaxX - 1;
\r
1126 else if (CursorX < 0)
\r
1129 CursorY += info.y;
\r
1130 if (CursorY >= MaxY)
\r
1131 CursorY = MaxY - 1;
\r
1132 else if (CursorY < 0)
\r
1135 VW_MoveCursor(CursorX,CursorY);
\r
1136 CursorBad = false;
\r
1138 Button0 = info.button0;
\r
1139 Button1 = info.button1;
\r
1140 return(Button0 || Button1);
\r
1146 ///////////////////////////////////////////////////////////////////////////
\r
1148 // USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
\r
1150 ///////////////////////////////////////////////////////////////////////////
\r
1152 USL_XORICursor(int x,int y,char *s,word cursor)
\r
1154 char buf[MaxString];
\r
1158 buf[cursor] = '\0';
\r
1159 USL_MeasureString(buf,&w,&h);
\r
1163 USL_DrawString("\x80");
\r
1166 ///////////////////////////////////////////////////////////////////////////
\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
1175 ///////////////////////////////////////////////////////////////////////////
\r
1177 US_LineInput(int x,int y,char *buf,char *def,boolean escok,
\r
1178 int maxchars,int maxwidth)
\r
1181 cursorvis,cursormoved,
\r
1185 s[MaxString],olds[MaxString];
\r
1190 longword lasttime;
\r
1199 cursor = strlen(s);
\r
1200 cursormoved = redraw = true;
\r
1202 cursorvis = done = false;
\r
1203 lasttime = TimeCount;
\r
1204 LastASCII = key_None;
\r
1205 LastScan = sc_None;
\r
1210 USL_XORICursor(x,y,s,cursor);
\r
1216 LastScan = sc_None;
\r
1218 LastASCII = key_None;
\r
1224 case sc_LeftArrow:
\r
1228 cursormoved = true;
\r
1230 case sc_RightArrow:
\r
1234 cursormoved = true;
\r
1239 cursormoved = true;
\r
1242 cursor = strlen(s);
\r
1244 cursormoved = true;
\r
1262 case sc_BackSpace:
\r
1265 strcpy(s + cursor - 1,s + cursor);
\r
1270 cursormoved = true;
\r
1275 strcpy(s + cursor,s + cursor + 1);
\r
1279 cursormoved = true;
\r
1282 case 0x4c: // Keypad 5
\r
1284 case sc_DownArrow:
\r
1295 USL_MeasureString(s,&w,&h);
\r
1300 && (len < MaxString - 1)
\r
1301 && ((!maxchars) || (len < maxchars))
\r
1302 && ((!maxwidth) || (w < maxwidth))
\r
1305 for (i = len + 1;i > cursor;i--)
\r
1316 USL_DrawString(olds);
\r
1321 USL_DrawString(s);
\r
1328 cursorvis = false;
\r
1329 lasttime = TimeCount - TickBase;
\r
1331 cursormoved = false;
\r
1333 if (TimeCount - lasttime > TickBase / 2)
\r
1335 lasttime = TimeCount;
\r
1337 cursorvis ^= true;
\r
1340 USL_XORICursor(x,y,s,cursor);
\r
1342 VW_UpdateScreen();
\r
1346 USL_XORICursor(x,y,s,cursor);
\r
1351 USL_DrawString(olds);
\r
1354 VW_UpdateScreen();
\r
1356 IN_ClearKeysDown();
\r