1 /* Catacomb Armageddon Source Code
\r
2 * Copyright (C) 1993-2014 Flat Rock Software
\r
4 * This program is free software; you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation; either version 2 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License along
\r
15 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
21 // ID_US.c - User Manager
\r
23 // By Jason Blochowiak
\r
27 // This module handles dealing with user input & feedback
\r
29 // Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,
\r
30 // and Refresh Mgrs, Memory Mgr for background save/restore
\r
33 // ingame - Flag set by game indicating if a game is in progress
\r
34 // abortgame - Flag set if the current game should be aborted (if a load
\r
36 // loadedgame - Flag set if a game was loaded
\r
37 // abortprogram - Normally nil, this points to a terminal error message
\r
38 // if the program needs to abort
\r
39 // restartgame - Normally set to gd_Continue, this is set to one of the
\r
40 // difficulty levels if a new game should be started
\r
41 // PrintX, PrintY - Where the User Mgr will print (global coords)
\r
42 // WindowX,WindowY,WindowW,WindowH - The dimensions of the current
\r
46 // DEBUG - handle LPT3 for Sound Source
\r
48 #include "ID_HEADS.H"
\r
50 #define CTL_M_ADLIBUPPIC CTL_S_ADLIBUPPIC
\r
51 #define CTL_M_ADLIBDNPIC CTL_S_ADLIBDNPIC
\r
60 #define MaxHelpLines 500
\r
62 #define MaxHighName 57
\r
63 #define MaxScores 10
\r
66 char name[MaxHighName + 1];
\r
71 #define MaxGameName 32
\r
72 #define MaxSaveGames 7
\r
77 char name[MaxGameName + 1];
\r
80 // Hack import for TED launch support
\r
81 extern boolean tedlevel;
\r
82 extern word tedlevelnum;
\r
83 extern void TEDDeath(void);
\r
84 static char *ParmStrings[] = {"TEDLEVEL","NOWAIT",""};
\r
88 boolean ingame,abortgame,loadedgame;
\r
90 GameDiff restartgame = gd_Continue;
\r
92 word WindowX,WindowY,WindowW,WindowH;
\r
94 // Internal variables
\r
95 static boolean US_Started;
\r
96 static boolean GameIsDirty,
\r
102 static memptr LineOffsets;
\r
104 static boolean Button0,Button1,
\r
106 static int CursorX,CursorY;
\r
108 static void (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,
\r
109 (*USL_DrawString)(char far *) = VWB_DrawPropString;
\r
111 static boolean (*USL_SaveGame)(int),(*USL_LoadGame)(int);
\r
112 static void (*USL_ResetGame)(void);
\r
113 static SaveGame Games[MaxSaveGames];
\r
114 static HighScore Scores[MaxScores] =
\r
116 {"Sir Lancelot",500},
\r
128 // Internal routines
\r
132 ///////////////////////////////////////////////////////////////////////////
\r
134 // USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed
\r
137 ///////////////////////////////////////////////////////////////////////////
\r
141 USL_HardError(word errval,int ax,int bp,int si)
\r
146 extern void ShutdownId(void);
\r
148 static char buf[32];
\r
149 static WindowRec wr;
\r
150 static boolean oldleavedriveon;
\r
157 oldleavedriveon = LeaveDriveOn;
\r
158 LeaveDriveOn = false;
\r
161 s = "Device Error";
\r
164 if ((di & 0x00ff) == 0)
\r
165 s = "Drive ~ is Write Protected";
\r
167 s = "Error on Drive ~";
\r
168 for (t = buf;*s;s++,t++) // Can't use sprintf()
\r
169 if ((*t = *s) == '~')
\r
170 *t = (ax & 0x00ff) + 'A';
\r
175 c = peekb(0x40,0x49); // Get the current screen mode
\r
176 if ((c < 4) || (c == 7))
\r
179 // DEBUG - handle screen cleanup
\r
181 US_SaveWindow(&wr);
\r
182 US_CenterWindow(30,3);
\r
184 US_CPrint("(R)etry or (A)bort?");
\r
186 IN_ClearKeysDown();
\r
188 asm sti // Let the keyboard interrupts come through
\r
192 switch (IN_WaitForASCII())
\r
205 US_RestoreWindow(&wr);
\r
206 LeaveDriveOn = oldleavedriveon;
\r
215 fprintf(stderr,"Terminal Error: %s\n",s);
\r
217 fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");
\r
227 ///////////////////////////////////////////////////////////////////////////
\r
229 // USL_GiveSaveName() - Returns a pointer to a static buffer that contains
\r
230 // the filename to use for the specified save game
\r
232 ///////////////////////////////////////////////////////////////////////////
\r
234 USL_GiveSaveName(word game)
\r
236 static char filename[32];
\r
239 for (s = "SAVEGM",t = filename;*s;)
\r
242 for (s = "."EXTENSION;*s;)
\r
249 ///////////////////////////////////////////////////////////////////////////
\r
251 // US_SetLoadSaveHooks() - Sets the routines that the User Mgr calls after
\r
252 // reading or writing the save game headers
\r
254 ///////////////////////////////////////////////////////////////////////////
\r
256 US_SetLoadSaveHooks(boolean (*load)(int),boolean (*save)(int),void (*reset)(void))
\r
258 USL_LoadGame = load;
\r
259 USL_SaveGame = save;
\r
260 USL_ResetGame = reset;
\r
263 ///////////////////////////////////////////////////////////////////////////
\r
265 // USL_ReadConfig() - Reads the configuration file, if present, and sets
\r
266 // things up accordingly. If it's not present, uses defaults. This file
\r
267 // includes the high scores.
\r
269 ///////////////////////////////////////////////////////////////////////////
\r
271 USL_ReadConfig(void)
\r
279 if ((file = open("CONFIG."EXTENSION,O_BINARY | O_RDONLY)) != -1)
\r
281 read(file,Scores,sizeof(HighScore) * MaxScores);
\r
282 read(file,&sd,sizeof(sd));
\r
283 read(file,&sm,sizeof(sm));
\r
284 read(file,&ctl,sizeof(ctl));
\r
285 read(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));
\r
288 HighScoresDirty = false;
\r
295 ctl = ctrl_Keyboard;
\r
298 HighScoresDirty = true;
\r
301 SD_Default(gotit,sd,sm);
\r
302 IN_Default(gotit,ctl);
\r
305 ///////////////////////////////////////////////////////////////////////////
\r
307 // USL_WriteConfig() - Writes out the current configuration, including the
\r
310 ///////////////////////////////////////////////////////////////////////////
\r
312 USL_WriteConfig(void)
\r
316 file = open("CONFIG."EXTENSION,O_CREAT | O_BINARY | O_WRONLY,
\r
317 S_IREAD | S_IWRITE | S_IFREG);
\r
320 write(file,Scores,sizeof(HighScore) * MaxScores);
\r
321 write(file,&SoundMode,sizeof(SoundMode));
\r
322 write(file,&MusicMode,sizeof(MusicMode));
\r
323 write(file,&(Controls[0]),sizeof(Controls[0]));
\r
324 write(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));
\r
329 ///////////////////////////////////////////////////////////////////////////
\r
331 // USL_CheckSavedGames() - Checks to see which saved games are present
\r
334 ///////////////////////////////////////////////////////////////////////////
\r
336 USL_CheckSavedGames(void)
\r
347 for (i = 0,game = Games;i < MaxSaveGames;i++,game++)
\r
349 filename = USL_GiveSaveName(i);
\r
351 if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)
\r
355 (read(file,game,sizeof(*game)) == sizeof(*game))
\r
356 && (!strcmp(game->signature,EXTENSION))
\r
364 game->present = true;
\r
367 strcpy(game->signature,EXTENSION);
\r
368 game->present = false;
\r
369 strcpy(game->name,"Empty");
\r
374 ///////////////////////////////////////////////////////////////////////////
\r
376 // US_Startup() - Starts the User Mgr
\r
378 ///////////////////////////////////////////////////////////////////////////
\r
385 harderr(USL_HardError); // Install the fatal error handler
\r
387 US_InitRndT(true); // Initialize the random number generator
\r
389 USL_ReadConfig(); // Read config file
\r
394 ///////////////////////////////////////////////////////////////////////////
\r
396 // US_Setup() - Does the disk access part of the User Mgr's startup
\r
398 ///////////////////////////////////////////////////////////////////////////
\r
402 USL_CheckSavedGames(); // Check which saved games are present
\r
405 ///////////////////////////////////////////////////////////////////////////
\r
407 // US_Shutdown() - Shuts down the User Mgr
\r
409 ///////////////////////////////////////////////////////////////////////////
\r
419 US_Started = false;
\r
422 ///////////////////////////////////////////////////////////////////////////
\r
424 // US_CheckParm() - checks to see if a string matches one of a set of
\r
425 // strings. The check is case insensitive. The routine returns the
\r
426 // index of the string that matched, or -1 if no matches were found
\r
428 ///////////////////////////////////////////////////////////////////////////
\r
430 US_CheckParm(char *parm,char **strings)
\r
436 while (!isalpha(*parm)) // Skip non-alphas
\r
439 for (i = 0;*strings && **strings;i++)
\r
441 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)
\r
457 ///////////////////////////////////////////////////////////////////////////
\r
459 // USL_ScreenDraw() - Draws a chunk of the text screen (called only by
\r
460 // US_TextScreen())
\r
462 ///////////////////////////////////////////////////////////////////////////
\r
464 USL_ScreenDraw(word x,word y,char *s,byte attr)
\r
468 screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2));
\r
476 ///////////////////////////////////////////////////////////////////////////
\r
478 // USL_ClearTextScreen() - Makes sure the screen is in text mode, clears it,
\r
479 // and moves the cursor to the leftmost column of the bottom line
\r
481 ///////////////////////////////////////////////////////////////////////////
\r
483 USL_ClearTextScreen(void)
\r
485 // Set to 80x25 color text mode
\r
488 geninterrupt(0x10);
\r
490 // Use BIOS to move the cursor to the bottom of the screen
\r
492 geninterrupt(0x10); // Get current video mode into _BH
\r
493 _DL = 0; // Lefthand side of the screen
\r
494 _DH = 24; // Bottom row
\r
496 geninterrupt(0x10);
\r
499 ///////////////////////////////////////////////////////////////////////////
\r
501 // US_TextScreen() - Puts up the startup text screen
\r
502 // Note: These are the only User Manager functions that can be safely called
\r
503 // before the User Mgr has been started up
\r
505 ///////////////////////////////////////////////////////////////////////////
\r
507 US_TextScreen(void)
\r
511 extern char far introscn;
\r
513 USL_ClearTextScreen();
\r
515 _fmemcpy(MK_FP(0xb800,0),7 + &introscn,80 * 25 * 2);
\r
517 // Check for TED launching here
\r
518 for (i = 1;i < _argc;i++)
\r
520 n = US_CheckParm(_argv[i],ParmStrings);
\r
523 tedlevelnum = atoi(_argv[i + 1]);
\r
524 if (tedlevelnum >= 0)
\r
540 ///////////////////////////////////////////////////////////////////////////
\r
542 // USL_Show() - Changes the appearance of one of the fields on the text
\r
543 // screen. Possibly adds a checkmark in front of it and highlights it
\r
545 ///////////////////////////////////////////////////////////////////////////
\r
547 USL_Show(word x,word y,word w,boolean show,boolean hilight)
\r
551 screen = MK_FP(0xb800,((x - 1) * 2) + (y * 80 * 2));
\r
552 *screen++ = show? 251 : ' '; // Checkmark char or space
\r
554 if (show && hilight)
\r
556 for (w++;w--;screen += 2)
\r
561 ///////////////////////////////////////////////////////////////////////////
\r
563 // USL_ShowMem() - Right justifies a longword in one of the memory fields on
\r
566 ///////////////////////////////////////////////////////////////////////////
\r
568 USL_ShowMem(word x,word y,long mem)
\r
573 for (i = strlen(ltoa(mem,buf,10));i < 5;i++)
\r
574 USL_ScreenDraw(x++,y," ",0x48);
\r
575 USL_ScreenDraw(x,y,buf,0x48);
\r
578 ///////////////////////////////////////////////////////////////////////////
\r
580 // US_UpdateTextScreen() - Called after the ID libraries are started up.
\r
581 // Displays what hardware is present.
\r
583 ///////////////////////////////////////////////////////////////////////////
\r
585 US_UpdateTextScreen(void)
\r
592 // Show video card info
\r
593 b = (grmode == CGAGR);
\r
594 USL_Show(21,7,4,(videocard >= CGAcard) && (videocard <= VGAcard),b);
\r
595 b = (grmode == EGAGR);
\r
596 USL_Show(21,8,4,(videocard >= EGAcard) && (videocard <= VGAcard),b);
\r
597 b = (grmode == VGAGR);
\r
598 USL_Show(21,9,4,videocard == VGAcard,b);
\r
600 USL_ScreenDraw(5,10,"SVGA Compatibility Mode Enabled.",0x4f);
\r
602 // Show input device info
\r
603 USL_Show(60,7,8,true,true);
\r
604 USL_Show(60,8,11,JoysPresent[0],true);
\r
605 USL_Show(60,9,11,JoysPresent[1],true);
\r
606 USL_Show(60,10,5,MousePresent,true);
\r
608 // Show sound hardware info
\r
609 USL_Show(21,14,11,true,SoundMode == sdm_PC);
\r
610 b = (SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib);
\r
611 USL_Show(21,15,5,AdLibPresent && !SoundBlasterPresent,
\r
612 b && !SoundBlasterPresent);
\r
613 USL_Show(21,16,13,SoundBlasterPresent,
\r
614 SoundBlasterPresent && (b || (SoundMode == sdm_SoundBlaster)));
\r
615 USL_Show(21,17,13,SoundSourcePresent,SoundMode == sdm_SoundSource);
\r
617 // Show memory available/used
\r
618 USL_ShowMem(63,15,mminfo.mainmem / 1024);
\r
619 USL_Show(53,15,23,true,true);
\r
620 USL_ShowMem(63,16,mminfo.EMSmem / 1024);
\r
621 USL_Show(53,16,23,mminfo.EMSmem? true : false,true);
\r
622 USL_ShowMem(63,17,mminfo.XMSmem / 1024);
\r
623 USL_Show(53,17,23,mminfo.XMSmem? true : false,true);
\r
624 totalmem = mminfo.mainmem + mminfo.EMSmem + mminfo.XMSmem;
\r
625 USL_ShowMem(63,18,totalmem / 1024);
\r
626 screen = MK_FP(0xb800,1 + (((63 - 1) * 2) + (18 * 80 * 2)));
\r
627 for (i = 0;i < 13;i++,screen += 2)
\r
630 // Change Initializing... to Loading...
\r
631 USL_ScreenDraw(27,22," Loading... ",0x9c);
\r
634 ///////////////////////////////////////////////////////////////////////////
\r
636 // US_FinishTextScreen() - After the main program has finished its initial
\r
637 // loading, this routine waits for a keypress and then clears the screen
\r
639 ///////////////////////////////////////////////////////////////////////////
\r
641 US_FinishTextScreen(void)
\r
643 // Change Loading... to Press a Key
\r
644 USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);
\r
646 if (!(tedlevel || NoWait))
\r
648 IN_ClearKeysDown();
\r
651 IN_ClearKeysDown();
\r
653 USL_ClearTextScreen();
\r
656 // Window/Printing routines
\r
658 ///////////////////////////////////////////////////////////////////////////
\r
660 // US_SetPrintRoutines() - Sets the routines used to measure and print
\r
661 // from within the User Mgr. Primarily provided to allow switching
\r
662 // between masked and non-masked fonts
\r
664 ///////////////////////////////////////////////////////////////////////////
\r
666 US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))
\r
668 USL_MeasureString = measure;
\r
669 USL_DrawString = print;
\r
672 ///////////////////////////////////////////////////////////////////////////
\r
674 // US_Print() - Prints a string in the current window. Newlines are
\r
677 ///////////////////////////////////////////////////////////////////////////
\r
687 while ((c = *se) && (c != '\n'))
\r
691 USL_MeasureString(s,&w,&h);
\r
710 ///////////////////////////////////////////////////////////////////////////
\r
712 // US_PrintUnsigned() - Prints an unsigned long
\r
714 ///////////////////////////////////////////////////////////////////////////
\r
716 US_PrintUnsigned(longword n)
\r
720 US_Print(ultoa(n,buffer,10));
\r
723 ///////////////////////////////////////////////////////////////////////////
\r
725 // US_PrintSigned() - Prints a signed long
\r
727 ///////////////////////////////////////////////////////////////////////////
\r
729 US_PrintSigned(long n)
\r
733 US_Print(ltoa(n,buffer,10));
\r
736 ///////////////////////////////////////////////////////////////////////////
\r
738 // USL_PrintInCenter() - Prints a string in the center of the given rect
\r
740 ///////////////////////////////////////////////////////////////////////////
\r
742 USL_PrintInCenter(char *s,Rect r)
\r
747 USL_MeasureString(s,&w,&h);
\r
748 rw = r.lr.x - r.ul.x;
\r
749 rh = r.lr.y - r.ul.y;
\r
751 px = r.ul.x + ((rw - w) / 2);
\r
752 py = r.ul.y + ((rh - h) / 2);
\r
756 ///////////////////////////////////////////////////////////////////////////
\r
758 // US_PrintCentered() - Prints a string centered in the current window.
\r
760 ///////////////////////////////////////////////////////////////////////////
\r
762 US_PrintCentered(char *s)
\r
768 r.lr.x = r.ul.x + WindowW;
\r
769 r.lr.y = r.ul.y + WindowH;
\r
771 USL_PrintInCenter(s,r);
\r
774 ///////////////////////////////////////////////////////////////////////////
\r
776 // US_CPrintLine() - Prints a string centered on the current line and
\r
777 // advances to the next line. Newlines are not supported.
\r
779 ///////////////////////////////////////////////////////////////////////////
\r
781 US_CPrintLine(char *s)
\r
785 USL_MeasureString(s,&w,&h);
\r
788 Quit("US_CPrintLine() - String exceeds width");
\r
789 px = WindowX + ((WindowW - w) / 2);
\r
795 ///////////////////////////////////////////////////////////////////////////
\r
797 // US_CPrint() - Prints a string in the current window. Newlines are
\r
800 ///////////////////////////////////////////////////////////////////////////
\r
810 while ((c = *se) && (c != '\n'))
\r
825 ///////////////////////////////////////////////////////////////////////////
\r
827 // US_ClearWindow() - Clears the current window to white and homes the
\r
830 ///////////////////////////////////////////////////////////////////////////
\r
832 US_ClearWindow(void)
\r
834 VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);
\r
839 ///////////////////////////////////////////////////////////////////////////
\r
841 // US_DrawWindow() - Draws a frame and sets the current window parms
\r
843 ///////////////////////////////////////////////////////////////////////////
\r
845 US_DrawWindow(word x,word y,word w,word h)
\r
865 VWB_DrawTile8M(sx,sy,0),VWB_DrawTile8M(sx,sy + sh,6);
\r
866 for (i = sx + 8;i <= sx + sw - 8;i += 8)
\r
867 VWB_DrawTile8M(i,sy,1),VWB_DrawTile8M(i,sy + sh,7);
\r
868 VWB_DrawTile8M(i,sy,2),VWB_DrawTile8M(i,sy + sh,8);
\r
870 for (i = sy + 8;i <= sy + sh - 8;i += 8)
\r
871 VWB_DrawTile8M(sx,i,3),VWB_DrawTile8M(sx + sw,i,5);
\r
874 ///////////////////////////////////////////////////////////////////////////
\r
876 // US_CenterWindow() - Generates a window of a given width & height in the
\r
877 // middle of the screen
\r
879 ///////////////////////////////////////////////////////////////////////////
\r
881 US_CenterWindow(word w,word h)
\r
883 US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
\r
886 ///////////////////////////////////////////////////////////////////////////
\r
888 // US_CenterSaveWindow() - Generates a window of a given width & height in
\r
889 // the middle of the screen, saving the background
\r
891 ///////////////////////////////////////////////////////////////////////////
\r
893 US_CenterSaveWindow(word w,word h,memptr *save)
\r
898 x = ((MaxX / 8) - w) / 2;
\r
899 y = ((MaxY / 8) - h) / 2;
\r
900 MM_GetPtr(save,(w * h) * CHARWIDTH);
\r
901 screen = bufferofs + panadjust + ylookup[y] + (x * CHARWIDTH);
\r
902 VW_ScreenToMem(screen,*save,w * CHARWIDTH,h);
\r
903 US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);
\r
906 ///////////////////////////////////////////////////////////////////////////
\r
908 // US_RestoreSaveWindow() - Restores the background of the size of the
\r
909 // current window from the memory specified by save
\r
911 ///////////////////////////////////////////////////////////////////////////
\r
913 US_RestoreSaveWindow(memptr *save)
\r
917 screen = bufferofs + panadjust + ylookup[WindowY] + (WindowX * CHARWIDTH);
\r
918 VW_MemToScreen(*save,screen,WindowW * CHARWIDTH,WindowH);
\r
922 ///////////////////////////////////////////////////////////////////////////
\r
924 // US_SaveWindow() - Saves the current window parms into a record for
\r
925 // later restoration
\r
927 ///////////////////////////////////////////////////////////////////////////
\r
929 US_SaveWindow(WindowRec *win)
\r
940 ///////////////////////////////////////////////////////////////////////////
\r
942 // US_RestoreWindow() - Sets the current window parms to those held in the
\r
945 ///////////////////////////////////////////////////////////////////////////
\r
947 US_RestoreWindow(WindowRec *win)
\r
960 ///////////////////////////////////////////////////////////////////////////
\r
962 // US_StartCursor() - Sets up the cursor for User Mgr use
\r
964 ///////////////////////////////////////////////////////////////////////////
\r
966 US_StartCursor(void)
\r
970 VW_SetCursor(CURSORARROWSPR);
\r
971 CursorX = MaxX / 2;
\r
972 CursorY = MaxY / 2;
\r
973 VW_MoveCursor(CursorX,CursorY);
\r
976 IN_ReadCursor(&info); // Dispose of any accumulated movement
\r
979 ///////////////////////////////////////////////////////////////////////////
\r
981 // US_ShutCursor() - Cleans up after US_StartCursor()
\r
983 ///////////////////////////////////////////////////////////////////////////
\r
985 US_ShutCursor(void)
\r
990 ///////////////////////////////////////////////////////////////////////////
\r
992 // US_UpdateCursor() - Gets the new cursor position & button states from
\r
993 // the Input Mgr and tells the View Mgr where the cursor is
\r
995 ///////////////////////////////////////////////////////////////////////////
\r
997 US_UpdateCursor(void)
\r
1001 IN_ReadCursor(&info);
\r
1002 if (info.x || info.y || CursorBad)
\r
1004 CursorX += info.x;
\r
1005 if (CursorX >= MaxX)
\r
1006 CursorX = MaxX - 1;
\r
1007 else if (CursorX < 0)
\r
1010 CursorY += info.y;
\r
1011 if (CursorY >= MaxY)
\r
1012 CursorY = MaxY - 1;
\r
1013 else if (CursorY < 0)
\r
1016 VW_MoveCursor(CursorX,CursorY);
\r
1017 CursorBad = false;
\r
1019 Button0 = info.button0;
\r
1020 Button1 = info.button1;
\r
1021 return(Button0 || Button1);
\r
1026 ///////////////////////////////////////////////////////////////////////////
\r
1028 // USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()
\r
1030 ///////////////////////////////////////////////////////////////////////////
\r
1032 USL_XORICursor(int x,int y,char *s,word cursor)
\r
1034 char buf[MaxString];
\r
1038 buf[cursor] = '\0';
\r
1039 USL_MeasureString(buf,&w,&h);
\r
1043 USL_DrawString("\x80");
\r
1046 ///////////////////////////////////////////////////////////////////////////
\r
1048 // US_LineInput() - Gets a line of user input at (x,y), the string defaults
\r
1049 // to whatever is pointed at by def. Input is restricted to maxchars
\r
1050 // chars or maxwidth pixels wide. If the user hits escape (and escok is
\r
1051 // true), nothing is copied into buf, and false is returned. If the
\r
1052 // user hits return, the current string is copied into buf, and true is
\r
1055 ///////////////////////////////////////////////////////////////////////////
\r
1057 US_LineInput(int x,int y,char *buf,char *def,boolean escok,
\r
1058 int maxchars,int maxwidth)
\r
1061 cursorvis,cursormoved,
\r
1065 s[MaxString],olds[MaxString];
\r
1070 longword lasttime;
\r
1079 cursor = strlen(s);
\r
1080 cursormoved = redraw = true;
\r
1082 cursorvis = done = false;
\r
1083 lasttime = TimeCount;
\r
1084 LastASCII = key_None;
\r
1085 LastScan = sc_None;
\r
1090 USL_XORICursor(x,y,s,cursor);
\r
1096 LastScan = sc_None;
\r
1098 LastASCII = key_None;
\r
1104 case sc_LeftArrow:
\r
1108 cursormoved = true;
\r
1110 case sc_RightArrow:
\r
1114 cursormoved = true;
\r
1119 cursormoved = true;
\r
1122 cursor = strlen(s);
\r
1124 cursormoved = true;
\r
1142 case sc_BackSpace:
\r
1145 strcpy(s + cursor - 1,s + cursor);
\r
1150 cursormoved = true;
\r
1155 strcpy(s + cursor,s + cursor + 1);
\r
1159 cursormoved = true;
\r
1162 case 0x4c: // Keypad 5
\r
1164 case sc_DownArrow:
\r
1175 USL_MeasureString(s,&w,&h);
\r
1180 && (len < MaxString - 1)
\r
1181 && ((!maxchars) || (len < maxchars))
\r
1182 && ((!maxwidth) || (w < maxwidth))
\r
1185 for (i = len + 1;i > cursor;i--)
\r
1196 USL_DrawString(olds);
\r
1201 USL_DrawString(s);
\r
1208 cursorvis = false;
\r
1209 lasttime = TimeCount - TickBase;
\r
1211 cursormoved = false;
\r
1213 if (TimeCount - lasttime > TickBase / 2)
\r
1215 lasttime = TimeCount;
\r
1217 cursorvis ^= true;
\r
1220 USL_XORICursor(x,y,s,cursor);
\r
1222 VW_UpdateScreen();
\r
1226 USL_XORICursor(x,y,s,cursor);
\r
1231 USL_DrawString(olds);
\r
1234 VW_UpdateScreen();
\r
1236 IN_ClearKeysDown();
\r
1240 // Control panel routines
\r
1242 static boolean FlushHelp;
\r
1243 static WindowRec HelpWindow,BottomWindow;
\r
1250 uii_Bad,uii_Button,uii_RadioButton,uii_CheckBox,uii_KeyCap
\r
1252 #define ui_Normal 0
\r
1253 #define ui_Selected 1
\r
1254 #define ui_Disabled 2
\r
1256 // Prototype the custom routines
\r
1257 static boolean USL_CtlButtonCustom(UserCall,word,word),
\r
1258 USL_CtlPButtonCustom(UserCall,word,word),
\r
1259 USL_CtlPSButtonCustom(UserCall,word,word),
\r
1260 USL_CtlPRButtonCustom(UserCall,word,word),
\r
1261 USL_CtlHButtonCustom(UserCall,word,word),
\r
1262 USL_CtlDButtonCustom(UserCall,word,word),
\r
1263 USL_CtlDEButtonCustom(UserCall,word,word),
\r
1264 USL_CtlDLButtonCustom(UserCall,word,word),
\r
1265 USL_CtlDSButtonCustom(UserCall,word,word),
\r
1266 USL_CtlSButtonCustom(UserCall,word,word),
\r
1267 USL_CtlCButtonCustom(UserCall,word,word),
\r
1268 USL_CtlCKbdButtonCustom(UserCall,word,word),
\r
1269 USL_CtlCJoyButtonCustom(UserCall,word,word);
\r
1271 // The structure of a user interaction item
\r
1273 Rect r; // The enclosing rectangle
\r
1274 UIType type; // The type of item
\r
1275 int picup,picdown; // What to draw when up/down
\r
1276 char *help; // Floating help string
\r
1277 ScanCode key; // Key equiv
\r
1278 word sel; // Interaction flags (ui_XXX)
\r
1279 boolean (*custom)(UserCall,word,word); // Custom routine
\r
1280 char *text; // Text for some items
\r
1284 word i,n, // Hit CtlPanels2[i][n]
\r
1285 toi,ton; // Move to CtlPanels2[toi][ton]
\r
1288 static ScanCode *KeyMaps[] =
\r
1290 &KbdDefs[0].button0,&KbdDefs[0].button1,
\r
1291 &KbdDefs[0].upleft,&KbdDefs[0].up,&KbdDefs[0].upright,
\r
1292 &KbdDefs[0].left, &KbdDefs[0].right,
\r
1293 &KbdDefs[0].downleft,&KbdDefs[0].down,&KbdDefs[0].downright,
\r
1296 // Some macros to make rectangle definition quite a bit less unpleasant
\r
1297 #define CtlPanelX 8
\r
1298 #define CtlPanelY 4
\r
1299 #define CtlPanel2X (8*8)
\r
1300 #define CtlPanel2Y (2*8)
\r
1301 #define CtlPanel3X (8*8)
\r
1302 #define CtlPanel3Y (7*8)
\r
1304 #define CtlPanelR(n) { CtlPanelX,CtlPanelY+(32 * (n)),\
\r
1305 CtlPanelX+40,CtlPanelY+(32 * (n)) + 32}
\r
1306 #define CtlPanel2R(x,y) { CtlPanel2X+(x)*8,CtlPanel2Y+(y)*8,\
\r
1307 CtlPanel2X+32+(x)*8,CtlPanel2Y+24+(y)*8}
\r
1308 #define CtlPanel3R(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
\r
1309 CtlPanel3X+32+(x)*8,CtlPanel3Y+24+(y)*8}
\r
1310 static UserItem CtlPanels[] =
\r
1312 {CtlPanelR(0),uii_RadioButton,CTL_STARTUPPIC,CTL_STARTDNPIC,"Start or Resume a Game",sc_None,ui_Normal,USL_CtlButtonCustom},
\r
1313 {CtlPanelR(1),uii_RadioButton,CTL_HELPUPPIC,CTL_HELPDNPIC,"Get Help With Commander Keen",sc_None,ui_Normal,USL_CtlButtonCustom},
\r
1314 {CtlPanelR(2),uii_RadioButton,CTL_DISKUPPIC,CTL_DISKDNPIC,"Load / Save / Quit",sc_None,ui_Normal,USL_CtlButtonCustom},
\r
1315 {CtlPanelR(3),uii_RadioButton,CTL_CONTROLSUPPIC,CTL_CONTROLSDNPIC,"Choose Controls",sc_C,ui_Normal,USL_CtlButtonCustom},
\r
1316 {CtlPanelR(4),uii_RadioButton,CTL_SOUNDUPPIC,CTL_SOUNDDNPIC,"Select Sound Device",sc_F2,ui_Normal,USL_CtlButtonCustom},
\r
1317 {CtlPanelR(5),uii_RadioButton,CTL_MUSICUPPIC,CTL_MUSICDNPIC,"Turn Music On / Off",sc_F7,ui_Normal,USL_CtlButtonCustom},
\r
1318 {-1,-1,-1,-1,uii_Bad}
\r
1322 {CtlPanel2R(10,0),uii_RadioButton,CTL_P_NEWGAMEUPPIC,CTL_P_NEWGAMEDNPIC,"Choose Difficulty for the New Game",sc_F5,ui_Normal,USL_CtlPButtonCustom},
\r
1323 {CtlPanel2R(15,0),uii_RadioButton,CTL_P_RESUMEUPPIC,CTL_P_RESUMEDNPIC,"Go Back to Current Game",sc_None,ui_Normal,USL_CtlPButtonCustom},
\r
1324 {-1,-1,-1,-1,uii_Bad}
\r
1328 {CtlPanel3R(13,5),uii_Button,CTL_P_MEDUPPIC,CTL_P_MEDDNPIC,"Start New Game in Normal Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},
\r
1329 {CtlPanel3R(8,5),uii_Button,CTL_P_EASYUPPIC,CTL_P_EASYDNPIC,"Start New Game in Easy Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},
\r
1330 {CtlPanel3R(18,5),uii_Button,CTL_P_HARDUPPIC,CTL_P_HARDDNPIC,"Start New Game in Hard Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},
\r
1331 {-1,-1,-1,-1,uii_Bad}
\r
1335 {CtlPanel3R(13,5),uii_Button,CTL_P_GORESUMEUPPIC,CTL_P_GORESUMEDNPIC,"Resume Current Game",sc_None,ui_Normal,USL_CtlPRButtonCustom},
\r
1336 {-1,-1,-1,-1,uii_Bad}
\r
1340 {CtlPanel2R(8,0),uii_Button,CTL_H_LOSTUPPIC,CTL_H_LOSTDNPIC,"Help Me, I'm Lost!",sc_F1,ui_Normal,USL_CtlHButtonCustom},
\r
1341 {CtlPanel2R(13,0),uii_Button,CTL_H_CTRLUPPIC,CTL_H_CTRLDNPIC,"Get Help with Controls",sc_None,ui_Normal,USL_CtlHButtonCustom},
\r
1342 {CtlPanel2R(18,0),uii_Button,CTL_H_STORYUPPIC,CTL_H_STORYDNPIC,"Read Story & Game Tips",sc_None,ui_Normal,USL_CtlHButtonCustom},
\r
1343 {-1,-1,-1,-1,uii_Bad}
\r
1347 {CtlPanel2R(9,0),uii_RadioButton,CTL_D_LSGAMEUPPIC,CTL_D_LSGAMEDNPIC,"Load or Save a Game",sc_F6,ui_Normal,USL_CtlDButtonCustom},
\r
1348 {CtlPanel2R(15,0),uii_RadioButton,CTL_D_DOSUPPIC,CTL_D_DOSDNPIC,"Exit to DOS",sc_Q,ui_Normal,USL_CtlDButtonCustom},
\r
1349 {-1,-1,-1,-1,uii_Bad}
\r
1353 #define CtlPanel3LSR(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
\r
1354 CtlPanel3X+32+(x)*8,CtlPanel3Y+16+(y)*8}
\r
1355 {CtlPanel3LSR(1,0),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
\r
1356 {CtlPanel3LSR(6,0),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
\r
1357 {CtlPanel3LSR(1,2),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
\r
1358 {CtlPanel3LSR(6,2),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
\r
1359 {CtlPanel3LSR(1,4),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
\r
1360 {CtlPanel3LSR(6,4),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
\r
1361 {CtlPanel3LSR(1,6),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
\r
1362 {CtlPanel3LSR(6,6),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
\r
1363 {CtlPanel3LSR(1,8),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
\r
1364 {CtlPanel3LSR(6,8),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
\r
1365 {CtlPanel3LSR(1,10),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
\r
1366 {CtlPanel3LSR(6,10),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
\r
1367 {CtlPanel3LSR(1,12),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},
\r
1368 {CtlPanel3LSR(6,12),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},
\r
1369 {-1,-1,-1,-1,uii_Bad}
\r
1373 #define CtlPanel3ER(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
\r
1374 CtlPanel3X+40+(x)*8,CtlPanel3Y+24+(y)*8}
\r
1375 {CtlPanel3ER(12,5),uii_Button,CTL_D_EXITUPPIC,CTL_D_EXITDNPIC,"Really Exit to DOS",sc_None,ui_Normal,USL_CtlDEButtonCustom},
\r
1376 {-1,-1,-1,-1,uii_Bad}
\r
1380 {CtlPanel2R(8,0),uii_RadioButton,CTL_C_KBDUPPIC,CTL_C_KBDDNPIC,"Use / Configure Keyboard",sc_F3,ui_Normal,USL_CtlCButtonCustom},
\r
1381 {CtlPanel2R(13,0),uii_RadioButton,CTL_C_JOY1UPPIC,CTL_C_JOY1DNPIC,"Use / Configure Joystick 1",sc_None,ui_Normal,USL_CtlCButtonCustom},
\r
1382 {CtlPanel2R(18,0),uii_RadioButton,CTL_C_JOY2UPPIC,CTL_C_JOY2DNPIC,"Use / Configure Joystick 2",sc_None,ui_Normal,USL_CtlCButtonCustom},
\r
1383 {-1,-1,-1,-1,uii_Bad}
\r
1385 #define CtlPanelKC3R(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\
\r
1386 CtlPanel3X+56+(x)*8,CtlPanel3Y+32+(y)*8}
\r
1389 {CtlPanelKC3R(1,2),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key for Jumping",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1390 {CtlPanelKC3R(1,6),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key for Throwing",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1391 {CtlPanelKC3R(8,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up & Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1392 {CtlPanelKC3R(15,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1393 {CtlPanelKC3R(22,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up & Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1394 {CtlPanelKC3R(8,4),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1395 {CtlPanelKC3R(22,4),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1396 {CtlPanelKC3R(8,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down & Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1397 {CtlPanelKC3R(15,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1398 {CtlPanelKC3R(22,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down & Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},
\r
1399 {-1,-1,-1,-1,uii_Bad}
\r
1403 {CtlPanel3R(13,5),uii_Button,CTL_C_CALIBRATEUPPIC,CTL_C_CALIBRATEDNPIC,"Configure Joystick",sc_None,ui_Normal,USL_CtlCJoyButtonCustom},
\r
1404 {-1,-1,-1,-1,uii_Bad}
\r
1408 {CtlPanel2R(3,0),uii_RadioButton,CTL_S_NOSNDUPPIC,CTL_S_NOSNDDNPIC,"Turn Sound Off",sc_None,ui_Normal,USL_CtlSButtonCustom},
\r
1409 {CtlPanel2R(8,0),uii_RadioButton,CTL_S_PCSNDUPPIC,CTL_S_PCSNDDNPIC,"Use PC Speaker",sc_None,ui_Normal,USL_CtlSButtonCustom},
\r
1410 {CtlPanel2R(13,0),uii_RadioButton,CTL_S_ADLIBUPPIC,CTL_S_ADLIBDNPIC,"Use AdLib Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},
\r
1411 {CtlPanel2R(18,0),uii_RadioButton,CTL_S_SNDBLUPPIC,CTL_S_SNDBLDNPIC,"Use SoundBlaster Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},
\r
1412 {CtlPanel2R(23,0),uii_RadioButton,CTL_S_SNDSRCUPPIC,CTL_S_SNDSRCDNPIC,"Use Sound Source Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},
\r
1413 {-1,-1,-1,-1,uii_Bad}
\r
1417 {CtlPanel3R(7,2),uii_CheckBox,CTL_CHECKUPPIC,CTL_CHECKDNPIC,"Turn Tandy Mode On / Off",sc_None,ui_Normal,0,"Tandy Mode"},
\r
1418 {CtlPanel3R(7,6),uii_CheckBox,CTL_CHECKUPPIC,CTL_CHECKDNPIC,"Switch between LPT1 & LPT2",sc_None,ui_Normal,0,"Use LPT2"},
\r
1419 {-1,-1,-1,-1,uii_Bad}
\r
1423 {CtlPanel2R(9,0),uii_RadioButton,CTL_M_NOMUSUPPIC,CTL_M_NOMUSDNPIC,"Background Music Off"},
\r
1424 {CtlPanel2R(15,0),uii_RadioButton,CTL_M_ADLIBUPPIC,CTL_M_ADLIBDNPIC,"Use AdLib/SoundBlaster Music"},
\r
1425 {-1,-1,-1,-1,uii_Bad}
\r
1429 CtlPPanels, // Start
\r
1430 CtlHPanels, // Help
\r
1431 CtlDPanels, // Disk
\r
1432 CtlCPanels, // Controls
\r
1433 CtlSPanels, // Sound
\r
1434 CtlMPanels // Music
\r
1436 *TheItems[4] = {CtlPanels};
\r
1437 static int CtlPanelButton;
\r
1439 ///////////////////////////////////////////////////////////////////////////
\r
1441 // USL_TurnOff() - Goes through a list of UserItems and sets them all to
\r
1442 // the normal state
\r
1444 ///////////////////////////////////////////////////////////////////////////
\r
1446 USL_TurnOff(UserItem *ip)
\r
1448 while (ip->type != uii_Bad)
\r
1450 ip->sel = ui_Normal;
\r
1455 ///////////////////////////////////////////////////////////////////////////
\r
1457 // USL_FindDown() - Finds which UserItem, if any, is selected in the given
\r
1460 ///////////////////////////////////////////////////////////////////////////
\r
1462 USL_FindDown(UserItem *ip)
\r
1466 for (i = 0;ip->type != uii_Bad;i++,ip++)
\r
1467 if (ip->sel & ui_Selected)
\r
1472 ///////////////////////////////////////////////////////////////////////////
\r
1474 // USL_ShowHelp() - Shows the specified string in the help window
\r
1476 ///////////////////////////////////////////////////////////////////////////
\r
1478 USL_ShowHelp(char *s)
\r
1485 US_SaveWindow(&wr);
\r
1486 US_RestoreWindow(&HelpWindow);
\r
1489 US_PrintCentered(s);
\r
1491 US_RestoreWindow(&wr);
\r
1494 ///////////////////////////////////////////////////////////////////////////
\r
1496 // USL_HandleError() - Handles telling the user that there's been an error
\r
1498 ///////////////////////////////////////////////////////////////////////////
\r
1500 USL_HandleError(int num)
\r
1504 strcpy(buf,"Error: ");
\r
1506 strcat(buf,"Unknown");
\r
1507 else if (num == ENOMEM)
\r
1508 strcat(buf,"Disk is Full");
\r
1509 else if (num == EINVFMT)
\r
1510 strcat(buf,"File is Incomplete");
\r
1512 strcat(buf,sys_errlist[num]);
\r
1516 fontcolor = F_SECONDCOLOR;
\r
1517 USL_ShowHelp(buf);
\r
1518 fontcolor = F_BLACK;
\r
1519 VW_UpdateScreen();
\r
1521 IN_ClearKeysDown();
\r
1525 VW_UpdateScreen();
\r
1528 ///////////////////////////////////////////////////////////////////////////
\r
1530 // USL_DrawItem() - Draws a UserItem. If there's a custom routine, this will
\r
1531 // call it with a uic_Draw command. If the custom routine returns true,
\r
1532 // then the routine handled all of the drawing. If it returns false,
\r
1533 // then this routine does the default drawing.
\r
1535 ///////////////////////////////////////////////////////////////////////////
\r
1537 USL_DrawItem(word hiti,word hitn)
\r
1539 boolean handled,centered;
\r
1542 int picup,picdown;
\r
1546 ip = &TheItems[hiti][hitn];
\r
1548 handled = ip->custom(uic_Draw,hiti,hitn);
\r
1554 picup = ip->picup;
\r
1555 picdown = ip->picdown;
\r
1558 case uii_CheckBox:
\r
1559 px = ip->r.lr.x + 8;
\r
1560 py = ip->r.ul.y + 8;
\r
1565 if (!(ip->sel & ui_Selected))
\r
1582 VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,
\r
1583 (ip->sel & ui_Selected)? picdown : picup);
\r
1587 USL_PrintInCenter(text,r);
\r
1590 USL_MeasureString(text,&w,&h);
\r
1591 VWB_Bar(px,py,w + 7,h,WHITE);
\r
1592 USL_DrawString(text);
\r
1595 if (ip->sel & ui_Disabled)
\r
1597 if ((picup == CTL_D_LOADUPPIC) || (picup == CTL_D_SAVEUPPIC))
\r
1598 VWB_DrawMPic(ip->r.ul.x,ip->r.ul.y,CTL_LSMASKPICM);
\r
1600 VWB_DrawMPic(ip->r.ul.x,ip->r.ul.y,CTL_LITTLEMASKPICM);
\r
1605 ///////////////////////////////////////////////////////////////////////////
\r
1607 // USL_DoHit() - Handles a hit on a UserItem. If there's a custom routine,
\r
1608 // it will be called. If it returns true, then don't do anything
\r
1609 // more. If it returns false, then use the standard behaviour
\r
1611 ///////////////////////////////////////////////////////////////////////////
\r
1613 USL_DoHit(word hiti,word hitn)
\r
1619 ip = &TheItems[hiti][hitn];
\r
1621 handled = ip->custom(uic_Hit,hiti,hitn);
\r
1627 if (TheItems[hiti][hitn].sel & ui_Disabled)
\r
1629 fontcolor = F_SECONDCOLOR;
\r
1630 USL_ShowHelp("This Item is Disabled");
\r
1631 fontcolor = F_BLACK;
\r
1640 // Must have a custom routine to handle hits - this just redraws
\r
1641 ip->sel ^= ui_Selected;
\r
1642 USL_DrawItem(hiti,hitn);
\r
1643 case uii_CheckBox:
\r
1644 ip->sel ^= ui_Selected;
\r
1645 USL_DrawItem(hiti,hitn);
\r
1647 case uii_RadioButton:
\r
1648 for (i = 0,ip = TheItems[hiti];ip->type != uii_Bad;i++,ip++)
\r
1653 && (ip->type == uii_RadioButton)
\r
1654 && (ip->sel & ui_Selected)
\r
1657 ip->sel &= ~ui_Selected;
\r
1658 USL_DrawItem(hiti,i);
\r
1661 TheItems[hiti][hitn].sel |= ui_Selected;
\r
1662 USL_DrawItem(hiti,hitn);
\r
1670 ///////////////////////////////////////////////////////////////////////////
\r
1672 // USL_IsInRect() - Checks to see if the coordinates given are within any
\r
1673 // of the Rects in the UserItem list. If so, returns true & sets the
\r
1674 // index & number for lookup. If not, returns false.
\r
1676 ///////////////////////////////////////////////////////////////////////////
\r
1678 USL_IsInRect(word x,word y,word *index,word *number)
\r
1680 UserItem *item,**items;
\r
1688 while (item->type != uii_Bad)
\r
1692 (x >= item->r.ul.x)
\r
1693 && (x < item->r.lr.x)
\r
1694 && (y >= item->r.ul.y)
\r
1695 && (y < item->r.lr.y)
\r
1708 ///////////////////////////////////////////////////////////////////////////
\r
1710 // USL_TrackItem() - Tracks the given item. If the cursor is inside of the
\r
1711 // item, it's redrawn as down. If the cursor is outside, the item is
\r
1712 // drawn in its original state. Returns true if the button was released
\r
1713 // while the cursor was inside the item, or false if it wasn't.
\r
1715 ///////////////////////////////////////////////////////////////////////////
\r
1717 USL_TrackItem(word hiti,word hitn)
\r
1719 boolean inside,last;
\r
1725 ip = &TheItems[hiti][hitn];
\r
1727 if (ip->type == uii_RadioButton)
\r
1730 for (op = TheItems[hiti],on = 0;op->type != uii_Bad;op++,on++)
\r
1732 if (op->sel & ui_Selected)
\r
1740 othersel = op->sel;
\r
1745 if (ip->sel & ui_Disabled)
\r
1747 fontcolor = F_SECONDCOLOR;
\r
1748 USL_ShowHelp("This item is disabled");
\r
1749 fontcolor = F_BLACK;
\r
1751 while (US_UpdateCursor())
\r
1752 VW_UpdateScreen();
\r
1761 USL_IsInRect(CursorX,CursorY,&ini,&inn);
\r
1762 inside = (ini == hiti) && (inn == hitn);
\r
1763 if (inside != last)
\r
1769 op->sel &= ~ui_Selected;
\r
1770 ip->sel |= ui_Selected;
\r
1773 ip->sel = sel ^ ui_Selected;
\r
1777 if (op && (op != ip))
\r
1779 op->sel |= ui_Selected;
\r
1780 ip->sel &= ~ui_Selected;
\r
1786 USL_DrawItem(hiti,hitn);
\r
1787 if (op && (op != ip))
\r
1788 USL_DrawItem(hiti,on);
\r
1792 VW_UpdateScreen();
\r
1793 } while (US_UpdateCursor());
\r
1796 op->sel = othersel;
\r
1800 if (op && (op != ip))
\r
1801 USL_DrawItem(hiti,on);
\r
1802 USL_DrawItem(hiti,hitn);
\r
1803 VW_UpdateScreen();
\r
1809 ///////////////////////////////////////////////////////////////////////////
\r
1811 // USL_GlideCursor() - Smoothly moves the cursor to the given location
\r
1813 ///////////////////////////////////////////////////////////////////////////
\r
1815 USL_GlideCursor(long newx,long newy)
\r
1821 if (grmode == CGAGR)
\r
1826 x = (long)CursorX << 16;
\r
1827 dx = ((newx << 16) - x) / steps;
\r
1828 y = (long)CursorY << 16;
\r
1829 dy = ((newy << 16) - y) / steps;
\r
1831 while ((CursorX != newx) || (CursorY != newy))
\r
1836 CursorX = x >> 16;
\r
1837 CursorY = y >> 16;
\r
1838 VW_MoveCursor(CursorX,CursorY);
\r
1839 VW_UpdateScreen();
\r
1844 ///////////////////////////////////////////////////////////////////////////
\r
1846 // USL_FindRect() - Code so ugly you'll puke! Given a Rect and direction,
\r
1847 // this routine will try to find a UserItem to move the cursor to
\r
1849 ///////////////////////////////////////////////////////////////////////////
\r
1851 USL_FindRect(Rect r,Motion xd,Motion yd)
\r
1855 Point diffs[9],diff,*dp;
\r
1856 Rect *rp,*good,*goods[9];
\r
1857 UserItem *ip,**items;
\r
1859 for (m1 = motion_Up,dp = diffs;m1 <= motion_Down;m1++)
\r
1861 for (m2 = motion_Left;m2 <= motion_Right;m2++,dp++)
\r
1863 dp->x = m2 * 1024;
\r
1864 dp->y = m1 * 1024;
\r
1867 for (i = 0;i < 9;i++)
\r
1870 // Find out which octants all of the rects (except r) are in
\r
1871 for (items = TheItems;*items;items++)
\r
1873 for (ip = *items;ip->type != uii_Bad;ip++)
\r
1876 diff.x = rp->ul.x - r.ul.x;
\r
1877 diff.y = rp->ul.y - r.ul.y;
\r
1878 if (!(diff.x || diff.y))
\r
1883 ((rp->ul.x >= r.ul.x) && (rp->ul.x < r.lr.x))
\r
1884 || ((rp->lr.x > r.ul.x) && (rp->lr.x <= r.lr.x))
\r
1887 if (rp->lr.y <= r.ul.y)
\r
1889 if (!(goods[1] && (diff.y < diffs[1].y)))
\r
1895 else if (rp->ul.y >= r.lr.y)
\r
1897 if (!(goods[7] && (diff.y > diffs[7].y)))
\r
1907 ((rp->ul.y >= r.ul.y) && (rp->ul.y < r.lr.y))
\r
1908 || ((rp->lr.y > r.ul.y) && (rp->lr.y <= r.lr.y))
\r
1911 if (rp->lr.x <= r.ul.x)
\r
1913 if (!(goods[3] && (diff.x < diffs[3].x)))
\r
1919 else if (rp->ul.x >= r.lr.x)
\r
1921 if (!(goods[5] && (diff.x > diffs[5].x)))
\r
1929 if (rp->ul.x < r.ul.x) // 0,6
\r
1931 if (rp->lr.y <= r.ul.y)
\r
1936 || (diff.y > diffs[0].y)
\r
1937 || (diff.x > diffs[6].x)
\r
1944 else if (rp->ul.y >= r.lr.y)
\r
1949 || (diff.y < diffs[6].y)
\r
1950 || (diff.x > diffs[6].x)
\r
1959 if (rp->lr.x > r.lr.x) // 2,8
\r
1961 if (rp->lr.y <= r.ul.y)
\r
1966 || (diff.y > diffs[2].y)
\r
1967 || (diff.x < diffs[2].x)
\r
1974 else if (rp->ul.y >= r.lr.y)
\r
1979 || (diff.y < diffs[8].y)
\r
1980 || (diff.x < diffs[8].x)
\r
1994 i1 = 1,i2 = 0,i3 = 2;
\r
2000 i1 = 3,i2 = 0,i3 = 6;
\r
2002 case motion_Right:
\r
2003 i1 = 5,i2 = 8,i3 = 2;
\r
2008 i1 = 7,i2 = 8,i3 = 6;
\r
2013 (good = goods[i1])
\r
2014 || (good = goods[i2])
\r
2015 || (good = goods[i3])
\r
2019 CursorX = good->lr.x - 8;
\r
2020 CursorY = good->lr.y - 8;
\r
2022 US_UpdateCursor();
\r
2024 USL_GlideCursor(good->lr.x - 8,good->lr.y - 8);
\r
2027 ///////////////////////////////////////////////////////////////////////////
\r
2029 // USL_CtlButtonCustom() - The custom routine for all of the Control Panel
\r
2030 // (leftmost) buttons. Clears all of the other item lists, clears the
\r
2031 // large area, and draws the line dividing the top and bottom areas.
\r
2032 // Then it sets up and draws the appropriate top row of icons.
\r
2034 ///////////////////////////////////////////////////////////////////////////
\r
2036 USL_CtlButtonCustom(UserCall call,word i,word n)
\r
2041 if (call != uic_Hit)
\r
2044 if (n == CtlPanelButton)
\r
2048 for (j = 8;j < 38;j++)
\r
2050 VWB_DrawTile8M(j * 8,6 * 8,10);
\r
2051 VWB_DrawTile8M(j * 8,21 * 8,10);
\r
2053 VWB_DrawTile8M(7 * 8,6 * 8,9);
\r
2054 VWB_DrawTile8M(38 * 8,6 * 8,11);
\r
2055 VWB_DrawTile8M(7 * 8,21 * 8,9);
\r
2056 VWB_DrawTile8M(38 * 8,21 * 8,11);
\r
2058 for (j = 1;j < 4;j++)
\r
2059 TheItems[j] = nil;
\r
2061 // Set to new button
\r
2062 CtlPanelButton = n;
\r
2065 TheItems[1] = ip = CtlPanels2[CtlPanelButton];
\r
2067 while (ip && (ip->type != uii_Bad))
\r
2069 USL_DrawItem(i + 1,j);
\r
2070 if (ip->sel & ui_Selected)
\r
2071 USL_DoHit(i + 1,j);
\r
2079 ///////////////////////////////////////////////////////////////////////////
\r
2081 // USL_CtlCKbdButtonCustom() - The custom routine for the keyboard keycaps.
\r
2082 // This routine gets a scancode and puts it in the appropriate
\r
2083 // KbdDefs[0] member.
\r
2085 ///////////////////////////////////////////////////////////////////////////
\r
2087 USL_CtlCKbdButtonCustom(UserCall call,word i,word n)
\r
2095 if (call != uic_Hit)
\r
2098 ip = &TheItems[i][n];
\r
2100 fontcolor = F_SECONDCOLOR;
\r
2101 USL_ShowHelp(ip->help);
\r
2102 fontcolor = F_BLACK;
\r
2104 VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,ip->picdown);
\r
2105 VW_UpdateScreen();
\r
2107 LastScan = sc_None;
\r
2112 if (TimeCount - time > 35) // Half-second delays
\r
2115 VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,state? ip->picdown : ip->picup);
\r
2116 VW_UpdateScreen();
\r
2119 if (US_UpdateCursor())
\r
2121 while (US_UpdateCursor())
\r
2129 if (LastScan == sc_LShift)
\r
2130 LastScan = sc_None;
\r
2132 } while (!(scan = LastScan));
\r
2133 IN_ClearKey(scan);
\r
2134 if (scan != sc_Escape)
\r
2136 for (j = 0,state = false;j < 10;j++)
\r
2140 if (*(KeyMaps[j]) == scan)
\r
2148 fontcolor = F_SECONDCOLOR;
\r
2149 USL_ShowHelp("That Key is Already Used!");
\r
2150 fontcolor = F_BLACK;
\r
2154 ip->text = IN_GetScanName(scan);
\r
2155 *(KeyMaps[n]) = scan;
\r
2160 USL_DrawItem(i,n);
\r
2162 VW_UpdateScreen();
\r
2167 ///////////////////////////////////////////////////////////////////////////
\r
2169 // USL_CtlCJoyButtonCustom() - The custom button routine for joystick
\r
2172 ///////////////////////////////////////////////////////////////////////////
\r
2174 USL_CtlCJoyButtonCustom(UserCall call,word i,word n)
\r
2180 i++,n++; // Shut the compiler up
\r
2182 if (call != uic_Hit)
\r
2185 IN_ClearKeysDown();
\r
2186 joy = USL_FindDown(CtlCPanels) - 1;
\r
2190 fontcolor = F_SECONDCOLOR;
\r
2192 USL_ShowHelp("Move Joystick to the Upper-Left");
\r
2193 VW_UpdateScreen();
\r
2194 while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joy))
\r
2196 if (LastScan != sc_Escape)
\r
2198 IN_GetJoyAbs(joy,&minx,&miny);
\r
2199 while (IN_GetJoyButtonsDB(joy))
\r
2202 USL_ShowHelp("Move Joystick to the Lower-Right");
\r
2203 VW_UpdateScreen();
\r
2204 while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joy))
\r
2206 if (LastScan != sc_Escape)
\r
2208 IN_GetJoyAbs(0,&maxx,&maxy);
\r
2209 IN_SetupJoy(joy,minx,maxx,miny,maxy);
\r
2213 if (LastScan != sc_Escape)
\r
2214 while (IN_GetJoyButtonsDB(joy))
\r
2218 IN_ClearKeysDown();
\r
2220 fontcolor = F_BLACK;
\r
2226 ///////////////////////////////////////////////////////////////////////////
\r
2228 // USL_ClearBottom() - Clears the bottom part of the window
\r
2230 ///////////////////////////////////////////////////////////////////////////
\r
2232 USL_ClearBottom(void)
\r
2236 US_SaveWindow(&wr);
\r
2237 US_RestoreWindow(&BottomWindow);
\r
2241 US_RestoreWindow(&wr);
\r
2244 ///////////////////////////////////////////////////////////////////////////
\r
2246 // USL_FormatHelp() - Formats helptext. Runs through and calculates the
\r
2247 // number of lines, and the offset for the start of each line. Stops
\r
2248 // after len bytes or when it hits a tilde ('~'). Munges the text.
\r
2250 ///////////////////////////////////////////////////////////////////////////
\r
2252 USL_FormatHelp(char far *text,long len)
\r
2258 far *s,far *l,far *le;
\r
2263 MM_GetPtr(&LineOffsets,MaxHelpLines * sizeof(word));
\r
2264 off = (word far *)LineOffsets;
\r
2265 for (line = 0,le = l = s = text;(s - text < len) && (*s != '~');s++)
\r
2267 if ((c = *s) == '\n')
\r
2270 *off++ = l - text; // Save offset of start of line
\r
2271 line++; // Bump line number
\r
2272 le = l = s + 1; // Set start of line ptr
\r
2277 if // Strip orphaned spaces
\r
2281 && (*(s - 1) == '\0')
\r
2282 && (*(s + 1) != ' ')
\r
2286 else if (c == ' ')
\r
2289 USL_MeasureString(l,&w,&h);
\r
2290 if (w >= WindowW) // If string width exceeds window,
\r
2292 *s = c; // Replace null char with proper char
\r
2293 *le = '\0'; // Go back to last line end
\r
2294 *off++ = l - text; // Save offset of start of line
\r
2295 line++; // Bump line number
\r
2296 l = s = le + 1; // Start next time through after last line end
\r
2300 *s = c; // Width still ok - put char back
\r
2301 le = s; // And save ptr to last ok end of word
\r
2312 ///////////////////////////////////////////////////////////////////////////
\r
2314 // USL_DrawHelp() - Draws helptext in the current window
\r
2316 ///////////////////////////////////////////////////////////////////////////
\r
2318 USL_DrawHelp(char far *text,word start,word end,word line,word h,word far *lp)
\r
2321 py = WindowY + (line * h);
\r
2322 for (lp += start;start < end;start++,px = WindowX + 4,py += h)
\r
2323 USL_DrawString(text + *lp++);
\r
2326 ///////////////////////////////////////////////////////////////////////////
\r
2328 // USL_DoHelp() - Formats and displays the specified help
\r
2330 ///////////////////////////////////////////////////////////////////////////
\r
2332 USL_DoHelp(memptr text,long len)
\r
2343 base,srcbase,destbase;
\r
2345 longword lasttime;
\r
2349 USL_ShowHelp("Arrow Keys Move / Escape Exits");
\r
2350 fontcolor = F_BLACK;
\r
2352 US_SaveWindow(&wr);
\r
2353 US_RestoreWindow(&BottomWindow);
\r
2357 VW_UpdateScreen();
\r
2359 lines = USL_FormatHelp((char far *)text,len);
\r
2360 USL_MeasureString("",&w,&h);
\r
2361 page = WindowH / h;
\r
2365 IN_ClearKeysDown();
\r
2370 waitkey = sc_None;
\r
2375 while (TimeCount - lasttime < 5)
\r
2377 lasttime = TimeCount;
\r
2385 else if (scroll == +1)
\r
2394 num = (page < lines)? page : lines;
\r
2399 if (grmode == CGAGR)
\r
2402 base = bufferofs + panadjust + (WindowX / pixdiv);
\r
2404 else if (grmode == EGAGR)
\r
2406 VWB_Bar(WindowX,WindowY + (loc * h),WindowW,num * h,WHITE);
\r
2407 USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);
\r
2410 base = displayofs + panadjust + (WindowX / pixdiv);
\r
2412 else if (grmode == VGAGR)
\r
2417 srcbase = base + ylookup[WindowY + h];
\r
2418 destbase = base + ylookup[WindowY];
\r
2419 if (grmode == EGAGR)
\r
2424 VW_ScreenToScreen(srcbase,destbase,WindowW / pixdiv,
\r
2429 i = WindowY + (h * (page - 1));
\r
2430 srcbase = base + ylookup[i - h];
\r
2431 destbase = base + ylookup[i];
\r
2432 base = ylookup[h];
\r
2433 for (i = page - 1;i;i--,srcbase -= base,destbase -= base)
\r
2434 VW_ScreenToScreen(srcbase,destbase,WindowW / pixdiv,h);
\r
2436 if (grmode == CGAGR)
\r
2438 VWB_Bar(WindowX,WindowY + (loc * h),WindowW,num * h,WHITE);
\r
2439 USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);
\r
2440 VW_UpdateScreen();
\r
2442 else if (grmode == EGAGR)
\r
2444 base = panadjust + (WindowX / pixdiv) +
\r
2445 ylookup[WindowY + (loc * h)];
\r
2446 VW_ScreenToScreen(base + bufferofs,base + displayofs,
\r
2447 WindowW / pixdiv,h);
\r
2453 USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);
\r
2454 VW_UpdateScreen();
\r
2462 while (IN_KeyDown(waitkey))
\r
2464 waitkey = sc_None;
\r
2466 IN_ReadCursor(&info);
\r
2476 else if (info.y > 0)
\r
2478 if (cur + page < lines)
\r
2485 else if (info.button0 || info.button1)
\r
2487 else if (IN_KeyDown(LastScan))
\r
2502 case sc_DownArrow:
\r
2503 if (cur + page < lines)
\r
2516 waitkey = sc_PgUp;
\r
2519 if (cur + page < lines)
\r
2522 if (cur + page >= lines)
\r
2523 cur = lines - page;
\r
2526 waitkey = sc_PgDn;
\r
2531 IN_ClearKeysDown();
\r
2534 IN_ReadCursor(&info);
\r
2535 } while (info.button0 || info.button1);
\r
2539 VW_UpdateScreen();
\r
2540 US_RestoreWindow(&wr);
\r
2543 ///////////////////////////////////////////////////////////////////////////
\r
2545 // USL_CtlHButtonCustom() - The custom routine for all of the help buttons
\r
2547 ///////////////////////////////////////////////////////////////////////////
\r
2549 USL_CtlHButtonCustom(UserCall call,word i,word n)
\r
2554 if (call != uic_Hit)
\r
2557 ip = &TheItems[i][n];
\r
2558 if (ip->sel & ui_Disabled)
\r
2561 ip->sel |= ui_Selected;
\r
2562 USL_DrawItem(i,n);
\r
2564 USL_ClearBottom();
\r
2566 fontcolor = F_SECONDCOLOR;
\r
2567 USL_ShowHelp("Loading & Formatting Text...");
\r
2568 VW_UpdateScreen();
\r
2570 #ifdef HELPTEXTLINKED // Ugly hack because of lack of disk space...
\r
2572 extern char far gametext,far context,far story;
\r
2589 MM_GetPtr(&dupe,5000);
\r
2590 _fmemcpy((char far *)dupe,buf,5000);
\r
2592 USL_DoHelp(dupe,5000);
\r
2594 MM_FreePtr(&dupe);
\r
2596 MM_FreePtr(&LineOffsets);
\r
2608 name = "GAMETEXT."EXTENSION;
\r
2611 name = "CONTEXT."EXTENSION;
\r
2614 name = "STORY."EXTENSION;
\r
2617 Quit("Bad help button number");
\r
2620 if ((file = open(name,O_RDONLY | O_TEXT)) == -1)
\r
2621 USL_HandleError(errno);
\r
2624 len = filelength(file);
\r
2625 MM_GetPtr(&buf,len);
\r
2627 if (CA_FarRead(file,(byte far *)buf,len))
\r
2628 USL_DoHelp(buf,len);
\r
2630 USL_HandleError(errno);
\r
2637 MM_FreePtr(&LineOffsets);
\r
2641 fontcolor = F_BLACK;
\r
2643 ip->sel &= ~ui_Selected;
\r
2644 USL_DrawItem(i,n);
\r
2649 ///////////////////////////////////////////////////////////////////////////
\r
2651 // USL_CtlDButtonCustom() - The custom routine for all of the disk buttons.
\r
2652 // Sets up the bottom area of the window with the appropriate buttons
\r
2654 ///////////////////////////////////////////////////////////////////////////
\r
2656 USL_CtlDButtonCustom(UserCall call,word i,word n)
\r
2661 if (call != uic_Hit)
\r
2664 ip = &TheItems[i][n];
\r
2665 if (ip->sel & ui_Disabled)
\r
2668 USL_ClearBottom();
\r
2671 TheItems[i + 1] = ip = n? CtlDEPanels : CtlDLSPanels;
\r
2672 while (ip && (ip->type != uii_Bad))
\r
2674 USL_DrawItem(i + 1,j++);
\r
2681 ///////////////////////////////////////////////////////////////////////////
\r
2683 // USL_DLSRect() - Draw the rectangle for the save game names
\r
2685 ///////////////////////////////////////////////////////////////////////////
\r
2687 USL_DLSRect(UserItem *ip)
\r
2691 r.ul.x = ip->r.lr.x + 40 + 2;
\r
2692 r.ul.y = ip->r.ul.y + 2;
\r
2693 r.lr.x = WindowX + WindowW - 8 - 2;
\r
2694 r.lr.y = ip->r.lr.y - 2;
\r
2696 VWB_Bar(r.ul.x,r.ul.y,r.lr.x - r.ul.x,r.lr.y - r.ul.y,WHITE);
\r
2698 VWB_Hlin(r.ul.x,r.lr.x,r.ul.y,BLACK);
\r
2699 VWB_Hlin(r.ul.x,r.lr.x,r.lr.y,BLACK);
\r
2700 VWB_Vlin(r.ul.y,r.lr.y,r.ul.x,BLACK);
\r
2701 VWB_Vlin(r.ul.y,r.lr.y,r.lr.x,BLACK);
\r
2709 ///////////////////////////////////////////////////////////////////////////
\r
2711 // USL_CtlDLButtonCustom() - The load game custom routine
\r
2713 ///////////////////////////////////////////////////////////////////////////
\r
2715 USL_CtlDLButtonCustom(UserCall call,word i,word n)
\r
2718 msg[MaxGameName + 12];
\r
2725 // DEBUG - deal with warning user about loading a game causing abort
\r
2727 game = &Games[n / 2];
\r
2728 ip = &TheItems[i][n];
\r
2736 fontcolor = game->present? F_BLACK : F_FIRSTCOLOR;
\r
2737 USL_DrawString(game->present? game->name : "Empty");
\r
2738 fontcolor = F_BLACK;
\r
2742 if (ip->sel & ui_Disabled)
\r
2746 filename = USL_GiveSaveName(n / 2);
\r
2748 US_SaveWindow(&wr);
\r
2749 US_CenterWindow(30,3);
\r
2750 strcpy(msg,"Loading `");
\r
2751 strcat(msg,game->name);
\r
2753 US_PrintCentered(msg);
\r
2755 VW_UpdateScreen();
\r
2758 if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)
\r
2760 if (read(file,game,sizeof(*game)) == sizeof(*game))
\r
2763 if (!USL_LoadGame(file))
\r
2764 USL_HandleError(err = errno);
\r
2767 USL_HandleError(err = errno);
\r
2771 USL_HandleError(err = errno);
\r
2775 loadedgame = true;
\r
2776 game->present = true;
\r
2782 US_RestoreWindow(&wr);
\r
2790 ///////////////////////////////////////////////////////////////////////////
\r
2792 // USL_CtlDSButtonCustom() - The save game custom routine
\r
2794 ///////////////////////////////////////////////////////////////////////////
\r
2796 USL_CtlDSButtonCustom(UserCall call,word i,word n)
\r
2807 if (call != uic_Hit)
\r
2810 game = &Games[n / 2];
\r
2811 ip = &TheItems[i][n];
\r
2812 if (ip->sel & ui_Disabled)
\r
2816 fontcolor = F_SECONDCOLOR;
\r
2817 USL_ShowHelp("Enter Game Name / Escape Aborts");
\r
2818 fontcolor = F_BLACK;
\r
2820 r = USL_DLSRect(ip - 1);
\r
2821 ok = US_LineInput(px,py,game->name,game->present? game->name : nil,true,
\r
2822 MaxGameName,r.lr.x - r.ul.x - 8);
\r
2823 if (!strlen(game->name))
\r
2824 strcpy(game->name,"Untitled");
\r
2827 US_SaveWindow(&wr);
\r
2828 US_CenterWindow(10,3);
\r
2829 US_PrintCentered("Saving");
\r
2831 VW_UpdateScreen();
\r
2834 filename = USL_GiveSaveName(n / 2);
\r
2836 file = open(filename,O_CREAT | O_BINARY | O_WRONLY,
\r
2837 S_IREAD | S_IWRITE | S_IFREG);
\r
2840 if (write(file,game,sizeof(*game)) == sizeof(*game))
\r
2843 ok = USL_SaveGame(file);
\r
2845 USL_HandleError(err = errno);
\r
2848 USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));
\r
2852 USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));
\r
2861 US_RestoreWindow(&wr);
\r
2862 USL_DoHit(i - 1,0);
\r
2863 VW_UpdateScreen();
\r
2866 if (!game->present)
\r
2867 game->present = ok;
\r
2871 GameIsDirty = false;
\r
2872 (ip - 1)->sel &= ~ui_Disabled;
\r
2875 USL_DrawItem(i,n - 1);
\r
2876 // USL_CtlDLButtonCustom(uic_Draw,i,n - 1);
\r
2881 ///////////////////////////////////////////////////////////////////////////
\r
2883 // USL_CtlSButtonCustom() - The custom routine for all of the sound buttons
\r
2885 ///////////////////////////////////////////////////////////////////////////
\r
2887 USL_CtlSButtonCustom(UserCall call,word i,word n)
\r
2892 if (call != uic_Hit)
\r
2895 ip = &TheItems[i][n];
\r
2896 if (ip->sel & ui_Disabled)
\r
2899 USL_ClearBottom();
\r
2901 if (n == sdm_SoundSource)
\r
2904 TheItems[i + 1] = ip = CtlSSSPanels;
\r
2905 while (ip && (ip->type != uii_Bad))
\r
2907 USL_DrawItem(i + 1,j++);
\r
2912 TheItems[i + 1] = nil;
\r
2917 ///////////////////////////////////////////////////////////////////////////
\r
2919 // USL_CtlPButtonCustom() - The custom routine for all of the start game btns
\r
2921 ///////////////////////////////////////////////////////////////////////////
\r
2923 USL_CtlPButtonCustom(UserCall call,word i,word n)
\r
2928 if (call != uic_Hit)
\r
2931 ip = &TheItems[i][n];
\r
2932 if (ip->sel & ui_Disabled)
\r
2935 USL_ClearBottom();
\r
2938 TheItems[i + 1] = ip = n? CtlPRPanels : CtlPSPanels;
\r
2939 while (ip && (ip->type != uii_Bad))
\r
2941 USL_DrawItem(i + 1,j++);
\r
2948 ///////////////////////////////////////////////////////////////////////////
\r
2950 // USL_GiveAbortWarning() - Draws a string that warns the user that an
\r
2951 // action they're about to take will abort the game in progress
\r
2953 ///////////////////////////////////////////////////////////////////////////
\r
2955 USL_GiveAbortWarning(void)
\r
2962 US_SaveWindow(&wr);
\r
2963 US_RestoreWindow(&BottomWindow);
\r
2967 VWB_Bar(WindowX,WindowY,WindowW,30,WHITE);
\r
2968 fontcolor = F_SECONDCOLOR;
\r
2969 US_CPrint("Warning! If you do this, you'll");
\r
2970 US_CPrint("abort the current game.");
\r
2971 fontcolor = F_BLACK;
\r
2973 US_RestoreWindow(&wr);
\r
2976 ///////////////////////////////////////////////////////////////////////////
\r
2978 // USL_CtlPSButtonCustom() - The custom routine for the start game button
\r
2980 ///////////////////////////////////////////////////////////////////////////
\r
2982 USL_CtlPSButtonCustom(UserCall call,word i,word n)
\r
2987 i++; // Shut the compiler up
\r
2995 restartgame = gd_Normal;
\r
2998 restartgame = gd_Easy;
\r
3001 restartgame = gd_Hard;
\r
3004 if (restartgame && ingame && USL_ResetGame)
\r
3009 USL_GiveAbortWarning();
\r
3019 ///////////////////////////////////////////////////////////////////////////
\r
3021 // USL_CtlPRButtonCustom() - The custom routine for the resume game button
\r
3023 ///////////////////////////////////////////////////////////////////////////
\r
3025 USL_CtlPRButtonCustom(UserCall call,word i,word n)
\r
3027 if (call != uic_Hit)
\r
3030 i++,n++; // Shut the compiler up
\r
3031 ResumeGame = true;
\r
3035 ///////////////////////////////////////////////////////////////////////////
\r
3037 // USL_CtlDEButtonCustom() - The custom routine for the exit to DOS button
\r
3039 ///////////////////////////////////////////////////////////////////////////
\r
3041 USL_CtlDEButtonCustom(UserCall call,word i,word n)
\r
3046 i++,n++; // Shut the compiler up
\r
3054 USL_GiveAbortWarning();
\r
3062 ///////////////////////////////////////////////////////////////////////////
\r
3064 // USL_CtlCButtonCustom() - The custom routine for all of the control
\r
3067 ///////////////////////////////////////////////////////////////////////////
\r
3069 USL_CtlCButtonCustom(UserCall call,word i,word n)
\r
3075 if (call != uic_Hit)
\r
3078 ip = &TheItems[i][n];
\r
3079 if (ip->sel & ui_Disabled)
\r
3082 USL_ClearBottom();
\r
3083 if (n == 0) // Keyboard
\r
3085 TheItems[i + 1] = ip = CtlCKbdPanels;
\r
3086 p = CtlCKbdPanels[2].r.lr;
\r
3087 VWB_DrawPic(p.x,p.y,CTL_DIRSPIC);
\r
3090 TheItems[i + 1] = ip = CtlCJoyPanels;
\r
3093 while (ip && (ip->type != uii_Bad))
\r
3095 USL_DrawItem(i + 1,j++);
\r
3102 ///////////////////////////////////////////////////////////////////////////
\r
3104 // USL_HitHotKey() - After a hotkey was hit, move the cursor to the first
\r
3105 // selected item in the group after the group containing the item
\r
3106 // holding the hotkey
\r
3108 ///////////////////////////////////////////////////////////////////////////
\r
3110 USL_HitHotKey(int i,int n)
\r
3114 if (ip = TheItems[++i])
\r
3116 if ((n = USL_FindDown(TheItems[i])) == -1)
\r
3119 CursorX = ip->r.lr.x - 8;
\r
3120 CursorY = ip->r.lr.y - 8;
\r
3125 ///////////////////////////////////////////////////////////////////////////
\r
3127 // USL_CheckScan() - Checks to see if the scancode in LastScan corresponds
\r
3128 // to anything in the list of useritems. If so, selects the item.
\r
3130 ///////////////////////////////////////////////////////////////////////////
\r
3132 USL_CheckScan(word *ci,word *cn)
\r
3140 #if 1 // DEBUG - probably kill this code
\r
3141 // Use 1..? for the items across the top row
\r
3142 if (TheItems[1] && !IN_KeyDown(sc_RShift))
\r
3144 for (i = 0,ip = TheItems[1];(ip->type != uii_Bad) && (i < 9);i++,ip++)
\r
3146 for (n = 0;n < i;n++)
\r
3148 if (LastScan == 2 + n) // Numbers from 1..9
\r
3150 if (!(TheItems[1][n].sel & ui_Disabled))
\r
3152 LastScan = sc_None;
\r
3160 // Use Alt-1..6 for the items in the leftmost column
\r
3161 if (IN_KeyDown(sc_RShift))
\r
3164 if (n < 6) // Numbers from 1..6
\r
3167 LastScan = sc_None;
\r
3173 // Check normal hotkeys for the leftmost column
\r
3174 for (i = 0;CtlPanels[i].type != uii_Bad;i++)
\r
3176 if (CtlPanels[i].key == LastScan)
\r
3178 LastScan = sc_None;
\r
3182 USL_HitHotKey(0,i);
\r
3187 // Check normal hotkeys for the top row
\r
3188 for (i = 0;i < 6;i++)
\r
3190 for (n = 0,ip = CtlPanels2[i];ip && ip->type != uii_Bad;n++,ip++)
\r
3192 if ((ip->key == LastScan) && !(ip->sel & ui_Disabled))
\r
3194 LastScan = sc_None;
\r
3199 USL_HitHotKey(1,n);
\r
3207 ///////////////////////////////////////////////////////////////////////////
\r
3209 // USL_SetUpCtlPanel() - Sets the states of the UserItems to reflect the
\r
3210 // values of all the appropriate variables
\r
3212 ///////////////////////////////////////////////////////////////////////////
\r
3214 USL_SetUpCtlPanel(void)
\r
3218 GameIsDirty = ingame;
\r
3220 // Set up restart game
\r
3221 USL_TurnOff(CtlPPanels);
\r
3222 CtlPPanels[0].sel = ingame? ui_Normal : ui_Selected;
\r
3223 CtlPPanels[1].sel = ingame? ui_Selected : ui_Disabled;
\r
3225 // Set up disk stuff - default to load/save game
\r
3226 USL_TurnOff(CtlDPanels);
\r
3227 CtlDPanels[0].sel = ui_Selected;
\r
3229 // Set up load/save buttons
\r
3230 USL_TurnOff(CtlDLSPanels);
\r
3231 for (i = 0;i < MaxSaveGames;i++)
\r
3233 if (!Games[i].present)
\r
3234 CtlDLSPanels[i * 2].sel = ui_Disabled;
\r
3236 CtlDLSPanels[(i * 2) + 1].sel = ui_Disabled;
\r
3239 // Set up Controls
\r
3240 USL_TurnOff(CtlCPanels);
\r
3241 CtlCPanels[1].sel = JoysPresent[0]? ui_Normal : ui_Disabled;
\r
3242 CtlCPanels[2].sel = JoysPresent[1]? ui_Normal : ui_Disabled;
\r
3243 if (Controls[0] == ctrl_Keyboard)
\r
3246 i = (Controls[0] == ctrl_Joystick1)? 1 : 2;
\r
3247 CtlCPanels[i].sel |= ui_Selected;
\r
3248 if (JoysPresent[1] && !JoysPresent[0])
\r
3249 CtlCPanels[2].key = sc_F4;
\r
3251 CtlCPanels[1].key = sc_F4;
\r
3253 // Set up Keyboard
\r
3254 for (i = 0;i < 10;i++)
\r
3255 CtlCKbdPanels[i].text = IN_GetScanName(*(KeyMaps[i]));
\r
3258 USL_TurnOff(CtlSPanels);
\r
3259 CtlSPanels[sdm_AdLib].sel = AdLibPresent? ui_Normal : ui_Disabled;
\r
3260 #if 0 // DEBUG - hack because no space for digitized sounds on Keen Dreams
\r
3261 CtlSPanels[sdm_SoundBlaster].sel =
\r
3262 SoundBlasterPresent? ui_Normal : ui_Disabled;
\r
3263 CtlSPanels[sdm_SoundSource].sel =
\r
3264 SoundSourcePresent? ui_Normal : ui_Disabled;
\r
3266 CtlSPanels[sdm_SoundBlaster].sel = ui_Disabled;
\r
3267 CtlSPanels[sdm_SoundSource].sel = ui_Disabled;
\r
3269 CtlSPanels[SoundMode].sel |= ui_Selected;
\r
3271 // Set up SoundSource
\r
3272 USL_TurnOff(CtlSSSPanels);
\r
3273 CtlSSSPanels[0].sel = ssIsTandy? ui_Selected : ui_Normal;
\r
3274 CtlSSSPanels[1].sel = (ssPort == 2)? ui_Selected : ui_Normal;
\r
3277 USL_TurnOff(CtlMPanels);
\r
3278 CtlMPanels[smm_AdLib].sel = AdLibPresent? ui_Normal : ui_Disabled;
\r
3279 CtlMPanels[MusicMode].sel |= ui_Selected;
\r
3282 ///////////////////////////////////////////////////////////////////////////
\r
3284 // USL_TearDownCtlPanel() - Given the state of the control panel, sets the
\r
3285 // modes and values as appropriate
\r
3287 ///////////////////////////////////////////////////////////////////////////
\r
3289 USL_TearDownCtlPanel(void)
\r
3293 i = USL_FindDown(CtlCPanels);
\r
3296 i = i? (i == 1? ctrl_Joystick1 : ctrl_Joystick2) : ctrl_Keyboard;
\r
3297 IN_SetControlType(0,i);
\r
3300 CtlCPanels[1].key = CtlCPanels[2].key = sc_None;
\r
3302 i = USL_FindDown(CtlSPanels);
\r
3304 SD_SetSoundMode(i);
\r
3306 ssIsTandy = CtlSSSPanels[0].sel & ui_Selected;
\r
3307 ssPort = (CtlSSSPanels[1].sel & ui_Selected)? 2 : 1;
\r
3309 i = USL_FindDown(CtlMPanels);
\r
3312 SD_SetMusicMode(i);
\r
3316 US_CenterWindow(20,8);
\r
3317 US_CPrint("Loading");
\r
3319 fontcolor = F_SECONDCOLOR;
\r
3320 US_CPrint("Sounds");
\r
3321 fontcolor = F_BLACK;
\r
3323 VW_UpdateScreen();
\r
3325 CA_LoadAllSounds();
\r
3330 ///////////////////////////////////////////////////////////////////////////
\r
3332 // US_ControlPanel() - This is the main routine for the control panel
\r
3334 ///////////////////////////////////////////////////////////////////////////
\r
3336 US_ControlPanel(void)
\r
3338 char gamename[MaxGameName + 10 + 1];
\r
3341 buttondown,inrect;
\r
3346 longword lasttime;
\r
3352 if (c == sc_Escape) // Map escape from game to Exit to DOS
\r
3356 for (i = CONTROLS_LUMP_START;i <= CONTROLS_LUMP_END;i++)
\r
3357 CA_MarkGrChunk(i);
\r
3358 CA_MarkGrChunk(CTL_LITTLEMASKPICM);
\r
3359 CA_MarkGrChunk(CTL_LSMASKPICM);
\r
3360 CA_CacheMarks("Options Screen");
\r
3362 USL_SetUpCtlPanel();
\r
3364 US_SetPrintRoutines(VW_MeasurePropString,VWB_DrawPropString);
\r
3365 fontcolor = F_BLACK;
\r
3367 VW_InitDoubleBuffer();
\r
3369 VWB_Bar(0,0,MaxX,MaxY,FIRSTCOLOR);
\r
3370 US_DrawWindow(8,22,30,2);
\r
3371 US_SaveWindow(&HelpWindow);
\r
3372 US_DrawWindow(8,7,30,14);
\r
3373 US_SaveWindow(&BottomWindow);
\r
3374 US_DrawWindow(8,1,30,20);
\r
3376 for (ip = CtlPanels;ip->type != uii_Bad;ip++)
\r
3377 VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,ip->picup);
\r
3380 CursorX = (8 * 8) + ((MaxX - (8 * 8)) / 2);
\r
3383 CtlPanelButton = -1;
\r
3385 USL_CheckScan(&i,&n);
\r
3386 if (CtlPanelButton == -1)
\r
3389 ResumeGame = false;
\r
3392 lastx = lasty = -1;
\r
3395 (restartgame == gd_Continue)
\r
3396 && !(done || loadedgame || ResumeGame)
\r
3399 VW_UpdateScreen();
\r
3401 buttondown = US_UpdateCursor();
\r
3402 inrect = USL_IsInRect(CursorX,CursorY,&i,&n);
\r
3407 lasttime = TimeCount;
\r
3408 FlushHelp = false;
\r
3412 if ((lasti != i) || (lastn != n))
\r
3414 // If over a Load button
\r
3417 (CtlPanelButton == 2)
\r
3419 && (TheItems[1][0].sel & ui_Selected)
\r
3420 && (Games[n / 2].present)
\r
3424 strcpy(gamename,"Load `");
\r
3425 strcat(gamename,Games[n / 2].name);
\r
3426 strcat(gamename,"'");
\r
3427 USL_ShowHelp(gamename);
\r
3430 USL_ShowHelp(TheItems[i][n].help);
\r
3435 else if (lasti != (word)-1)
\r
3437 USL_ShowHelp("Select a Button");
\r
3445 userect = TheItems[i][n].r;
\r
3448 userect.ul.x = CursorX;
\r
3449 userect.ul.y = CursorY;
\r
3450 userect.lr = userect.ul;
\r
3453 if (IN_KeyDown(sc_UpArrow))
\r
3455 USL_FindRect(userect,motion_None,motion_Up);
\r
3456 buttondown = false;
\r
3457 IN_ClearKey(sc_UpArrow);
\r
3459 else if (IN_KeyDown(sc_DownArrow))
\r
3461 USL_FindRect(userect,motion_None,motion_Down);
\r
3462 buttondown = false;
\r
3463 IN_ClearKey(sc_DownArrow);
\r
3465 else if (IN_KeyDown(sc_LeftArrow))
\r
3467 USL_FindRect(userect,motion_Left,motion_None);
\r
3468 buttondown = false;
\r
3469 IN_ClearKey(sc_LeftArrow);
\r
3471 else if (IN_KeyDown(sc_RightArrow))
\r
3473 USL_FindRect(userect,motion_Right,motion_None);
\r
3474 buttondown = false;
\r
3475 IN_ClearKey(sc_RightArrow);
\r
3479 IN_KeyDown(c = sc_Return)
\r
3480 || IN_KeyDown(c = KbdDefs[0].button0)
\r
3481 || IN_KeyDown(c = KbdDefs[0].button1)
\r
3487 ip = &TheItems[hiti][hitn];
\r
3489 if ((ip->type == uii_Button) && !(ip->sel & ui_Disabled))
\r
3491 lasttime = TimeCount;
\r
3493 ip->sel |= ui_Selected;
\r
3494 USL_DrawItem(hiti,hitn);
\r
3495 VW_UpdateScreen();
\r
3497 while (TimeCount - lasttime < TickBase / 4)
\r
3499 lasttime = TimeCount;
\r
3501 ip->sel &= ~ui_Selected;
\r
3502 USL_DrawItem(hiti,hitn);
\r
3503 VW_UpdateScreen();
\r
3505 while (TimeCount - lasttime < TickBase / 4)
\r
3509 USL_DoHit(hiti,hitn);
\r
3512 else if (USL_CheckScan(&i,&n))
\r
3514 else if (buttondown && inrect && USL_TrackItem(hiti,hitn))
\r
3515 USL_DoHit(hiti,hitn);
\r
3517 if (LastScan == sc_Escape)
\r
3519 IN_ClearKey(sc_Escape);
\r
3526 if ((lastx != CursorX) || (lasty != CursorY))
\r
3530 lasttime = TimeCount;
\r
3532 if (TimeCount - lasttime > TickBase * 10)
\r
3534 if (((TimeCount - lasttime) / TickBase) & 2)
\r
3535 fontcolor = F_SECONDCOLOR;
\r
3536 USL_ShowHelp("Press F1 for Help");
\r
3537 fontcolor = F_BLACK;
\r
3543 USL_TearDownCtlPanel();
\r
3545 if (restartgame && USL_ResetGame)
\r
3554 US_CenterWindow(20,3);
\r
3555 fontcolor = F_SECONDCOLOR;
\r
3556 US_PrintCentered("Now Exiting to DOS...");
\r
3557 fontcolor = F_BLACK;
\r
3558 VW_UpdateScreen();
\r
3566 // High score routines
\r
3568 ///////////////////////////////////////////////////////////////////////////
\r
3570 // US_DisplayHighScores() - Assumes that double buffering has been started.
\r
3571 // If passed a -1 will just display the high scores, but if passed
\r
3572 // a non-negative number will display that entry in red and let the
\r
3573 // user type in a name
\r
3575 ///////////////////////////////////////////////////////////////////////////
\r
3577 US_DisplayHighScores(int which)
\r
3579 char buffer[16],*str;
\r
3585 US_CenterWindow(30,MaxScores + (MaxScores / 2));
\r
3587 x = WindowX + (WindowW / 2);
\r
3588 US_Print(" Name");
\r
3590 US_Print("Score");
\r
3592 US_Print("Done\n\n");
\r
3595 for (i = WindowX;i < WindowX + WindowW;i += 8)
\r
3596 VWB_DrawTile8M(i,WindowY + 8,10);
\r
3597 VWB_DrawTile8M(WindowX - 8,WindowY + 8,9);
\r
3598 VWB_DrawTile8M(WindowX + WindowW,WindowY + 8,11);
\r
3600 for (i = 0,s = Scores;i < MaxScores;i++,s++)
\r
3602 fontcolor = (i == which)? F_SECONDCOLOR : F_BLACK;
\r
3607 if (strlen(s->name))
\r
3608 US_Print(s->name);
\r
3615 PrintX = x + (7 * 8);
\r
3616 ultoa(s->score,buffer,10);
\r
3617 for (str = buffer;*str;str++)
\r
3618 *str = *str + (129 - '0'); // Used fixed-width numbers (129...)
\r
3619 USL_MeasureString(buffer,&w,&h);
\r
3625 US_PrintUnsigned(s->completed);
\r
3634 fontcolor = F_SECONDCOLOR;
\r
3638 strcpy(Scores[which].name,"");
\r
3639 US_LineInput(PrintX,PrintY,Scores[which].name,nil,true,MaxHighName,
\r
3640 (WindowW / 2) - 8);
\r
3642 fontcolor = F_BLACK;
\r
3644 VW_UpdateScreen();
\r
3647 ///////////////////////////////////////////////////////////////////////////
\r
3649 // US_CheckHighScore() - Checks gamestate to see if the just-ended game
\r
3650 // should be entered in the high score list. If so, lets the user
\r
3651 // enter their name
\r
3653 ///////////////////////////////////////////////////////////////////////////
\r
3655 US_CheckHighScore(long score,word other)
\r
3659 HighScore myscore;
\r
3661 strcpy(myscore.name,"");
\r
3662 myscore.score = score;
\r
3663 myscore.completed = other;
\r
3665 for (i = 0,n = -1;i < MaxScores;i++)
\r
3669 (myscore.score > Scores[i].score)
\r
3671 (myscore.score == Scores[i].score)
\r
3672 && (myscore.completed > Scores[i].completed)
\r
3676 for (j = MaxScores;--j > i;)
\r
3677 Scores[j] = Scores[j - 1];
\r
3678 Scores[i] = myscore;
\r
3681 HighScoresDirty = true;
\r
3686 VW_InitDoubleBuffer();
\r
3687 VWB_Bar(0,0,MaxX,MaxY,FIRSTCOLOR);
\r
3689 US_DisplayHighScores(n);
\r
3690 IN_UserInput(5 * TickBase,false);
\r