-/* Catacomb Armageddon Source Code\r
- * Copyright (C) 1993-2014 Flat Rock Software\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License along\r
- * with this program; if not, write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\r
- */\r
-\r
-//\r
-// ID Engine\r
-// ID_US.c - User Manager\r
-// v1.0d1\r
-// By Jason Blochowiak\r
-//\r
-\r
-//\r
-// This module handles dealing with user input & feedback\r
-//\r
-// Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,\r
-// and Refresh Mgrs, Memory Mgr for background save/restore\r
-//\r
-// Globals:\r
-// ingame - Flag set by game indicating if a game is in progress\r
-// abortgame - Flag set if the current game should be aborted (if a load\r
-// game fails)\r
-// loadedgame - Flag set if a game was loaded\r
-// abortprogram - Normally nil, this points to a terminal error message\r
-// if the program needs to abort\r
-// restartgame - Normally set to gd_Continue, this is set to one of the\r
-// difficulty levels if a new game should be started\r
-// PrintX, PrintY - Where the User Mgr will print (global coords)\r
-// WindowX,WindowY,WindowW,WindowH - The dimensions of the current\r
-// window\r
-//\r
-\r
-// DEBUG - handle LPT3 for Sound Source\r
-\r
-#include "ID_HEADS.H"\r
-\r
-#define CTL_M_ADLIBUPPIC CTL_S_ADLIBUPPIC\r
-#define CTL_M_ADLIBDNPIC CTL_S_ADLIBDNPIC\r
-\r
-#pragma hdrstop\r
-\r
-#pragma warn -pia\r
-\r
-#define MaxX 320\r
-#define MaxY 200\r
-\r
-#define MaxHelpLines 500\r
-\r
-#define MaxHighName 57\r
-#define MaxScores 10\r
-typedef struct\r
- {\r
- char name[MaxHighName + 1];\r
- long score;\r
- word completed;\r
- } HighScore;\r
-\r
-#define MaxGameName 32\r
-#define MaxSaveGames 7\r
-typedef struct\r
- {\r
- char signature[4];\r
- boolean present;\r
- char name[MaxGameName + 1];\r
- } SaveGame;\r
-\r
-// Hack import for TED launch support\r
-extern boolean tedlevel;\r
-extern word tedlevelnum;\r
-extern void TEDDeath(void);\r
-static char *ParmStrings[] = {"TEDLEVEL","NOWAIT",""};\r
-\r
-\r
-// Global variables\r
- boolean ingame,abortgame,loadedgame;\r
- char *abortprogram;\r
- GameDiff restartgame = gd_Continue;\r
- word PrintX,PrintY;\r
- word WindowX,WindowY,WindowW,WindowH;\r
-\r
-// Internal variables\r
-static boolean US_Started;\r
-static boolean GameIsDirty,\r
- HighScoresDirty,\r
- QuitToDos,\r
- ResumeGame,\r
- NoWait;\r
-\r
-static memptr LineOffsets;\r
-\r
-static boolean Button0,Button1,\r
- CursorBad;\r
-static int CursorX,CursorY;\r
-\r
-static void (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,\r
- (*USL_DrawString)(char far *) = VWB_DrawPropString;\r
-\r
-static boolean (*USL_SaveGame)(int),(*USL_LoadGame)(int);\r
-static void (*USL_ResetGame)(void);\r
-static SaveGame Games[MaxSaveGames];\r
-static HighScore Scores[MaxScores] =\r
- {\r
- {"Sir Lancelot",500},\r
- {"",0},\r
- {"",0},\r
- {"",0},\r
- {"",0},\r
- {"",0},\r
- {"",0},\r
- {"",0},\r
- {"",0},\r
- {"",0}\r
- };\r
-\r
-// Internal routines\r
-\r
-// Public routines\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed\r
-// from DOS.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#pragma warn -par\r
-#pragma warn -rch\r
-int\r
-USL_HardError(word errval,int ax,int bp,int si)\r
-{\r
-#define IGNORE 0\r
-#define RETRY 1\r
-#define ABORT 2\r
-extern void ShutdownId(void);\r
-\r
-static char buf[32];\r
-static WindowRec wr;\r
-static boolean oldleavedriveon;\r
- int di;\r
- char c,*s,*t;\r
-\r
-\r
- di = _DI;\r
-\r
- oldleavedriveon = LeaveDriveOn;\r
- LeaveDriveOn = false;\r
-\r
- if (ax < 0)\r
- s = "Device Error";\r
- else\r
- {\r
- if ((di & 0x00ff) == 0)\r
- s = "Drive ~ is Write Protected";\r
- else\r
- s = "Error on Drive ~";\r
- for (t = buf;*s;s++,t++) // Can't use sprintf()\r
- if ((*t = *s) == '~')\r
- *t = (ax & 0x00ff) + 'A';\r
- *t = '\0';\r
- s = buf;\r
- }\r
-\r
- c = peekb(0x40,0x49); // Get the current screen mode\r
- if ((c < 4) || (c == 7))\r
- goto oh_kill_me;\r
-\r
- // DEBUG - handle screen cleanup\r
-\r
- US_SaveWindow(&wr);\r
- US_CenterWindow(30,3);\r
- US_CPrint(s);\r
- US_CPrint("(R)etry or (A)bort?");\r
- VW_UpdateScreen();\r
- IN_ClearKeysDown();\r
-\r
-asm sti // Let the keyboard interrupts come through\r
-\r
- while (true)\r
- {\r
- switch (IN_WaitForASCII())\r
- {\r
- case key_Escape:\r
- case 'a':\r
- case 'A':\r
- goto oh_kill_me;\r
- break;\r
- case key_Return:\r
- case key_Space:\r
- case 'r':\r
- case 'R':\r
- US_ClearWindow();\r
- VW_UpdateScreen();\r
- US_RestoreWindow(&wr);\r
- LeaveDriveOn = oldleavedriveon;\r
- return(RETRY);\r
- break;\r
- }\r
- }\r
-\r
-oh_kill_me:\r
- abortprogram = s;\r
- ShutdownId();\r
- fprintf(stderr,"Terminal Error: %s\n",s);\r
- if (tedlevel)\r
- fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");\r
-\r
- return(ABORT);\r
-#undef IGNORE\r
-#undef RETRY\r
-#undef ABORT\r
-}\r
-#pragma warn +par\r
-#pragma warn +rch\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_GiveSaveName() - Returns a pointer to a static buffer that contains\r
-// the filename to use for the specified save game\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static char *\r
-USL_GiveSaveName(word game)\r
-{\r
-static char filename[32];\r
- char *s,*t;\r
-\r
- for (s = "SAVEGM",t = filename;*s;)\r
- *t++ = *s++;\r
- *t++ = game + '0';\r
- for (s = "."EXTENSION;*s;)\r
- *t++ = *s++;\r
- *t = '\0';\r
-\r
- return(filename);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_SetLoadSaveHooks() - Sets the routines that the User Mgr calls after\r
-// reading or writing the save game headers\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_SetLoadSaveHooks(boolean (*load)(int),boolean (*save)(int),void (*reset)(void))\r
-{\r
- USL_LoadGame = load;\r
- USL_SaveGame = save;\r
- USL_ResetGame = reset;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_ReadConfig() - Reads the configuration file, if present, and sets\r
-// things up accordingly. If it's not present, uses defaults. This file\r
-// includes the high scores.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_ReadConfig(void)\r
-{\r
- boolean gotit;\r
- int file;\r
- SDMode sd;\r
- SMMode sm;\r
- ControlType ctl;\r
-\r
- if ((file = open("CONFIG."EXTENSION,O_BINARY | O_RDONLY)) != -1)\r
- {\r
- read(file,Scores,sizeof(HighScore) * MaxScores);\r
- read(file,&sd,sizeof(sd));\r
- read(file,&sm,sizeof(sm));\r
- read(file,&ctl,sizeof(ctl));\r
- read(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));\r
- close(file);\r
-\r
- HighScoresDirty = false;\r
- gotit = true;\r
- }\r
- else\r
- {\r
- sd = sdm_Off;\r
- sm = smm_Off;\r
- ctl = ctrl_Keyboard;\r
-\r
- gotit = false;\r
- HighScoresDirty = true;\r
- }\r
-\r
- SD_Default(gotit,sd,sm);\r
- IN_Default(gotit,ctl);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_WriteConfig() - Writes out the current configuration, including the\r
-// high scores.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_WriteConfig(void)\r
-{\r
- int file;\r
-\r
- file = open("CONFIG."EXTENSION,O_CREAT | O_BINARY | O_WRONLY,\r
- S_IREAD | S_IWRITE | S_IFREG);\r
- if (file != -1)\r
- {\r
- write(file,Scores,sizeof(HighScore) * MaxScores);\r
- write(file,&SoundMode,sizeof(SoundMode));\r
- write(file,&MusicMode,sizeof(MusicMode));\r
- write(file,&(Controls[0]),sizeof(Controls[0]));\r
- write(file,&(KbdDefs[0]),sizeof(KbdDefs[0]));\r
- close(file);\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CheckSavedGames() - Checks to see which saved games are present\r
-// & valid\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_CheckSavedGames(void)\r
-{\r
- boolean ok;\r
- char *filename;\r
- word i;\r
- int file;\r
- SaveGame *game;\r
-\r
- USL_SaveGame = 0;\r
- USL_LoadGame = 0;\r
-\r
- for (i = 0,game = Games;i < MaxSaveGames;i++,game++)\r
- {\r
- filename = USL_GiveSaveName(i);\r
- ok = false;\r
- if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)\r
- {\r
- if\r
- (\r
- (read(file,game,sizeof(*game)) == sizeof(*game))\r
- && (!strcmp(game->signature,EXTENSION))\r
- )\r
- ok = true;\r
-\r
- close(file);\r
- }\r
-\r
- if (ok)\r
- game->present = true;\r
- else\r
- {\r
- strcpy(game->signature,EXTENSION);\r
- game->present = false;\r
- strcpy(game->name,"Empty");\r
- }\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_Startup() - Starts the User Mgr\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_Startup(void)\r
-{\r
- if (US_Started)\r
- return;\r
-\r
- harderr(USL_HardError); // Install the fatal error handler\r
-\r
- US_InitRndT(true); // Initialize the random number generator\r
-\r
- USL_ReadConfig(); // Read config file\r
-\r
- US_Started = true;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_Setup() - Does the disk access part of the User Mgr's startup\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_Setup(void)\r
-{\r
- USL_CheckSavedGames(); // Check which saved games are present\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_Shutdown() - Shuts down the User Mgr\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_Shutdown(void)\r
-{\r
- if (!US_Started)\r
- return;\r
-\r
- if (!abortprogram)\r
- USL_WriteConfig();\r
-\r
- US_Started = false;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_CheckParm() - checks to see if a string matches one of a set of\r
-// strings. The check is case insensitive. The routine returns the\r
-// index of the string that matched, or -1 if no matches were found\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-int\r
-US_CheckParm(char *parm,char **strings)\r
-{\r
- char cp,cs,\r
- *p,*s;\r
- int i;\r
-\r
- while (!isalpha(*parm)) // Skip non-alphas\r
- parm++;\r
-\r
- for (i = 0;*strings && **strings;i++)\r
- {\r
- for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)\r
- {\r
- cs = *s++;\r
- if (!cs)\r
- return(i);\r
- cp = *p++;\r
-\r
- if (isupper(cs))\r
- cs = tolower(cs);\r
- if (isupper(cp))\r
- cp = tolower(cp);\r
- }\r
- }\r
- return(-1);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_ScreenDraw() - Draws a chunk of the text screen (called only by\r
-// US_TextScreen())\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_ScreenDraw(word x,word y,char *s,byte attr)\r
-{\r
- byte far *screen;\r
-\r
- screen = MK_FP(0xb800,(x * 2) + (y * 80 * 2));\r
- while (*s)\r
- {\r
- *screen++ = *s++;\r
- *screen++ = attr;\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_ClearTextScreen() - Makes sure the screen is in text mode, clears it,\r
-// and moves the cursor to the leftmost column of the bottom line\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_ClearTextScreen(void)\r
-{\r
- // Set to 80x25 color text mode\r
- _AL = 3; // Mode 3\r
- _AH = 0x00;\r
- geninterrupt(0x10);\r
-\r
- // Use BIOS to move the cursor to the bottom of the screen\r
- _AH = 0x0f;\r
- geninterrupt(0x10); // Get current video mode into _BH\r
- _DL = 0; // Lefthand side of the screen\r
- _DH = 24; // Bottom row\r
- _AH = 0x02;\r
- geninterrupt(0x10);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_TextScreen() - Puts up the startup text screen\r
-// Note: These are the only User Manager functions that can be safely called\r
-// before the User Mgr has been started up\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_TextScreen(void)\r
-{\r
- word i,n,\r
- sx,sy;\r
-extern char far introscn;\r
-\r
- USL_ClearTextScreen();\r
-\r
- _fmemcpy(MK_FP(0xb800,0),7 + &introscn,80 * 25 * 2);\r
-\r
- // Check for TED launching here\r
- for (i = 1;i < _argc;i++)\r
- {\r
- n = US_CheckParm(_argv[i],ParmStrings);\r
- if (n == 0)\r
- {\r
- tedlevelnum = atoi(_argv[i + 1]);\r
- if (tedlevelnum >= 0)\r
- {\r
- tedlevel = true;\r
- return;\r
- }\r
- else\r
- break;\r
- }\r
- else if (n == 1)\r
- {\r
- NoWait = true;\r
- return;\r
- }\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_Show() - Changes the appearance of one of the fields on the text\r
-// screen. Possibly adds a checkmark in front of it and highlights it\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_Show(word x,word y,word w,boolean show,boolean hilight)\r
-{\r
- byte far *screen;\r
-\r
- screen = MK_FP(0xb800,((x - 1) * 2) + (y * 80 * 2));\r
- *screen++ = show? 251 : ' '; // Checkmark char or space\r
- *screen = 0x48;\r
- if (show && hilight)\r
- {\r
- for (w++;w--;screen += 2)\r
- *screen = 0x4f;\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_ShowMem() - Right justifies a longword in one of the memory fields on\r
-// the text screen\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_ShowMem(word x,word y,long mem)\r
-{\r
- char buf[16];\r
- word i;\r
-\r
- for (i = strlen(ltoa(mem,buf,10));i < 5;i++)\r
- USL_ScreenDraw(x++,y," ",0x48);\r
- USL_ScreenDraw(x,y,buf,0x48);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_UpdateTextScreen() - Called after the ID libraries are started up.\r
-// Displays what hardware is present.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_UpdateTextScreen(void)\r
-{\r
- boolean b;\r
- byte far *screen;\r
- word i;\r
- longword totalmem;\r
-\r
- // Show video card info\r
- b = (grmode == CGAGR);\r
- USL_Show(21,7,4,(videocard >= CGAcard) && (videocard <= VGAcard),b);\r
- b = (grmode == EGAGR);\r
- USL_Show(21,8,4,(videocard >= EGAcard) && (videocard <= VGAcard),b);\r
- b = (grmode == VGAGR);\r
- USL_Show(21,9,4,videocard == VGAcard,b);\r
- if (compatability)\r
- USL_ScreenDraw(5,10,"SVGA Compatibility Mode Enabled.",0x4f);\r
-\r
- // Show input device info\r
- USL_Show(60,7,8,true,true);\r
- USL_Show(60,8,11,JoysPresent[0],true);\r
- USL_Show(60,9,11,JoysPresent[1],true);\r
- USL_Show(60,10,5,MousePresent,true);\r
-\r
- // Show sound hardware info\r
- USL_Show(21,14,11,true,SoundMode == sdm_PC);\r
- b = (SoundMode == sdm_AdLib) || (MusicMode == smm_AdLib);\r
- USL_Show(21,15,5,AdLibPresent && !SoundBlasterPresent,\r
- b && !SoundBlasterPresent);\r
- USL_Show(21,16,13,SoundBlasterPresent,\r
- SoundBlasterPresent && (b || (SoundMode == sdm_SoundBlaster)));\r
- USL_Show(21,17,13,SoundSourcePresent,SoundMode == sdm_SoundSource);\r
-\r
- // Show memory available/used\r
- USL_ShowMem(63,15,mminfo.mainmem / 1024);\r
- USL_Show(53,15,23,true,true);\r
- USL_ShowMem(63,16,mminfo.EMSmem / 1024);\r
- USL_Show(53,16,23,mminfo.EMSmem? true : false,true);\r
- USL_ShowMem(63,17,mminfo.XMSmem / 1024);\r
- USL_Show(53,17,23,mminfo.XMSmem? true : false,true);\r
- totalmem = mminfo.mainmem + mminfo.EMSmem + mminfo.XMSmem;\r
- USL_ShowMem(63,18,totalmem / 1024);\r
- screen = MK_FP(0xb800,1 + (((63 - 1) * 2) + (18 * 80 * 2)));\r
- for (i = 0;i < 13;i++,screen += 2)\r
- *screen = 0x4f;\r
-\r
- // Change Initializing... to Loading...\r
- USL_ScreenDraw(27,22," Loading... ",0x9c);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_FinishTextScreen() - After the main program has finished its initial\r
-// loading, this routine waits for a keypress and then clears the screen\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_FinishTextScreen(void)\r
-{\r
- // Change Loading... to Press a Key\r
- USL_ScreenDraw(29,22," Ready - Press a Key ",0x9a);\r
-\r
- if (!(tedlevel || NoWait))\r
- {\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
- }\r
- IN_ClearKeysDown();\r
-\r
- USL_ClearTextScreen();\r
-}\r
-\r
-// Window/Printing routines\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_SetPrintRoutines() - Sets the routines used to measure and print\r
-// from within the User Mgr. Primarily provided to allow switching\r
-// between masked and non-masked fonts\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))\r
-{\r
- USL_MeasureString = measure;\r
- USL_DrawString = print;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_Print() - Prints a string in the current window. Newlines are\r
-// supported.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_Print(char *s)\r
-{\r
- char c,*se;\r
- word w,h;\r
-\r
- while (*s)\r
- {\r
- se = s;\r
- while ((c = *se) && (c != '\n'))\r
- se++;\r
- *se = '\0';\r
-\r
- USL_MeasureString(s,&w,&h);\r
- px = PrintX;\r
- py = PrintY;\r
- USL_DrawString(s);\r
-\r
- s = se;\r
- if (c)\r
- {\r
- *se = c;\r
- s++;\r
-\r
- PrintX = WindowX;\r
- PrintY += h;\r
- }\r
- else\r
- PrintX += w;\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_PrintUnsigned() - Prints an unsigned long\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_PrintUnsigned(longword n)\r
-{\r
- char buffer[32];\r
-\r
- US_Print(ultoa(n,buffer,10));\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_PrintSigned() - Prints a signed long\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_PrintSigned(long n)\r
-{\r
- char buffer[32];\r
-\r
- US_Print(ltoa(n,buffer,10));\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_PrintInCenter() - Prints a string in the center of the given rect\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_PrintInCenter(char *s,Rect r)\r
-{\r
- word w,h,\r
- rw,rh;\r
-\r
- USL_MeasureString(s,&w,&h);\r
- rw = r.lr.x - r.ul.x;\r
- rh = r.lr.y - r.ul.y;\r
-\r
- px = r.ul.x + ((rw - w) / 2);\r
- py = r.ul.y + ((rh - h) / 2);\r
- USL_DrawString(s);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_PrintCentered() - Prints a string centered in the current window.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_PrintCentered(char *s)\r
-{\r
- Rect r;\r
-\r
- r.ul.x = WindowX;\r
- r.ul.y = WindowY;\r
- r.lr.x = r.ul.x + WindowW;\r
- r.lr.y = r.ul.y + WindowH;\r
-\r
- USL_PrintInCenter(s,r);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_CPrintLine() - Prints a string centered on the current line and\r
-// advances to the next line. Newlines are not supported.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_CPrintLine(char *s)\r
-{\r
- word w,h;\r
-\r
- USL_MeasureString(s,&w,&h);\r
-\r
- if (w > WindowW)\r
- Quit("US_CPrintLine() - String exceeds width");\r
- px = WindowX + ((WindowW - w) / 2);\r
- py = PrintY;\r
- USL_DrawString(s);\r
- PrintY += h;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_CPrint() - Prints a string in the current window. Newlines are\r
-// supported.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_CPrint(char *s)\r
-{\r
- char c,*se;\r
- word w,h;\r
-\r
- while (*s)\r
- {\r
- se = s;\r
- while ((c = *se) && (c != '\n'))\r
- se++;\r
- *se = '\0';\r
-\r
- US_CPrintLine(s);\r
-\r
- s = se;\r
- if (c)\r
- {\r
- *se = c;\r
- s++;\r
- }\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_ClearWindow() - Clears the current window to white and homes the\r
-// cursor\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_ClearWindow(void)\r
-{\r
- VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);\r
- PrintX = WindowX;\r
- PrintY = WindowY;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_DrawWindow() - Draws a frame and sets the current window parms\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_DrawWindow(word x,word y,word w,word h)\r
-{\r
- word i,\r
- sx,sy,sw,sh;\r
-\r
- WindowX = x * 8;\r
- WindowY = y * 8;\r
- WindowW = w * 8;\r
- WindowH = h * 8;\r
-\r
- PrintX = WindowX;\r
- PrintY = WindowY;\r
-\r
- sx = (x - 1) * 8;\r
- sy = (y - 1) * 8;\r
- sw = (w + 1) * 8;\r
- sh = (h + 1) * 8;\r
-\r
- US_ClearWindow();\r
-\r
- VWB_DrawTile8M(sx,sy,0),VWB_DrawTile8M(sx,sy + sh,6);\r
- for (i = sx + 8;i <= sx + sw - 8;i += 8)\r
- VWB_DrawTile8M(i,sy,1),VWB_DrawTile8M(i,sy + sh,7);\r
- VWB_DrawTile8M(i,sy,2),VWB_DrawTile8M(i,sy + sh,8);\r
-\r
- for (i = sy + 8;i <= sy + sh - 8;i += 8)\r
- VWB_DrawTile8M(sx,i,3),VWB_DrawTile8M(sx + sw,i,5);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_CenterWindow() - Generates a window of a given width & height in the\r
-// middle of the screen\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_CenterWindow(word w,word h)\r
-{\r
- US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_CenterSaveWindow() - Generates a window of a given width & height in\r
-// the middle of the screen, saving the background\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_CenterSaveWindow(word w,word h,memptr *save)\r
-{\r
- word x,y,\r
- screen;\r
-\r
- x = ((MaxX / 8) - w) / 2;\r
- y = ((MaxY / 8) - h) / 2;\r
- MM_GetPtr(save,(w * h) * CHARWIDTH);\r
- screen = bufferofs + panadjust + ylookup[y] + (x * CHARWIDTH);\r
- VW_ScreenToMem(screen,*save,w * CHARWIDTH,h);\r
- US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_RestoreSaveWindow() - Restores the background of the size of the\r
-// current window from the memory specified by save\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_RestoreSaveWindow(memptr *save)\r
-{\r
- word screen;\r
-\r
- screen = bufferofs + panadjust + ylookup[WindowY] + (WindowX * CHARWIDTH);\r
- VW_MemToScreen(*save,screen,WindowW * CHARWIDTH,WindowH);\r
- MM_FreePtr(save);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_SaveWindow() - Saves the current window parms into a record for\r
-// later restoration\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_SaveWindow(WindowRec *win)\r
-{\r
- win->x = WindowX;\r
- win->y = WindowY;\r
- win->w = WindowW;\r
- win->h = WindowH;\r
-\r
- win->px = PrintX;\r
- win->py = PrintY;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_RestoreWindow() - Sets the current window parms to those held in the\r
-// record\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_RestoreWindow(WindowRec *win)\r
-{\r
- WindowX = win->x;\r
- WindowY = win->y;\r
- WindowW = win->w;\r
- WindowH = win->h;\r
-\r
- PrintX = win->px;\r
- PrintY = win->py;\r
-}\r
-\r
-// Cursor routines\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_StartCursor() - Sets up the cursor for User Mgr use\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_StartCursor(void)\r
-{\r
- CursorInfo info;\r
-\r
- VW_SetCursor(CURSORARROWSPR);\r
- CursorX = MaxX / 2;\r
- CursorY = MaxY / 2;\r
- VW_MoveCursor(CursorX,CursorY);\r
- VW_ShowCursor();\r
-\r
- IN_ReadCursor(&info); // Dispose of any accumulated movement\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_ShutCursor() - Cleans up after US_StartCursor()\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_ShutCursor(void)\r
-{\r
- VW_HideCursor();\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_UpdateCursor() - Gets the new cursor position & button states from\r
-// the Input Mgr and tells the View Mgr where the cursor is\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-boolean\r
-US_UpdateCursor(void)\r
-{\r
- CursorInfo info;\r
-\r
- IN_ReadCursor(&info);\r
- if (info.x || info.y || CursorBad)\r
- {\r
- CursorX += info.x;\r
- if (CursorX >= MaxX)\r
- CursorX = MaxX - 1;\r
- else if (CursorX < 0)\r
- CursorX = 0;\r
-\r
- CursorY += info.y;\r
- if (CursorY >= MaxY)\r
- CursorY = MaxY - 1;\r
- else if (CursorY < 0)\r
- CursorY = 0;\r
-\r
- VW_MoveCursor(CursorX,CursorY);\r
- CursorBad = false;\r
- }\r
- Button0 = info.button0;\r
- Button1 = info.button1;\r
- return(Button0 || Button1);\r
-}\r
-\r
-// Input routines\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_XORICursor(int x,int y,char *s,word cursor)\r
-{\r
- char buf[MaxString];\r
- word w,h;\r
-\r
- strcpy(buf,s);\r
- buf[cursor] = '\0';\r
- USL_MeasureString(buf,&w,&h);\r
-\r
- px = x + w - 1;\r
- py = y;\r
- USL_DrawString("\x80");\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_LineInput() - Gets a line of user input at (x,y), the string defaults\r
-// to whatever is pointed at by def. Input is restricted to maxchars\r
-// chars or maxwidth pixels wide. If the user hits escape (and escok is\r
-// true), nothing is copied into buf, and false is returned. If the\r
-// user hits return, the current string is copied into buf, and true is\r
-// returned\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-boolean\r
-US_LineInput(int x,int y,char *buf,char *def,boolean escok,\r
- int maxchars,int maxwidth)\r
-{\r
- boolean redraw,\r
- cursorvis,cursormoved,\r
- done,result;\r
- ScanCode sc;\r
- char c,\r
- s[MaxString],olds[MaxString];\r
- word i,\r
- cursor,\r
- w,h,\r
- len;\r
- longword lasttime;\r
-\r
- VW_HideCursor();\r
-\r
- if (def)\r
- strcpy(s,def);\r
- else\r
- *s = '\0';\r
- *olds = '\0';\r
- cursor = strlen(s);\r
- cursormoved = redraw = true;\r
-\r
- cursorvis = done = false;\r
- lasttime = TimeCount;\r
- LastASCII = key_None;\r
- LastScan = sc_None;\r
-\r
- while (!done)\r
- {\r
- if (cursorvis)\r
- USL_XORICursor(x,y,s,cursor);\r
-\r
- asm pushf\r
- asm cli\r
-\r
- sc = LastScan;\r
- LastScan = sc_None;\r
- c = LastASCII;\r
- LastASCII = key_None;\r
-\r
- asm popf\r
-\r
- switch (sc)\r
- {\r
- case sc_LeftArrow:\r
- if (cursor)\r
- cursor--;\r
- c = key_None;\r
- cursormoved = true;\r
- break;\r
- case sc_RightArrow:\r
- if (s[cursor])\r
- cursor++;\r
- c = key_None;\r
- cursormoved = true;\r
- break;\r
- case sc_Home:\r
- cursor = 0;\r
- c = key_None;\r
- cursormoved = true;\r
- break;\r
- case sc_End:\r
- cursor = strlen(s);\r
- c = key_None;\r
- cursormoved = true;\r
- break;\r
-\r
- case sc_Return:\r
- strcpy(buf,s);\r
- done = true;\r
- result = true;\r
- c = key_None;\r
- break;\r
- case sc_Escape:\r
- if (escok)\r
- {\r
- done = true;\r
- result = false;\r
- }\r
- c = key_None;\r
- break;\r
-\r
- case sc_BackSpace:\r
- if (cursor)\r
- {\r
- strcpy(s + cursor - 1,s + cursor);\r
- cursor--;\r
- redraw = true;\r
- }\r
- c = key_None;\r
- cursormoved = true;\r
- break;\r
- case sc_Delete:\r
- if (s[cursor])\r
- {\r
- strcpy(s + cursor,s + cursor + 1);\r
- redraw = true;\r
- }\r
- c = key_None;\r
- cursormoved = true;\r
- break;\r
-\r
- case 0x4c: // Keypad 5\r
- case sc_UpArrow:\r
- case sc_DownArrow:\r
- case sc_PgUp:\r
- case sc_PgDn:\r
- case sc_Insert:\r
- c = key_None;\r
- break;\r
- }\r
-\r
- if (c)\r
- {\r
- len = strlen(s);\r
- USL_MeasureString(s,&w,&h);\r
-\r
- if\r
- (\r
- isprint(c)\r
- && (len < MaxString - 1)\r
- && ((!maxchars) || (len < maxchars))\r
- && ((!maxwidth) || (w < maxwidth))\r
- )\r
- {\r
- for (i = len + 1;i > cursor;i--)\r
- s[i] = s[i - 1];\r
- s[cursor++] = c;\r
- redraw = true;\r
- }\r
- }\r
-\r
- if (redraw)\r
- {\r
- px = x;\r
- py = y;\r
- USL_DrawString(olds);\r
- strcpy(olds,s);\r
-\r
- px = x;\r
- py = y;\r
- USL_DrawString(s);\r
-\r
- redraw = false;\r
- }\r
-\r
- if (cursormoved)\r
- {\r
- cursorvis = false;\r
- lasttime = TimeCount - TickBase;\r
-\r
- cursormoved = false;\r
- }\r
- if (TimeCount - lasttime > TickBase / 2)\r
- {\r
- lasttime = TimeCount;\r
-\r
- cursorvis ^= true;\r
- }\r
- if (cursorvis)\r
- USL_XORICursor(x,y,s,cursor);\r
-\r
- VW_UpdateScreen();\r
- }\r
-\r
- if (cursorvis)\r
- USL_XORICursor(x,y,s,cursor);\r
- if (!result)\r
- {\r
- px = x;\r
- py = y;\r
- USL_DrawString(olds);\r
- }\r
- VW_ShowCursor();\r
- VW_UpdateScreen();\r
-\r
- IN_ClearKeysDown();\r
- return(result);\r
-}\r
-\r
-// Control panel routines\r
-\r
-static boolean FlushHelp;\r
-static WindowRec HelpWindow,BottomWindow;\r
-typedef enum\r
- {\r
- uic_Draw,uic_Hit\r
- } UserCall;\r
-typedef enum\r
- {\r
- uii_Bad,uii_Button,uii_RadioButton,uii_CheckBox,uii_KeyCap\r
- } UIType;\r
-#define ui_Normal 0\r
-#define ui_Selected 1\r
-#define ui_Disabled 2\r
-\r
- // Prototype the custom routines\r
-static boolean USL_CtlButtonCustom(UserCall,word,word),\r
- USL_CtlPButtonCustom(UserCall,word,word),\r
- USL_CtlPSButtonCustom(UserCall,word,word),\r
- USL_CtlPRButtonCustom(UserCall,word,word),\r
- USL_CtlHButtonCustom(UserCall,word,word),\r
- USL_CtlDButtonCustom(UserCall,word,word),\r
- USL_CtlDEButtonCustom(UserCall,word,word),\r
- USL_CtlDLButtonCustom(UserCall,word,word),\r
- USL_CtlDSButtonCustom(UserCall,word,word),\r
- USL_CtlSButtonCustom(UserCall,word,word),\r
- USL_CtlCButtonCustom(UserCall,word,word),\r
- USL_CtlCKbdButtonCustom(UserCall,word,word),\r
- USL_CtlCJoyButtonCustom(UserCall,word,word);\r
-\r
- // The structure of a user interaction item\r
-typedef struct {\r
- Rect r; // The enclosing rectangle\r
- UIType type; // The type of item\r
- int picup,picdown; // What to draw when up/down\r
- char *help; // Floating help string\r
- ScanCode key; // Key equiv\r
- word sel; // Interaction flags (ui_XXX)\r
- boolean (*custom)(UserCall,word,word); // Custom routine\r
- char *text; // Text for some items\r
- } UserItem;\r
-typedef struct {\r
- ScanCode key;\r
- word i,n, // Hit CtlPanels2[i][n]\r
- toi,ton; // Move to CtlPanels2[toi][ton]\r
- } HotKey; // MARK\r
-\r
-static ScanCode *KeyMaps[] =\r
- {\r
- &KbdDefs[0].button0,&KbdDefs[0].button1,\r
- &KbdDefs[0].upleft,&KbdDefs[0].up,&KbdDefs[0].upright,\r
- &KbdDefs[0].left, &KbdDefs[0].right,\r
- &KbdDefs[0].downleft,&KbdDefs[0].down,&KbdDefs[0].downright,\r
- };\r
-\r
-// Some macros to make rectangle definition quite a bit less unpleasant\r
-#define CtlPanelX 8\r
-#define CtlPanelY 4\r
-#define CtlPanel2X (8*8)\r
-#define CtlPanel2Y (2*8)\r
-#define CtlPanel3X (8*8)\r
-#define CtlPanel3Y (7*8)\r
-\r
-#define CtlPanelR(n) { CtlPanelX,CtlPanelY+(32 * (n)),\\r
- CtlPanelX+40,CtlPanelY+(32 * (n)) + 32}\r
-#define CtlPanel2R(x,y) { CtlPanel2X+(x)*8,CtlPanel2Y+(y)*8,\\r
- CtlPanel2X+32+(x)*8,CtlPanel2Y+24+(y)*8}\r
-#define CtlPanel3R(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\\r
- CtlPanel3X+32+(x)*8,CtlPanel3Y+24+(y)*8}\r
-static UserItem CtlPanels[] =\r
- {\r
-{CtlPanelR(0),uii_RadioButton,CTL_STARTUPPIC,CTL_STARTDNPIC,"Start or Resume a Game",sc_None,ui_Normal,USL_CtlButtonCustom},\r
-{CtlPanelR(1),uii_RadioButton,CTL_HELPUPPIC,CTL_HELPDNPIC,"Get Help With Commander Keen",sc_None,ui_Normal,USL_CtlButtonCustom},\r
-{CtlPanelR(2),uii_RadioButton,CTL_DISKUPPIC,CTL_DISKDNPIC,"Load / Save / Quit",sc_None,ui_Normal,USL_CtlButtonCustom},\r
-{CtlPanelR(3),uii_RadioButton,CTL_CONTROLSUPPIC,CTL_CONTROLSDNPIC,"Choose Controls",sc_C,ui_Normal,USL_CtlButtonCustom},\r
-{CtlPanelR(4),uii_RadioButton,CTL_SOUNDUPPIC,CTL_SOUNDDNPIC,"Select Sound Device",sc_F2,ui_Normal,USL_CtlButtonCustom},\r
-{CtlPanelR(5),uii_RadioButton,CTL_MUSICUPPIC,CTL_MUSICDNPIC,"Turn Music On / Off",sc_F7,ui_Normal,USL_CtlButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlPPanels[] =\r
- {\r
-{CtlPanel2R(10,0),uii_RadioButton,CTL_P_NEWGAMEUPPIC,CTL_P_NEWGAMEDNPIC,"Choose Difficulty for the New Game",sc_F5,ui_Normal,USL_CtlPButtonCustom},\r
-{CtlPanel2R(15,0),uii_RadioButton,CTL_P_RESUMEUPPIC,CTL_P_RESUMEDNPIC,"Go Back to Current Game",sc_None,ui_Normal,USL_CtlPButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlPSPanels[] =\r
- {\r
-{CtlPanel3R(13,5),uii_Button,CTL_P_MEDUPPIC,CTL_P_MEDDNPIC,"Start New Game in Normal Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},\r
-{CtlPanel3R(8,5),uii_Button,CTL_P_EASYUPPIC,CTL_P_EASYDNPIC,"Start New Game in Easy Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},\r
-{CtlPanel3R(18,5),uii_Button,CTL_P_HARDUPPIC,CTL_P_HARDDNPIC,"Start New Game in Hard Mode",sc_None,ui_Normal,USL_CtlPSButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlPRPanels[] =\r
- {\r
-{CtlPanel3R(13,5),uii_Button,CTL_P_GORESUMEUPPIC,CTL_P_GORESUMEDNPIC,"Resume Current Game",sc_None,ui_Normal,USL_CtlPRButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlHPanels[] =\r
- {\r
-{CtlPanel2R(8,0),uii_Button,CTL_H_LOSTUPPIC,CTL_H_LOSTDNPIC,"Help Me, I'm Lost!",sc_F1,ui_Normal,USL_CtlHButtonCustom},\r
-{CtlPanel2R(13,0),uii_Button,CTL_H_CTRLUPPIC,CTL_H_CTRLDNPIC,"Get Help with Controls",sc_None,ui_Normal,USL_CtlHButtonCustom},\r
-{CtlPanel2R(18,0),uii_Button,CTL_H_STORYUPPIC,CTL_H_STORYDNPIC,"Read Story & Game Tips",sc_None,ui_Normal,USL_CtlHButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlDPanels[] =\r
- {\r
-{CtlPanel2R(9,0),uii_RadioButton,CTL_D_LSGAMEUPPIC,CTL_D_LSGAMEDNPIC,"Load or Save a Game",sc_F6,ui_Normal,USL_CtlDButtonCustom},\r
-{CtlPanel2R(15,0),uii_RadioButton,CTL_D_DOSUPPIC,CTL_D_DOSDNPIC,"Exit to DOS",sc_Q,ui_Normal,USL_CtlDButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlDLSPanels[] =\r
- {\r
-#define CtlPanel3LSR(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\\r
- CtlPanel3X+32+(x)*8,CtlPanel3Y+16+(y)*8}\r
-{CtlPanel3LSR(1,0),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},\r
-{CtlPanel3LSR(6,0),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},\r
-{CtlPanel3LSR(1,2),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},\r
-{CtlPanel3LSR(6,2),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},\r
-{CtlPanel3LSR(1,4),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},\r
-{CtlPanel3LSR(6,4),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},\r
-{CtlPanel3LSR(1,6),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},\r
-{CtlPanel3LSR(6,6),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},\r
-{CtlPanel3LSR(1,8),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},\r
-{CtlPanel3LSR(6,8),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},\r
-{CtlPanel3LSR(1,10),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},\r
-{CtlPanel3LSR(6,10),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},\r
-{CtlPanel3LSR(1,12),uii_Button,CTL_D_LOADUPPIC,CTL_D_LOADDNPIC,"Load This Game",sc_None,ui_Normal,USL_CtlDLButtonCustom},\r
-{CtlPanel3LSR(6,12),uii_Button,CTL_D_SAVEUPPIC,CTL_D_SAVEDNPIC,"Save Current Game Here",sc_None,ui_Normal,USL_CtlDSButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlDEPanels[] =\r
- {\r
-#define CtlPanel3ER(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\\r
- CtlPanel3X+40+(x)*8,CtlPanel3Y+24+(y)*8}\r
-{CtlPanel3ER(12,5),uii_Button,CTL_D_EXITUPPIC,CTL_D_EXITDNPIC,"Really Exit to DOS",sc_None,ui_Normal,USL_CtlDEButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlCPanels[] =\r
- {\r
-{CtlPanel2R(8,0),uii_RadioButton,CTL_C_KBDUPPIC,CTL_C_KBDDNPIC,"Use / Configure Keyboard",sc_F3,ui_Normal,USL_CtlCButtonCustom},\r
-{CtlPanel2R(13,0),uii_RadioButton,CTL_C_JOY1UPPIC,CTL_C_JOY1DNPIC,"Use / Configure Joystick 1",sc_None,ui_Normal,USL_CtlCButtonCustom},\r
-{CtlPanel2R(18,0),uii_RadioButton,CTL_C_JOY2UPPIC,CTL_C_JOY2DNPIC,"Use / Configure Joystick 2",sc_None,ui_Normal,USL_CtlCButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
-#define CtlPanelKC3R(x,y) { CtlPanel3X+(x)*8,CtlPanel3Y+(y)*8,\\r
- CtlPanel3X+56+(x)*8,CtlPanel3Y+32+(y)*8}\r
- CtlCKbdPanels[] =\r
- {\r
-{CtlPanelKC3R(1,2),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key for Jumping",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(1,6),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key for Throwing",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(8,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up & Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(15,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(22,0),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Up & Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(8,4),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(22,4),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(8,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down & Left",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(15,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{CtlPanelKC3R(22,8),uii_KeyCap,CTL_KEYCAPPIC,CTL_KEYCAPCURPIC,"Define Key to move Down & Right",sc_None,ui_Normal,USL_CtlCKbdButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlCJoyPanels[] =\r
- {\r
-{CtlPanel3R(13,5),uii_Button,CTL_C_CALIBRATEUPPIC,CTL_C_CALIBRATEDNPIC,"Configure Joystick",sc_None,ui_Normal,USL_CtlCJoyButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlSPanels[] =\r
- {\r
-{CtlPanel2R(3,0),uii_RadioButton,CTL_S_NOSNDUPPIC,CTL_S_NOSNDDNPIC,"Turn Sound Off",sc_None,ui_Normal,USL_CtlSButtonCustom},\r
-{CtlPanel2R(8,0),uii_RadioButton,CTL_S_PCSNDUPPIC,CTL_S_PCSNDDNPIC,"Use PC Speaker",sc_None,ui_Normal,USL_CtlSButtonCustom},\r
-{CtlPanel2R(13,0),uii_RadioButton,CTL_S_ADLIBUPPIC,CTL_S_ADLIBDNPIC,"Use AdLib Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},\r
-{CtlPanel2R(18,0),uii_RadioButton,CTL_S_SNDBLUPPIC,CTL_S_SNDBLDNPIC,"Use SoundBlaster Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},\r
-{CtlPanel2R(23,0),uii_RadioButton,CTL_S_SNDSRCUPPIC,CTL_S_SNDSRCDNPIC,"Use Sound Source Sound Effects",sc_None,ui_Normal,USL_CtlSButtonCustom},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlSSSPanels[] =\r
- {\r
-{CtlPanel3R(7,2),uii_CheckBox,CTL_CHECKUPPIC,CTL_CHECKDNPIC,"Turn Tandy Mode On / Off",sc_None,ui_Normal,0,"Tandy Mode"},\r
-{CtlPanel3R(7,6),uii_CheckBox,CTL_CHECKUPPIC,CTL_CHECKDNPIC,"Switch between LPT1 & LPT2",sc_None,ui_Normal,0,"Use LPT2"},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- CtlMPanels[] =\r
- {\r
-{CtlPanel2R(9,0),uii_RadioButton,CTL_M_NOMUSUPPIC,CTL_M_NOMUSDNPIC,"Background Music Off"},\r
-{CtlPanel2R(15,0),uii_RadioButton,CTL_M_ADLIBUPPIC,CTL_M_ADLIBDNPIC,"Use AdLib/SoundBlaster Music"},\r
-{-1,-1,-1,-1,uii_Bad}\r
- },\r
- *CtlPanels2[] =\r
- {\r
- CtlPPanels, // Start\r
- CtlHPanels, // Help\r
- CtlDPanels, // Disk\r
- CtlCPanels, // Controls\r
- CtlSPanels, // Sound\r
- CtlMPanels // Music\r
- },\r
- *TheItems[4] = {CtlPanels};\r
-static int CtlPanelButton;\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_TurnOff() - Goes through a list of UserItems and sets them all to\r
-// the normal state\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_TurnOff(UserItem *ip)\r
-{\r
- while (ip->type != uii_Bad)\r
- {\r
- ip->sel = ui_Normal;\r
- ip++;\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_FindDown() - Finds which UserItem, if any, is selected in the given\r
-// list\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static int\r
-USL_FindDown(UserItem *ip)\r
-{\r
- int i;\r
-\r
- for (i = 0;ip->type != uii_Bad;i++,ip++)\r
- if (ip->sel & ui_Selected)\r
- return(i);\r
- return(-1);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_ShowHelp() - Shows the specified string in the help window\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_ShowHelp(char *s)\r
-{\r
- WindowRec wr;\r
-\r
- if (!s)\r
- return;\r
-\r
- US_SaveWindow(&wr);\r
- US_RestoreWindow(&HelpWindow);\r
-\r
- US_ClearWindow();\r
- US_PrintCentered(s);\r
-\r
- US_RestoreWindow(&wr);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_HandleError() - Handles telling the user that there's been an error\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_HandleError(int num)\r
-{\r
- char buf[64];\r
-\r
- strcpy(buf,"Error: ");\r
- if (num < 0)\r
- strcat(buf,"Unknown");\r
- else if (num == ENOMEM)\r
- strcat(buf,"Disk is Full");\r
- else if (num == EINVFMT)\r
- strcat(buf,"File is Incomplete");\r
- else\r
- strcat(buf,sys_errlist[num]);\r
-\r
- VW_HideCursor();\r
-\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp(buf);\r
- fontcolor = F_BLACK;\r
- VW_UpdateScreen();\r
-\r
- IN_ClearKeysDown();\r
- IN_Ack();\r
-\r
- VW_ShowCursor();\r
- VW_UpdateScreen();\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_DrawItem() - Draws a UserItem. If there's a custom routine, this will\r
-// call it with a uic_Draw command. If the custom routine returns true,\r
-// then the routine handled all of the drawing. If it returns false,\r
-// then this routine does the default drawing.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_DrawItem(word hiti,word hitn)\r
-{\r
- boolean handled,centered;\r
- char *text;\r
- word w,h;\r
- int picup,picdown;\r
- Rect r;\r
- UserItem *ip;\r
-\r
- ip = &TheItems[hiti][hitn];\r
- if (ip->custom)\r
- handled = ip->custom(uic_Draw,hiti,hitn);\r
- else\r
- handled = false;\r
-\r
- if (!handled)\r
- {\r
- picup = ip->picup;\r
- picdown = ip->picdown;\r
- switch (ip->type)\r
- {\r
- case uii_CheckBox:\r
- px = ip->r.lr.x + 8;\r
- py = ip->r.ul.y + 8;\r
- text = ip->text;\r
- centered = false;\r
- break;\r
- case uii_KeyCap:\r
- if (!(ip->sel & ui_Selected))\r
- {\r
- text = ip->text;\r
- if (text)\r
- {\r
- r = ip->r;\r
- centered = true;\r
- }\r
- }\r
- else\r
- text = nil;\r
- break;\r
- default:\r
- text = nil;\r
- break;\r
- }\r
-\r
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,\r
- (ip->sel & ui_Selected)? picdown : picup);\r
- if (text)\r
- {\r
- if (centered)\r
- USL_PrintInCenter(text,r);\r
- else\r
- {\r
- USL_MeasureString(text,&w,&h);\r
- VWB_Bar(px,py,w + 7,h,WHITE);\r
- USL_DrawString(text);\r
- }\r
- }\r
- if (ip->sel & ui_Disabled)\r
- {\r
- if ((picup == CTL_D_LOADUPPIC) || (picup == CTL_D_SAVEUPPIC))\r
- VWB_DrawMPic(ip->r.ul.x,ip->r.ul.y,CTL_LSMASKPICM);\r
- else\r
- VWB_DrawMPic(ip->r.ul.x,ip->r.ul.y,CTL_LITTLEMASKPICM);\r
- }\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_DoHit() - Handles a hit on a UserItem. If there's a custom routine,\r
-// it will be called. If it returns true, then don't do anything\r
-// more. If it returns false, then use the standard behaviour\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_DoHit(word hiti,word hitn)\r
-{\r
- boolean handled;\r
- word i;\r
- UserItem *ip;\r
-\r
- ip = &TheItems[hiti][hitn];\r
- if (ip->custom)\r
- handled = ip->custom(uic_Hit,hiti,hitn);\r
- else\r
- handled = false;\r
-\r
- if (!handled)\r
- {\r
- if (TheItems[hiti][hitn].sel & ui_Disabled)\r
- {\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp("This Item is Disabled");\r
- fontcolor = F_BLACK;\r
- return;\r
- }\r
-\r
- FlushHelp = true;\r
-\r
- switch (ip->type)\r
- {\r
- case uii_Button:\r
- // Must have a custom routine to handle hits - this just redraws\r
- ip->sel ^= ui_Selected;\r
- USL_DrawItem(hiti,hitn);\r
- case uii_CheckBox:\r
- ip->sel ^= ui_Selected;\r
- USL_DrawItem(hiti,hitn);\r
- break;\r
- case uii_RadioButton:\r
- for (i = 0,ip = TheItems[hiti];ip->type != uii_Bad;i++,ip++)\r
- {\r
- if\r
- (\r
- (i != hitn)\r
- && (ip->type == uii_RadioButton)\r
- && (ip->sel & ui_Selected)\r
- )\r
- {\r
- ip->sel &= ~ui_Selected;\r
- USL_DrawItem(hiti,i);\r
- }\r
- }\r
- TheItems[hiti][hitn].sel |= ui_Selected;\r
- USL_DrawItem(hiti,hitn);\r
- break;\r
- case uii_KeyCap:\r
- break;\r
- }\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_IsInRect() - Checks to see if the coordinates given are within any\r
-// of the Rects in the UserItem list. If so, returns true & sets the\r
-// index & number for lookup. If not, returns false.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_IsInRect(word x,word y,word *index,word *number)\r
-{\r
- UserItem *item,**items;\r
-\r
- items = TheItems;\r
- *index = 0;\r
- while (*items)\r
- {\r
- item = *items;\r
- *number = 0;\r
- while (item->type != uii_Bad)\r
- {\r
- if\r
- (\r
- (x >= item->r.ul.x)\r
- && (x < item->r.lr.x)\r
- && (y >= item->r.ul.y)\r
- && (y < item->r.lr.y)\r
- )\r
- return(true);\r
- (*number)++;\r
- item++;\r
- }\r
-\r
- (*index)++;\r
- items++;\r
- }\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_TrackItem() - Tracks the given item. If the cursor is inside of the\r
-// item, it's redrawn as down. If the cursor is outside, the item is\r
-// drawn in its original state. Returns true if the button was released\r
-// while the cursor was inside the item, or false if it wasn't.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_TrackItem(word hiti,word hitn)\r
-{\r
- boolean inside,last;\r
- word ini,inn,\r
- on,\r
- sel,othersel;\r
- UserItem *ip,*op;\r
-\r
- ip = &TheItems[hiti][hitn];\r
- sel = ip->sel;\r
- if (ip->type == uii_RadioButton)\r
- {\r
- inside = false;\r
- for (op = TheItems[hiti],on = 0;op->type != uii_Bad;op++,on++)\r
- {\r
- if (op->sel & ui_Selected)\r
- {\r
- inside = true;\r
- break;\r
- }\r
- }\r
- if (!inside)\r
- op = ip;\r
- othersel = op->sel;\r
- }\r
- else\r
- op = nil;\r
-\r
- if (ip->sel & ui_Disabled)\r
- {\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp("This item is disabled");\r
- fontcolor = F_BLACK;\r
-\r
- while (US_UpdateCursor())\r
- VW_UpdateScreen();\r
-\r
- FlushHelp = true;\r
- return(false);\r
- }\r
-\r
- last = false;\r
- do\r
- {\r
- USL_IsInRect(CursorX,CursorY,&ini,&inn);\r
- inside = (ini == hiti) && (inn == hitn);\r
- if (inside != last)\r
- {\r
- if (inside)\r
- {\r
- if (op)\r
- {\r
- op->sel &= ~ui_Selected;\r
- ip->sel |= ui_Selected;\r
- }\r
- else\r
- ip->sel = sel ^ ui_Selected;\r
- }\r
- else\r
- {\r
- if (op && (op != ip))\r
- {\r
- op->sel |= ui_Selected;\r
- ip->sel &= ~ui_Selected;\r
- }\r
- else\r
- ip->sel = sel;\r
- }\r
-\r
- USL_DrawItem(hiti,hitn);\r
- if (op && (op != ip))\r
- USL_DrawItem(hiti,on);\r
-\r
- last = inside;\r
- }\r
- VW_UpdateScreen();\r
- } while (US_UpdateCursor());\r
-\r
- if (op)\r
- op->sel = othersel;\r
- ip->sel = sel;\r
- if (!inside)\r
- {\r
- if (op && (op != ip))\r
- USL_DrawItem(hiti,on);\r
- USL_DrawItem(hiti,hitn);\r
- VW_UpdateScreen();\r
- }\r
-\r
- return(inside);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_GlideCursor() - Smoothly moves the cursor to the given location\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_GlideCursor(long newx,long newy)\r
-{\r
- word steps;\r
- long x,y,\r
- dx,dy;\r
-\r
- if (grmode == CGAGR)\r
- steps = 1;\r
- else\r
- steps = 8;\r
-\r
- x = (long)CursorX << 16;\r
- dx = ((newx << 16) - x) / steps;\r
- y = (long)CursorY << 16;\r
- dy = ((newy << 16) - y) / steps;\r
-\r
- while ((CursorX != newx) || (CursorY != newy))\r
- {\r
- x += dx;\r
- y += dy;\r
-\r
- CursorX = x >> 16;\r
- CursorY = y >> 16;\r
- VW_MoveCursor(CursorX,CursorY);\r
- VW_UpdateScreen();\r
- }\r
- CursorBad = true;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_FindRect() - Code so ugly you'll puke! Given a Rect and direction,\r
-// this routine will try to find a UserItem to move the cursor to\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_FindRect(Rect r,Motion xd,Motion yd)\r
-{\r
- word i,i1,i2,i3;\r
- Motion m1,m2;\r
- Point diffs[9],diff,*dp;\r
- Rect *rp,*good,*goods[9];\r
- UserItem *ip,**items;\r
-\r
- for (m1 = motion_Up,dp = diffs;m1 <= motion_Down;m1++)\r
- {\r
- for (m2 = motion_Left;m2 <= motion_Right;m2++,dp++)\r
- {\r
- dp->x = m2 * 1024;\r
- dp->y = m1 * 1024;\r
- }\r
- }\r
- for (i = 0;i < 9;i++)\r
- goods[i] = nil;\r
-\r
- // Find out which octants all of the rects (except r) are in\r
- for (items = TheItems;*items;items++)\r
- {\r
- for (ip = *items;ip->type != uii_Bad;ip++)\r
- {\r
- rp = &ip->r;\r
- diff.x = rp->ul.x - r.ul.x;\r
- diff.y = rp->ul.y - r.ul.y;\r
- if (!(diff.x || diff.y))\r
- continue;\r
-\r
- if // 1,4,7\r
- (\r
- ((rp->ul.x >= r.ul.x) && (rp->ul.x < r.lr.x))\r
- || ((rp->lr.x > r.ul.x) && (rp->lr.x <= r.lr.x))\r
- )\r
- {\r
- if (rp->lr.y <= r.ul.y)\r
- {\r
- if (!(goods[1] && (diff.y < diffs[1].y)))\r
- {\r
- goods[1] = rp;\r
- diffs[1] = diff;\r
- }\r
- }\r
- else if (rp->ul.y >= r.lr.y)\r
- {\r
- if (!(goods[7] && (diff.y > diffs[7].y)))\r
- {\r
- goods[7] = rp;\r
- diffs[7] = diff;\r
- }\r
- }\r
- }\r
-\r
- if // 3,4,5\r
- (\r
- ((rp->ul.y >= r.ul.y) && (rp->ul.y < r.lr.y))\r
- || ((rp->lr.y > r.ul.y) && (rp->lr.y <= r.lr.y))\r
- )\r
- {\r
- if (rp->lr.x <= r.ul.x)\r
- {\r
- if (!(goods[3] && (diff.x < diffs[3].x)))\r
- {\r
- goods[3] = rp;\r
- diffs[3] = diff;\r
- }\r
- }\r
- else if (rp->ul.x >= r.lr.x)\r
- {\r
- if (!(goods[5] && (diff.x > diffs[5].x)))\r
- {\r
- goods[5] = rp;\r
- diffs[5] = diff;\r
- }\r
- }\r
- }\r
-\r
- if (rp->ul.x < r.ul.x) // 0,6\r
- {\r
- if (rp->lr.y <= r.ul.y)\r
- {\r
- if\r
- (\r
- (!goods[0])\r
- || (diff.y > diffs[0].y)\r
- || (diff.x > diffs[6].x)\r
- )\r
- {\r
- goods[0] = rp;\r
- diffs[0] = diff;\r
- }\r
- }\r
- else if (rp->ul.y >= r.lr.y)\r
- {\r
- if\r
- (\r
- (!goods[6])\r
- || (diff.y < diffs[6].y)\r
- || (diff.x > diffs[6].x)\r
- )\r
- {\r
- goods[6] = rp;\r
- diffs[6] = diff;\r
- }\r
- }\r
- }\r
-\r
- if (rp->lr.x > r.lr.x) // 2,8\r
- {\r
- if (rp->lr.y <= r.ul.y)\r
- {\r
- if\r
- (\r
- (!goods[2])\r
- || (diff.y > diffs[2].y)\r
- || (diff.x < diffs[2].x)\r
- )\r
- {\r
- goods[2] = rp;\r
- diffs[2] = diff;\r
- }\r
- }\r
- else if (rp->ul.y >= r.lr.y)\r
- {\r
- if\r
- (\r
- (!goods[8])\r
- || (diff.y < diffs[8].y)\r
- || (diff.x < diffs[8].x)\r
- )\r
- {\r
- goods[8] = rp;\r
- diffs[8] = diff;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- switch (yd)\r
- {\r
- case motion_Up:\r
- i1 = 1,i2 = 0,i3 = 2;\r
- break;\r
- case motion_None:\r
- switch (xd)\r
- {\r
- case motion_Left:\r
- i1 = 3,i2 = 0,i3 = 6;\r
- break;\r
- case motion_Right:\r
- i1 = 5,i2 = 8,i3 = 2;\r
- break;\r
- }\r
- break;\r
- case motion_Down:\r
- i1 = 7,i2 = 8,i3 = 6;\r
- break;\r
- }\r
-\r
- (\r
- (good = goods[i1])\r
- || (good = goods[i2])\r
- || (good = goods[i3])\r
- || (good = &r)\r
- );\r
-#if 0\r
- CursorX = good->lr.x - 8;\r
- CursorY = good->lr.y - 8;\r
- CursorBad = true;\r
- US_UpdateCursor();\r
-#endif\r
- USL_GlideCursor(good->lr.x - 8,good->lr.y - 8);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlButtonCustom() - The custom routine for all of the Control Panel\r
-// (leftmost) buttons. Clears all of the other item lists, clears the\r
-// large area, and draws the line dividing the top and bottom areas.\r
-// Then it sets up and draws the appropriate top row of icons.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlButtonCustom(UserCall call,word i,word n)\r
-{\r
- word j;\r
- UserItem *ip;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- if (n == CtlPanelButton)\r
- return(true);\r
-\r
- US_ClearWindow();\r
- for (j = 8;j < 38;j++)\r
- {\r
- VWB_DrawTile8M(j * 8,6 * 8,10);\r
- VWB_DrawTile8M(j * 8,21 * 8,10);\r
- }\r
- VWB_DrawTile8M(7 * 8,6 * 8,9);\r
- VWB_DrawTile8M(38 * 8,6 * 8,11);\r
- VWB_DrawTile8M(7 * 8,21 * 8,9);\r
- VWB_DrawTile8M(38 * 8,21 * 8,11);\r
-\r
- for (j = 1;j < 4;j++)\r
- TheItems[j] = nil;\r
-\r
- // Set to new button\r
- CtlPanelButton = n;\r
-\r
- // Draw new items\r
- TheItems[1] = ip = CtlPanels2[CtlPanelButton];\r
- j = 0;\r
- while (ip && (ip->type != uii_Bad))\r
- {\r
- USL_DrawItem(i + 1,j);\r
- if (ip->sel & ui_Selected)\r
- USL_DoHit(i + 1,j);\r
- j++;\r
- ip++;\r
- }\r
-\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlCKbdButtonCustom() - The custom routine for the keyboard keycaps.\r
-// This routine gets a scancode and puts it in the appropriate\r
-// KbdDefs[0] member.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlCKbdButtonCustom(UserCall call,word i,word n)\r
-{\r
- boolean state;\r
- word j;\r
- ScanCode scan;\r
- longword time;\r
- UserItem *ip;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- ip = &TheItems[i][n];\r
-\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp(ip->help);\r
- fontcolor = F_BLACK;\r
- VW_HideCursor();\r
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,ip->picdown);\r
- VW_UpdateScreen();\r
-\r
- LastScan = sc_None;\r
- time = TimeCount;\r
- state = true;\r
- do\r
- {\r
- if (TimeCount - time > 35) // Half-second delays\r
- {\r
- state ^= true;\r
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,state? ip->picdown : ip->picup);\r
- VW_UpdateScreen();\r
- time = TimeCount;\r
- }\r
- if (US_UpdateCursor())\r
- {\r
- while (US_UpdateCursor())\r
- ;\r
- scan = sc_Escape;\r
- break;\r
- }\r
-\r
- asm pushf\r
- asm cli\r
- if (LastScan == sc_LShift)\r
- LastScan = sc_None;\r
- asm popf\r
- } while (!(scan = LastScan));\r
- IN_ClearKey(scan);\r
- if (scan != sc_Escape)\r
- {\r
- for (j = 0,state = false;j < 10;j++)\r
- {\r
- if (j == n)\r
- continue;\r
- if (*(KeyMaps[j]) == scan)\r
- {\r
- state = true;\r
- break;\r
- }\r
- }\r
- if (state)\r
- {\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp("That Key is Already Used!");\r
- fontcolor = F_BLACK;\r
- }\r
- else\r
- {\r
- ip->text = IN_GetScanName(scan);\r
- *(KeyMaps[n]) = scan;\r
- FlushHelp = true;\r
- }\r
- }\r
-\r
- USL_DrawItem(i,n);\r
- VW_ShowCursor();\r
- VW_UpdateScreen();\r
-\r
- return(true);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlCJoyButtonCustom() - The custom button routine for joystick\r
-// calibration\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlCJoyButtonCustom(UserCall call,word i,word n)\r
-{\r
- word joy,\r
- minx,maxx,\r
- miny,maxy;\r
-\r
- i++,n++; // Shut the compiler up\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- IN_ClearKeysDown();\r
- joy = USL_FindDown(CtlCPanels) - 1;\r
-\r
- VW_HideCursor();\r
- FlushHelp = true;\r
- fontcolor = F_SECONDCOLOR;\r
-\r
- USL_ShowHelp("Move Joystick to the Upper-Left");\r
- VW_UpdateScreen();\r
- while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joy))\r
- ;\r
- if (LastScan != sc_Escape)\r
- {\r
- IN_GetJoyAbs(joy,&minx,&miny);\r
- while (IN_GetJoyButtonsDB(joy))\r
- ;\r
-\r
- USL_ShowHelp("Move Joystick to the Lower-Right");\r
- VW_UpdateScreen();\r
- while ((LastScan != sc_Escape) && !IN_GetJoyButtonsDB(joy))\r
- ;\r
- if (LastScan != sc_Escape)\r
- {\r
- IN_GetJoyAbs(0,&maxx,&maxy);\r
- IN_SetupJoy(joy,minx,maxx,miny,maxy);\r
- }\r
- }\r
-\r
- if (LastScan != sc_Escape)\r
- while (IN_GetJoyButtonsDB(joy))\r
- ;\r
-\r
- if (LastScan)\r
- IN_ClearKeysDown();\r
-\r
- fontcolor = F_BLACK;\r
- VW_ShowCursor();\r
-\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_ClearBottom() - Clears the bottom part of the window\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_ClearBottom(void)\r
-{\r
- WindowRec wr;\r
-\r
- US_SaveWindow(&wr);\r
- US_RestoreWindow(&BottomWindow);\r
-\r
- US_ClearWindow();\r
-\r
- US_RestoreWindow(&wr);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_FormatHelp() - Formats helptext. Runs through and calculates the\r
-// number of lines, and the offset for the start of each line. Stops\r
-// after len bytes or when it hits a tilde ('~'). Munges the text.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static word\r
-USL_FormatHelp(char far *text,long len)\r
-{\r
- word line,\r
- w,h,\r
- far *off;\r
- char c,\r
- far *s,far *l,far *le;\r
-\r
- WindowX += 4;\r
- WindowW -= 4;\r
-\r
- MM_GetPtr(&LineOffsets,MaxHelpLines * sizeof(word));\r
- off = (word far *)LineOffsets;\r
- for (line = 0,le = l = s = text;(s - text < len) && (*s != '~');s++)\r
- {\r
- if ((c = *s) == '\n')\r
- {\r
- *s = '\0';\r
- *off++ = l - text; // Save offset of start of line\r
- line++; // Bump line number\r
- le = l = s + 1; // Set start of line ptr\r
- }\r
-\r
- if (c == '\r')\r
- c = *s = ' ';\r
- if // Strip orphaned spaces\r
- (\r
- (c == ' ')\r
- && (s == l)\r
- && (*(s - 1) == '\0')\r
- && (*(s + 1) != ' ')\r
- && (s > text)\r
- )\r
- le = l = s + 1;\r
- else if (c == ' ')\r
- {\r
- *s = '\0';\r
- USL_MeasureString(l,&w,&h);\r
- if (w >= WindowW) // If string width exceeds window,\r
- {\r
- *s = c; // Replace null char with proper char\r
- *le = '\0'; // Go back to last line end\r
- *off++ = l - text; // Save offset of start of line\r
- line++; // Bump line number\r
- l = s = le + 1; // Start next time through after last line end\r
- }\r
- else\r
- {\r
- *s = c; // Width still ok - put char back\r
- le = s; // And save ptr to last ok end of word\r
- }\r
- }\r
- }\r
-\r
- WindowX -= 4;\r
- WindowW += 4;\r
-\r
- return(line);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_DrawHelp() - Draws helptext in the current window\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_DrawHelp(char far *text,word start,word end,word line,word h,word far *lp)\r
-{\r
- px = WindowX + 4;\r
- py = WindowY + (line * h);\r
- for (lp += start;start < end;start++,px = WindowX + 4,py += h)\r
- USL_DrawString(text + *lp++);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_DoHelp() - Formats and displays the specified help\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_DoHelp(memptr text,long len)\r
-{\r
- boolean done,\r
- moved;\r
- int scroll;\r
- word i,\r
- pixdiv,\r
- w,h,\r
- lines,cur,page,\r
- top,num,loc,\r
- far *lp,\r
- base,srcbase,destbase;\r
- ScanCode waitkey;\r
- longword lasttime;\r
- WindowRec wr;\r
- CursorInfo info;\r
-\r
- USL_ShowHelp("Arrow Keys Move / Escape Exits");\r
- fontcolor = F_BLACK;\r
-\r
- US_SaveWindow(&wr);\r
- US_RestoreWindow(&BottomWindow);\r
- US_ClearWindow();\r
-\r
- VW_HideCursor();\r
- VW_UpdateScreen();\r
-\r
- lines = USL_FormatHelp((char far *)text,len);\r
- USL_MeasureString("",&w,&h);\r
- page = WindowH / h;\r
- cur = 0;\r
- lp = LineOffsets;\r
-\r
- IN_ClearKeysDown();\r
- moved = true;\r
- lasttime = 0;\r
- scroll = 0;\r
- done = false;\r
- waitkey = sc_None;\r
- while (!done)\r
- {\r
- if (moved)\r
- {\r
- while (TimeCount - lasttime < 5)\r
- ;\r
- lasttime = TimeCount;\r
-\r
- if (scroll == -1)\r
- {\r
- top = cur;\r
- num = 1;\r
- loc = 0;\r
- }\r
- else if (scroll == +1)\r
- {\r
- num = 1;\r
- loc = page - 1;\r
- top = cur + loc;\r
- }\r
- else\r
- {\r
- top = cur;\r
- num = (page < lines)? page : lines;\r
- loc = 0;\r
- }\r
- if (scroll)\r
- {\r
- if (grmode == CGAGR)\r
- {\r
- pixdiv = 4;\r
- base = bufferofs + panadjust + (WindowX / pixdiv);\r
- }\r
- else if (grmode == EGAGR)\r
- {\r
- VWB_Bar(WindowX,WindowY + (loc * h),WindowW,num * h,WHITE);\r
- USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);\r
-\r
- pixdiv = 8;\r
- base = displayofs + panadjust + (WindowX / pixdiv);\r
- }\r
- else if (grmode == VGAGR)\r
- pixdiv = 1;\r
-\r
- if (scroll == 1)\r
- {\r
- srcbase = base + ylookup[WindowY + h];\r
- destbase = base + ylookup[WindowY];\r
- if (grmode == EGAGR)\r
- {\r
- EGAWRITEMODE(1);\r
- VW_WaitVBL(1);\r
- }\r
- VW_ScreenToScreen(srcbase,destbase,WindowW / pixdiv,\r
- WindowH - h);\r
- }\r
- else\r
- {\r
- i = WindowY + (h * (page - 1));\r
- srcbase = base + ylookup[i - h];\r
- destbase = base + ylookup[i];\r
- base = ylookup[h];\r
- for (i = page - 1;i;i--,srcbase -= base,destbase -= base)\r
- VW_ScreenToScreen(srcbase,destbase,WindowW / pixdiv,h);\r
- }\r
- if (grmode == CGAGR)\r
- {\r
- VWB_Bar(WindowX,WindowY + (loc * h),WindowW,num * h,WHITE);\r
- USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);\r
- VW_UpdateScreen();\r
- }\r
- else if (grmode == EGAGR)\r
- {\r
- base = panadjust + (WindowX / pixdiv) +\r
- ylookup[WindowY + (loc * h)];\r
- VW_ScreenToScreen(base + bufferofs,base + displayofs,\r
- WindowW / pixdiv,h);\r
- }\r
- }\r
- else\r
- {\r
- US_ClearWindow();\r
- USL_DrawHelp((char far *)text,top,top + num,loc,h,lp);\r
- VW_UpdateScreen();\r
- }\r
-\r
- moved = false;\r
- scroll = 0;\r
- }\r
-\r
- if (waitkey)\r
- while (IN_KeyDown(waitkey))\r
- ;\r
- waitkey = sc_None;\r
-\r
- IN_ReadCursor(&info);\r
- if (info.y < 0)\r
- {\r
- if (cur > 0)\r
- {\r
- scroll = -1;\r
- cur--;\r
- moved = true;\r
- }\r
- }\r
- else if (info.y > 0)\r
- {\r
- if (cur + page < lines)\r
- {\r
- scroll = +1;\r
- cur++;\r
- moved = true;\r
- }\r
- }\r
- else if (info.button0 || info.button1)\r
- done = true;\r
- else if (IN_KeyDown(LastScan))\r
- {\r
- switch (LastScan)\r
- {\r
- case sc_Escape:\r
- done = true;\r
- break;\r
- case sc_UpArrow:\r
- if (cur > 0)\r
- {\r
- scroll = -1;\r
- cur--;\r
- moved = true;\r
- }\r
- break;\r
- case sc_DownArrow:\r
- if (cur + page < lines)\r
- {\r
- scroll = +1;\r
- cur++;\r
- moved = true;\r
- }\r
- break;\r
- case sc_PgUp:\r
- if (cur > page)\r
- cur -= page;\r
- else\r
- cur = 0;\r
- moved = true;\r
- waitkey = sc_PgUp;\r
- break;\r
- case sc_PgDn:\r
- if (cur + page < lines)\r
- {\r
- cur += page;\r
- if (cur + page >= lines)\r
- cur = lines - page;\r
- moved = true;\r
- }\r
- waitkey = sc_PgDn;\r
- break;\r
- }\r
- }\r
- }\r
- IN_ClearKeysDown();\r
- do\r
- {\r
- IN_ReadCursor(&info);\r
- } while (info.button0 || info.button1);\r
-\r
- VW_ShowCursor();\r
- US_ClearWindow();\r
- VW_UpdateScreen();\r
- US_RestoreWindow(&wr);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlHButtonCustom() - The custom routine for all of the help buttons\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlHButtonCustom(UserCall call,word i,word n)\r
-{\r
- word j;\r
- UserItem *ip;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- ip = &TheItems[i][n];\r
- if (ip->sel & ui_Disabled)\r
- return(false);\r
-\r
- ip->sel |= ui_Selected;\r
- USL_DrawItem(i,n);\r
-\r
- USL_ClearBottom();\r
-\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp("Loading & Formatting Text...");\r
- VW_UpdateScreen();\r
-\r
-#ifdef HELPTEXTLINKED // Ugly hack because of lack of disk space...\r
- {\r
-extern char far gametext,far context,far story;\r
- char far *buf;\r
- memptr dupe;\r
-\r
- switch (n)\r
- {\r
- case 0:\r
- buf = &gametext;\r
- break;\r
- case 1:\r
- buf = &context;\r
- break;\r
- case 2:\r
- buf = &story;\r
- break;\r
- }\r
-\r
- MM_GetPtr(&dupe,5000);\r
- _fmemcpy((char far *)dupe,buf,5000);\r
-\r
- USL_DoHelp(dupe,5000);\r
-\r
- MM_FreePtr(&dupe);\r
- if (LineOffsets)\r
- MM_FreePtr(&LineOffsets);\r
- }\r
-#else\r
- {\r
- char *name;\r
- int file;\r
- long len;\r
- memptr buf;\r
-\r
- switch (n)\r
- {\r
- case 0:\r
- name = "GAMETEXT."EXTENSION;\r
- break;\r
- case 1:\r
- name = "CONTEXT."EXTENSION;\r
- break;\r
- case 2:\r
- name = "STORY."EXTENSION;\r
- break;\r
- default:\r
- Quit("Bad help button number");\r
- }\r
-\r
- if ((file = open(name,O_RDONLY | O_TEXT)) == -1)\r
- USL_HandleError(errno);\r
- else\r
- {\r
- len = filelength(file);\r
- MM_GetPtr(&buf,len);\r
-\r
- if (CA_FarRead(file,(byte far *)buf,len))\r
- USL_DoHelp(buf,len);\r
- else\r
- USL_HandleError(errno);\r
-\r
- close(file);\r
- MM_FreePtr(&buf);\r
- }\r
-\r
- if (LineOffsets)\r
- MM_FreePtr(&LineOffsets);\r
- }\r
-#endif\r
-\r
- fontcolor = F_BLACK;\r
-\r
- ip->sel &= ~ui_Selected;\r
- USL_DrawItem(i,n);\r
-\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlDButtonCustom() - The custom routine for all of the disk buttons.\r
-// Sets up the bottom area of the window with the appropriate buttons\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlDButtonCustom(UserCall call,word i,word n)\r
-{\r
- word j;\r
- UserItem *ip;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- ip = &TheItems[i][n];\r
- if (ip->sel & ui_Disabled)\r
- return(false);\r
-\r
- USL_ClearBottom();\r
-\r
- j = 0;\r
- TheItems[i + 1] = ip = n? CtlDEPanels : CtlDLSPanels;\r
- while (ip && (ip->type != uii_Bad))\r
- {\r
- USL_DrawItem(i + 1,j++);\r
- ip++;\r
- }\r
-\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_DLSRect() - Draw the rectangle for the save game names\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static Rect\r
-USL_DLSRect(UserItem *ip)\r
-{\r
- Rect r;\r
-\r
- r.ul.x = ip->r.lr.x + 40 + 2;\r
- r.ul.y = ip->r.ul.y + 2;\r
- r.lr.x = WindowX + WindowW - 8 - 2;\r
- r.lr.y = ip->r.lr.y - 2;\r
-\r
- VWB_Bar(r.ul.x,r.ul.y,r.lr.x - r.ul.x,r.lr.y - r.ul.y,WHITE);\r
-\r
- VWB_Hlin(r.ul.x,r.lr.x,r.ul.y,BLACK);\r
- VWB_Hlin(r.ul.x,r.lr.x,r.lr.y,BLACK);\r
- VWB_Vlin(r.ul.y,r.lr.y,r.ul.x,BLACK);\r
- VWB_Vlin(r.ul.y,r.lr.y,r.lr.x,BLACK);\r
-\r
- px = r.ul.x + 2;\r
- py = r.ul.y + 2;\r
-\r
- return(r);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlDLButtonCustom() - The load game custom routine\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlDLButtonCustom(UserCall call,word i,word n)\r
-{\r
- char *filename,\r
- msg[MaxGameName + 12];\r
- word err;\r
- int file;\r
- UserItem *ip;\r
- SaveGame *game;\r
- WindowRec wr;\r
-\r
- // DEBUG - deal with warning user about loading a game causing abort\r
-\r
- game = &Games[n / 2];\r
- ip = &TheItems[i][n];\r
-\r
- switch (call)\r
- {\r
- case uic_Draw:\r
- if (!loadedgame)\r
- {\r
- USL_DLSRect(ip);\r
- fontcolor = game->present? F_BLACK : F_FIRSTCOLOR;\r
- USL_DrawString(game->present? game->name : "Empty");\r
- fontcolor = F_BLACK;\r
- }\r
- break;\r
- case uic_Hit:\r
- if (ip->sel & ui_Disabled)\r
- return(false);\r
-\r
- LeaveDriveOn++;\r
- filename = USL_GiveSaveName(n / 2);\r
-\r
- US_SaveWindow(&wr);\r
- US_CenterWindow(30,3);\r
- strcpy(msg,"Loading `");\r
- strcat(msg,game->name);\r
- strcat(msg,"\'");\r
- US_PrintCentered(msg);\r
- VW_HideCursor();\r
- VW_UpdateScreen();\r
-\r
- err = 0;\r
- if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)\r
- {\r
- if (read(file,game,sizeof(*game)) == sizeof(*game))\r
- {\r
- if (USL_LoadGame)\r
- if (!USL_LoadGame(file))\r
- USL_HandleError(err = errno);\r
- }\r
- else\r
- USL_HandleError(err = errno);\r
- close(file);\r
- }\r
- else\r
- USL_HandleError(err = errno);\r
- if (err)\r
- abortgame = true;\r
- else\r
- loadedgame = true;\r
- game->present = true;\r
-\r
- if (loadedgame)\r
- Paused = true;\r
-\r
- VW_ShowCursor();\r
- US_RestoreWindow(&wr);\r
-\r
- LeaveDriveOn--;\r
- break;\r
- }\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlDSButtonCustom() - The save game custom routine\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlDSButtonCustom(UserCall call,word i,word n)\r
-{\r
- boolean ok;\r
- char *filename;\r
- word err;\r
- int file;\r
- Rect r;\r
- UserItem *ip;\r
- SaveGame *game;\r
- WindowRec wr;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- game = &Games[n / 2];\r
- ip = &TheItems[i][n];\r
- if (ip->sel & ui_Disabled)\r
- return(false);\r
-\r
- FlushHelp = true;\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp("Enter Game Name / Escape Aborts");\r
- fontcolor = F_BLACK;\r
-\r
- r = USL_DLSRect(ip - 1);\r
- ok = US_LineInput(px,py,game->name,game->present? game->name : nil,true,\r
- MaxGameName,r.lr.x - r.ul.x - 8);\r
- if (!strlen(game->name))\r
- strcpy(game->name,"Untitled");\r
- if (ok)\r
- {\r
- US_SaveWindow(&wr);\r
- US_CenterWindow(10,3);\r
- US_PrintCentered("Saving");\r
- VW_HideCursor();\r
- VW_UpdateScreen();\r
-\r
- LeaveDriveOn++;\r
- filename = USL_GiveSaveName(n / 2);\r
- err = 0;\r
- file = open(filename,O_CREAT | O_BINARY | O_WRONLY,\r
- S_IREAD | S_IWRITE | S_IFREG);\r
- if (file != -1)\r
- {\r
- if (write(file,game,sizeof(*game)) == sizeof(*game))\r
- {\r
- if (USL_SaveGame)\r
- ok = USL_SaveGame(file);\r
- if (!ok)\r
- USL_HandleError(err = errno);\r
- }\r
- else\r
- USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));\r
- close(file);\r
- }\r
- else\r
- USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));\r
- if (err)\r
- {\r
- remove(filename);\r
- ok = false;\r
- }\r
- LeaveDriveOn--;\r
-\r
- VW_ShowCursor();\r
- US_RestoreWindow(&wr);\r
- USL_DoHit(i - 1,0);\r
- VW_UpdateScreen();\r
- }\r
-\r
- if (!game->present)\r
- game->present = ok;\r
-\r
- if (ok)\r
- {\r
- GameIsDirty = false;\r
- (ip - 1)->sel &= ~ui_Disabled;\r
- }\r
-\r
- USL_DrawItem(i,n - 1);\r
-// USL_CtlDLButtonCustom(uic_Draw,i,n - 1);\r
-\r
- return(true);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlSButtonCustom() - The custom routine for all of the sound buttons\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlSButtonCustom(UserCall call,word i,word n)\r
-{\r
- word j;\r
- UserItem *ip;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- ip = &TheItems[i][n];\r
- if (ip->sel & ui_Disabled)\r
- return(false);\r
-\r
- USL_ClearBottom();\r
-\r
- if (n == sdm_SoundSource)\r
- {\r
- j = 0;\r
- TheItems[i + 1] = ip = CtlSSSPanels;\r
- while (ip && (ip->type != uii_Bad))\r
- {\r
- USL_DrawItem(i + 1,j++);\r
- ip++;\r
- }\r
- }\r
- else\r
- TheItems[i + 1] = nil;\r
-\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlPButtonCustom() - The custom routine for all of the start game btns\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlPButtonCustom(UserCall call,word i,word n)\r
-{\r
- word j;\r
- UserItem *ip;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- ip = &TheItems[i][n];\r
- if (ip->sel & ui_Disabled)\r
- return(false);\r
-\r
- USL_ClearBottom();\r
-\r
- j = 0;\r
- TheItems[i + 1] = ip = n? CtlPRPanels : CtlPSPanels;\r
- while (ip && (ip->type != uii_Bad))\r
- {\r
- USL_DrawItem(i + 1,j++);\r
- ip++;\r
- }\r
-\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_GiveAbortWarning() - Draws a string that warns the user that an\r
-// action they're about to take will abort the game in progress\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_GiveAbortWarning(void)\r
-{\r
- WindowRec wr;\r
-\r
- if (!GameIsDirty)\r
- return;\r
-\r
- US_SaveWindow(&wr);\r
- US_RestoreWindow(&BottomWindow);\r
- US_HomeWindow();\r
- PrintY += 5;\r
-\r
- VWB_Bar(WindowX,WindowY,WindowW,30,WHITE);\r
- fontcolor = F_SECONDCOLOR;\r
- US_CPrint("Warning! If you do this, you'll");\r
- US_CPrint("abort the current game.");\r
- fontcolor = F_BLACK;\r
-\r
- US_RestoreWindow(&wr);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlPSButtonCustom() - The custom routine for the start game button\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlPSButtonCustom(UserCall call,word i,word n)\r
-{\r
- boolean result;\r
- UserItem *ip;\r
-\r
- i++; // Shut the compiler up\r
-\r
- switch (call)\r
- {\r
- case uic_Hit:\r
- switch (n)\r
- {\r
- case 0:\r
- restartgame = gd_Normal;\r
- break;\r
- case 1:\r
- restartgame = gd_Easy;\r
- break;\r
- case 2:\r
- restartgame = gd_Hard;\r
- break;\r
- }\r
- if (restartgame && ingame && USL_ResetGame)\r
- USL_ResetGame();\r
- result = false;\r
- break;\r
- case uic_Draw:\r
- USL_GiveAbortWarning();\r
- result = false;\r
- break;\r
- default:\r
- result = false;\r
- break;\r
- }\r
- return(result);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlPRButtonCustom() - The custom routine for the resume game button\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlPRButtonCustom(UserCall call,word i,word n)\r
-{\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- i++,n++; // Shut the compiler up\r
- ResumeGame = true;\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlDEButtonCustom() - The custom routine for the exit to DOS button\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlDEButtonCustom(UserCall call,word i,word n)\r
-{\r
- boolean result;\r
- UserItem *ip;\r
-\r
- i++,n++; // Shut the compiler up\r
-\r
- switch (call)\r
- {\r
- case uic_Hit:\r
- QuitToDos = true;\r
- break;\r
- case uic_Draw:\r
- USL_GiveAbortWarning();\r
- default:\r
- result = false;\r
- break;\r
- }\r
- return(result);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CtlCButtonCustom() - The custom routine for all of the control\r
-// buttons\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CtlCButtonCustom(UserCall call,word i,word n)\r
-{\r
- word j;\r
- Point p;\r
- UserItem *ip;\r
-\r
- if (call != uic_Hit)\r
- return(false);\r
-\r
- ip = &TheItems[i][n];\r
- if (ip->sel & ui_Disabled)\r
- return(false);\r
-\r
- USL_ClearBottom();\r
- if (n == 0) // Keyboard\r
- {\r
- TheItems[i + 1] = ip = CtlCKbdPanels;\r
- p = CtlCKbdPanels[2].r.lr;\r
- VWB_DrawPic(p.x,p.y,CTL_DIRSPIC);\r
- }\r
- else\r
- TheItems[i + 1] = ip = CtlCJoyPanels;\r
-\r
- j = 0;\r
- while (ip && (ip->type != uii_Bad))\r
- {\r
- USL_DrawItem(i + 1,j++);\r
- ip++;\r
- }\r
-\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_HitHotKey() - After a hotkey was hit, move the cursor to the first\r
-// selected item in the group after the group containing the item\r
-// holding the hotkey\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_HitHotKey(int i,int n)\r
-{\r
- UserItem *ip;\r
-\r
- if (ip = TheItems[++i])\r
- {\r
- if ((n = USL_FindDown(TheItems[i])) == -1)\r
- n = 0;\r
- ip += n;\r
- CursorX = ip->r.lr.x - 8;\r
- CursorY = ip->r.lr.y - 8;\r
- CursorBad = true;\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_CheckScan() - Checks to see if the scancode in LastScan corresponds\r
-// to anything in the list of useritems. If so, selects the item.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-USL_CheckScan(word *ci,word *cn)\r
-{\r
- word i,n;\r
- UserItem *ip;\r
-\r
- if (!LastScan)\r
- return(false);\r
-\r
-#if 1 // DEBUG - probably kill this code\r
- // Use 1..? for the items across the top row\r
- if (TheItems[1] && !IN_KeyDown(sc_RShift))\r
- {\r
- for (i = 0,ip = TheItems[1];(ip->type != uii_Bad) && (i < 9);i++,ip++)\r
- ;\r
- for (n = 0;n < i;n++)\r
- {\r
- if (LastScan == 2 + n) // Numbers from 1..9\r
- {\r
- if (!(TheItems[1][n].sel & ui_Disabled))\r
- {\r
- LastScan = sc_None;\r
- USL_DoHit(1,n);\r
- return(true);\r
- }\r
- }\r
- }\r
- }\r
-\r
- // Use Alt-1..6 for the items in the leftmost column\r
- if (IN_KeyDown(sc_RShift))\r
- {\r
- n = LastScan - 2;\r
- if (n < 6) // Numbers from 1..6\r
- {\r
- USL_DoHit(0,n);\r
- LastScan = sc_None;\r
- return(true);\r
- }\r
- }\r
-#endif\r
-\r
- // Check normal hotkeys for the leftmost column\r
- for (i = 0;CtlPanels[i].type != uii_Bad;i++)\r
- {\r
- if (CtlPanels[i].key == LastScan)\r
- {\r
- LastScan = sc_None;\r
- USL_DoHit(0,i);\r
- *ci = 0;\r
- *cn = i;\r
- USL_HitHotKey(0,i);\r
- return(true);\r
- }\r
- }\r
-\r
- // Check normal hotkeys for the top row\r
- for (i = 0;i < 6;i++)\r
- {\r
- for (n = 0,ip = CtlPanels2[i];ip && ip->type != uii_Bad;n++,ip++)\r
- {\r
- if ((ip->key == LastScan) && !(ip->sel & ui_Disabled))\r
- {\r
- LastScan = sc_None;\r
- USL_DoHit(0,i);\r
- USL_DoHit(1,n);\r
- *ci = 1;\r
- *cn = n;\r
- USL_HitHotKey(1,n);\r
- return(true);\r
- }\r
- }\r
- }\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_SetUpCtlPanel() - Sets the states of the UserItems to reflect the\r
-// values of all the appropriate variables\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_SetUpCtlPanel(void)\r
-{\r
- word i,j;\r
-\r
- GameIsDirty = ingame;\r
-\r
- // Set up restart game\r
- USL_TurnOff(CtlPPanels);\r
- CtlPPanels[0].sel = ingame? ui_Normal : ui_Selected;\r
- CtlPPanels[1].sel = ingame? ui_Selected : ui_Disabled;\r
-\r
- // Set up disk stuff - default to load/save game\r
- USL_TurnOff(CtlDPanels);\r
- CtlDPanels[0].sel = ui_Selected;\r
-\r
- // Set up load/save buttons\r
- USL_TurnOff(CtlDLSPanels);\r
- for (i = 0;i < MaxSaveGames;i++)\r
- {\r
- if (!Games[i].present)\r
- CtlDLSPanels[i * 2].sel = ui_Disabled;\r
- if (!ingame)\r
- CtlDLSPanels[(i * 2) + 1].sel = ui_Disabled;\r
- }\r
-\r
- // Set up Controls\r
- USL_TurnOff(CtlCPanels);\r
- CtlCPanels[1].sel = JoysPresent[0]? ui_Normal : ui_Disabled;\r
- CtlCPanels[2].sel = JoysPresent[1]? ui_Normal : ui_Disabled;\r
- if (Controls[0] == ctrl_Keyboard)\r
- i = 0;\r
- else\r
- i = (Controls[0] == ctrl_Joystick1)? 1 : 2;\r
- CtlCPanels[i].sel |= ui_Selected;\r
- if (JoysPresent[1] && !JoysPresent[0])\r
- CtlCPanels[2].key = sc_F4;\r
- else\r
- CtlCPanels[1].key = sc_F4;\r
-\r
- // Set up Keyboard\r
- for (i = 0;i < 10;i++)\r
- CtlCKbdPanels[i].text = IN_GetScanName(*(KeyMaps[i]));\r
-\r
- // Set up Sounds\r
- USL_TurnOff(CtlSPanels);\r
- CtlSPanels[sdm_AdLib].sel = AdLibPresent? ui_Normal : ui_Disabled;\r
-#if 0 // DEBUG - hack because no space for digitized sounds on Keen Dreams\r
- CtlSPanels[sdm_SoundBlaster].sel =\r
- SoundBlasterPresent? ui_Normal : ui_Disabled;\r
- CtlSPanels[sdm_SoundSource].sel =\r
- SoundSourcePresent? ui_Normal : ui_Disabled;\r
-#else\r
- CtlSPanels[sdm_SoundBlaster].sel = ui_Disabled;\r
- CtlSPanels[sdm_SoundSource].sel = ui_Disabled;\r
-#endif\r
- CtlSPanels[SoundMode].sel |= ui_Selected;\r
-\r
- // Set up SoundSource\r
- USL_TurnOff(CtlSSSPanels);\r
- CtlSSSPanels[0].sel = ssIsTandy? ui_Selected : ui_Normal;\r
- CtlSSSPanels[1].sel = (ssPort == 2)? ui_Selected : ui_Normal;\r
-\r
- // Set up Music\r
- USL_TurnOff(CtlMPanels);\r
- CtlMPanels[smm_AdLib].sel = AdLibPresent? ui_Normal : ui_Disabled;\r
- CtlMPanels[MusicMode].sel |= ui_Selected;\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// USL_TearDownCtlPanel() - Given the state of the control panel, sets the\r
-// modes and values as appropriate\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-USL_TearDownCtlPanel(void)\r
-{\r
- int i;\r
-\r
- i = USL_FindDown(CtlCPanels);\r
- if (i != -1)\r
- {\r
- i = i? (i == 1? ctrl_Joystick1 : ctrl_Joystick2) : ctrl_Keyboard;\r
- IN_SetControlType(0,i);\r
- }\r
-\r
- CtlCPanels[1].key = CtlCPanels[2].key = sc_None;\r
-\r
- i = USL_FindDown(CtlSPanels);\r
- if (i != -1)\r
- SD_SetSoundMode(i);\r
-\r
- ssIsTandy = CtlSSSPanels[0].sel & ui_Selected;\r
- ssPort = (CtlSSSPanels[1].sel & ui_Selected)? 2 : 1;\r
-\r
- i = USL_FindDown(CtlMPanels);\r
- if (i != -1)\r
- {\r
- SD_SetMusicMode(i);\r
-\r
- if (!QuitToDos)\r
- {\r
- US_CenterWindow(20,8);\r
- US_CPrint("Loading");\r
-#if 0\r
- fontcolor = F_SECONDCOLOR;\r
- US_CPrint("Sounds");\r
- fontcolor = F_BLACK;\r
-#endif\r
- VW_UpdateScreen();\r
-\r
- CA_LoadAllSounds();\r
- }\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_ControlPanel() - This is the main routine for the control panel\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_ControlPanel(void)\r
-{\r
- char gamename[MaxGameName + 10 + 1];\r
- ScanCode c;\r
- boolean done,\r
- buttondown,inrect;\r
- word hiti,hitn,\r
- i,n,\r
- lasti,lastn,\r
- lastx,lasty;\r
- longword lasttime;\r
- Point p;\r
- Rect userect;\r
- UserItem *ip;\r
-\r
- c = LastScan;\r
- if (c == sc_Escape) // Map escape from game to Exit to DOS\r
- c = sc_Q;\r
-\r
- CA_UpLevel();\r
- for (i = CONTROLS_LUMP_START;i <= CONTROLS_LUMP_END;i++)\r
- CA_MarkGrChunk(i);\r
- CA_MarkGrChunk(CTL_LITTLEMASKPICM);\r
- CA_MarkGrChunk(CTL_LSMASKPICM);\r
- CA_CacheMarks("Options Screen");\r
-\r
- USL_SetUpCtlPanel();\r
-\r
- US_SetPrintRoutines(VW_MeasurePropString,VWB_DrawPropString);\r
- fontcolor = F_BLACK;\r
-\r
- VW_InitDoubleBuffer();\r
-\r
- VWB_Bar(0,0,MaxX,MaxY,FIRSTCOLOR);\r
- US_DrawWindow(8,22,30,2);\r
- US_SaveWindow(&HelpWindow);\r
- US_DrawWindow(8,7,30,14);\r
- US_SaveWindow(&BottomWindow);\r
- US_DrawWindow(8,1,30,20);\r
-\r
- for (ip = CtlPanels;ip->type != uii_Bad;ip++)\r
- VWB_DrawPic(ip->r.ul.x,ip->r.ul.y,ip->picup);\r
-\r
- US_StartCursor();\r
- CursorX = (8 * 8) + ((MaxX - (8 * 8)) / 2);\r
- CursorBad = true;\r
-\r
- CtlPanelButton = -1;\r
- LastScan = c;\r
- USL_CheckScan(&i,&n);\r
- if (CtlPanelButton == -1)\r
- USL_DoHit(0,0);\r
-\r
- ResumeGame = false;\r
- done = false;\r
- FlushHelp = true;\r
- lastx = lasty = -1;\r
- while\r
- (\r
- (restartgame == gd_Continue)\r
- && !(done || loadedgame || ResumeGame)\r
- )\r
- {\r
- VW_UpdateScreen();\r
-\r
- buttondown = US_UpdateCursor();\r
- inrect = USL_IsInRect(CursorX,CursorY,&i,&n);\r
-\r
- if (FlushHelp)\r
- {\r
- lasti = -2;\r
- lasttime = TimeCount;\r
- FlushHelp = false;\r
- }\r
- if (inrect)\r
- {\r
- if ((lasti != i) || (lastn != n))\r
- {\r
- // If over a Load button\r
- if\r
- (\r
- (CtlPanelButton == 2)\r
- && (i == 2)\r
- && (TheItems[1][0].sel & ui_Selected)\r
- && (Games[n / 2].present)\r
- && !(n & 1)\r
- )\r
- {\r
- strcpy(gamename,"Load `");\r
- strcat(gamename,Games[n / 2].name);\r
- strcat(gamename,"'");\r
- USL_ShowHelp(gamename);\r
- }\r
- else\r
- USL_ShowHelp(TheItems[i][n].help);\r
- lasti = i;\r
- lastn = n;\r
- }\r
- }\r
- else if (lasti != (word)-1)\r
- {\r
- USL_ShowHelp("Select a Button");\r
- lasti = -1;\r
- }\r
-\r
- hiti = i;\r
- hitn = n;\r
-\r
- if (inrect)\r
- userect = TheItems[i][n].r;\r
- else\r
- {\r
- userect.ul.x = CursorX;\r
- userect.ul.y = CursorY;\r
- userect.lr = userect.ul;\r
- }\r
-\r
- if (IN_KeyDown(sc_UpArrow))\r
- {\r
- USL_FindRect(userect,motion_None,motion_Up);\r
- buttondown = false;\r
- IN_ClearKey(sc_UpArrow);\r
- }\r
- else if (IN_KeyDown(sc_DownArrow))\r
- {\r
- USL_FindRect(userect,motion_None,motion_Down);\r
- buttondown = false;\r
- IN_ClearKey(sc_DownArrow);\r
- }\r
- else if (IN_KeyDown(sc_LeftArrow))\r
- {\r
- USL_FindRect(userect,motion_Left,motion_None);\r
- buttondown = false;\r
- IN_ClearKey(sc_LeftArrow);\r
- }\r
- else if (IN_KeyDown(sc_RightArrow))\r
- {\r
- USL_FindRect(userect,motion_Right,motion_None);\r
- buttondown = false;\r
- IN_ClearKey(sc_RightArrow);\r
- }\r
- else if\r
- (\r
- IN_KeyDown(c = sc_Return)\r
- || IN_KeyDown(c = KbdDefs[0].button0)\r
- || IN_KeyDown(c = KbdDefs[0].button1)\r
- )\r
- {\r
- IN_ClearKey(c);\r
- if (inrect)\r
- {\r
- ip = &TheItems[hiti][hitn];\r
-\r
- if ((ip->type == uii_Button) && !(ip->sel & ui_Disabled))\r
- {\r
- lasttime = TimeCount;\r
-\r
- ip->sel |= ui_Selected;\r
- USL_DrawItem(hiti,hitn);\r
- VW_UpdateScreen();\r
-\r
- while (TimeCount - lasttime < TickBase / 4)\r
- ;\r
- lasttime = TimeCount;\r
-\r
- ip->sel &= ~ui_Selected;\r
- USL_DrawItem(hiti,hitn);\r
- VW_UpdateScreen();\r
-\r
- while (TimeCount - lasttime < TickBase / 4)\r
- ;\r
- }\r
-\r
- USL_DoHit(hiti,hitn);\r
- }\r
- }\r
- else if (USL_CheckScan(&i,&n))\r
- ;\r
- else if (buttondown && inrect && USL_TrackItem(hiti,hitn))\r
- USL_DoHit(hiti,hitn);\r
-\r
- if (LastScan == sc_Escape)\r
- {\r
- IN_ClearKey(sc_Escape);\r
- done = true;\r
- }\r
-\r
- if (QuitToDos)\r
- done = true;\r
-\r
- if ((lastx != CursorX) || (lasty != CursorY))\r
- {\r
- lastx = CursorX;\r
- lasty = CursorY;\r
- lasttime = TimeCount;\r
- }\r
- if (TimeCount - lasttime > TickBase * 10)\r
- {\r
- if (((TimeCount - lasttime) / TickBase) & 2)\r
- fontcolor = F_SECONDCOLOR;\r
- USL_ShowHelp("Press F1 for Help");\r
- fontcolor = F_BLACK;\r
- }\r
- }\r
-\r
- US_ShutCursor();\r
-\r
- USL_TearDownCtlPanel();\r
-\r
- if (restartgame && USL_ResetGame)\r
- USL_ResetGame();\r
-\r
- if (QuitToDos)\r
- {\r
- if (tedlevel)\r
- TEDDeath();\r
- else\r
- {\r
- US_CenterWindow(20,3);\r
- fontcolor = F_SECONDCOLOR;\r
- US_PrintCentered("Now Exiting to DOS...");\r
- fontcolor = F_BLACK;\r
- VW_UpdateScreen();\r
- Quit(nil);\r
- }\r
- }\r
-\r
- CA_DownLevel();\r
-}\r
-\r
-// High score routines\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_DisplayHighScores() - Assumes that double buffering has been started.\r
-// If passed a -1 will just display the high scores, but if passed\r
-// a non-negative number will display that entry in red and let the\r
-// user type in a name\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_DisplayHighScores(int which)\r
-{\r
- char buffer[16],*str;\r
- word i,\r
- w,h,\r
- x,y;\r
- HighScore *s;\r
-\r
- US_CenterWindow(30,MaxScores + (MaxScores / 2));\r
-\r
- x = WindowX + (WindowW / 2);\r
- US_Print(" Name");\r
- PrintX = x + 20;\r
- US_Print("Score");\r
- PrintX = x + 60;\r
- US_Print("Done\n\n");\r
- PrintY -= 3;\r
-\r
- for (i = WindowX;i < WindowX + WindowW;i += 8)\r
- VWB_DrawTile8M(i,WindowY + 8,10);\r
- VWB_DrawTile8M(WindowX - 8,WindowY + 8,9);\r
- VWB_DrawTile8M(WindowX + WindowW,WindowY + 8,11);\r
-\r
- for (i = 0,s = Scores;i < MaxScores;i++,s++)\r
- {\r
- fontcolor = (i == which)? F_SECONDCOLOR : F_BLACK;\r
-\r
- if (i != which)\r
- {\r
- US_Print(" ");\r
- if (strlen(s->name))\r
- US_Print(s->name);\r
- else\r
- US_Print("-");\r
- }\r
- else\r
- y = PrintY;\r
-\r
- PrintX = x + (7 * 8);\r
- ultoa(s->score,buffer,10);\r
- for (str = buffer;*str;str++)\r
- *str = *str + (129 - '0'); // Used fixed-width numbers (129...)\r
- USL_MeasureString(buffer,&w,&h);\r
- PrintX -= w;\r
- US_Print(buffer);\r
-\r
- PrintX = x + 60;\r
- if (s->completed)\r
- US_PrintUnsigned(s->completed);\r
- else\r
- US_Print("-");\r
-\r
- US_Print("\n");\r
- }\r
-\r
- if (which != -1)\r
- {\r
- fontcolor = F_SECONDCOLOR;\r
- PrintY = y;\r
- PrintX = WindowX;\r
- US_Print(" ");\r
- strcpy(Scores[which].name,"");\r
- US_LineInput(PrintX,PrintY,Scores[which].name,nil,true,MaxHighName,\r
- (WindowW / 2) - 8);\r
- }\r
- fontcolor = F_BLACK;\r
-\r
- VW_UpdateScreen();\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// US_CheckHighScore() - Checks gamestate to see if the just-ended game\r
-// should be entered in the high score list. If so, lets the user\r
-// enter their name\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-US_CheckHighScore(long score,word other)\r
-{\r
- word i,j,\r
- n;\r
- HighScore myscore;\r
-\r
- strcpy(myscore.name,"");\r
- myscore.score = score;\r
- myscore.completed = other;\r
-\r
- for (i = 0,n = -1;i < MaxScores;i++)\r
- {\r
- if\r
- (\r
- (myscore.score > Scores[i].score)\r
- || (\r
- (myscore.score == Scores[i].score)\r
- && (myscore.completed > Scores[i].completed)\r
- )\r
- )\r
- {\r
- for (j = MaxScores;--j > i;)\r
- Scores[j] = Scores[j - 1];\r
- Scores[i] = myscore;\r
-\r
- n = i;\r
- HighScoresDirty = true;\r
- break;\r
- }\r
- }\r
-\r
- VW_InitDoubleBuffer();\r
- VWB_Bar(0,0,MaxX,MaxY,FIRSTCOLOR);\r
-\r
- US_DisplayHighScores(n);\r
- IN_UserInput(5 * TickBase,false);\r
-}\r