+/* Reconstructed Commander Keen 4-6 Source Code\r
+ * Copyright (C) 2021 K1n9_Duk3\r
+ *\r
+ * This file is primarily based on:\r
+ * Catacomb 3-D 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 - User interface\r
+// v1.1d1\r
+// By Jason Blochowiak\r
+// Hacked up for Catacomb 3D\r
+//\r
+\r
+#include "ID_HEADS.H"\r
+#pragma hdrstop\r
+\r
+#pragma warn -pia\r
+\r
+// Special imports\r
+extern boolean showscorebox;\r
+#ifdef KEEN\r
+extern boolean jerk;\r
+extern boolean oldshooting;\r
+extern ScanCode firescan;\r
+void USL_CheckSavedGames(void);\r
+#else\r
+ ScanCode firescan;\r
+#endif\r
+\r
+// Global variables\r
+ boolean ingame,abortgame,loadedgame;\r
+ GameDiff restartgame = gd_Continue;\r
+\r
+// Internal variables\r
+static boolean GameIsDirty,\r
+ QuitToDos,\r
+ CtlPanelDone;\r
+\r
+#ifdef KEEN6\r
+ int listindex = -1;\r
+ boolean checkpassed;\r
+#endif\r
+\r
+// Forward reference prototypes\r
+static void USL_SetupCard(void);\r
+\r
+// Control panel data\r
+\r
+#define CtlPanelSX 74\r
+#define CtlPanelSY 48\r
+#define CtlPanelEX 234\r
+#define CtlPanelEY 150\r
+#define CtlPanelW (CtlPanelEX - CtlPanelSX)\r
+#define CtlPanelH (CtlPanelEY - CtlPanelSY)\r
+\r
+#ifdef KEEN\r
+\r
+#define TileBase 92\r
+\r
+#if GRMODE == CGAGR\r
+\r
+#define BackColor 0\r
+#define HiliteColor (BackColor ^ 3)\r
+#define NohiliteColor (BackColor ^ 2)\r
+\r
+#else\r
+\r
+#define BackColor 8\r
+#define HiliteColor (BackColor ^ 10)\r
+#define NohiliteColor (BackColor ^ 2)\r
+\r
+#endif // if GRMODE == CGAGR ... else ...\r
+\r
+#else // ifdef KEEN\r
+\r
+#define TileBase 92\r
+\r
+// DEBUG - CGA\r
+#define BackColor 0\r
+#define HiliteColor (BackColor ^ 12)\r
+#define NohiliteColor (BackColor ^ 4)\r
+\r
+#endif\r
+\r
+typedef enum\r
+ {\r
+ uc_None,\r
+ uc_Return,\r
+ uc_Abort,\r
+ uc_Quit,\r
+ uc_Loaded,\r
+ uc_SEasy,\r
+ uc_SNormal,\r
+ uc_SHard,\r
+ } UComm;\r
+typedef enum\r
+ {\r
+ uii_Bad,\r
+ uii_Button,uii_RadioButton,uii_Folder\r
+ } UIType;\r
+typedef enum\r
+ {\r
+ ui_Normal = 0,\r
+ ui_Pushed = 1,\r
+ ui_Selected = 2,\r
+ ui_Disabled = 4,\r
+ ui_Separated = 8\r
+ } UIFlags;\r
+#define UISelectFlags (ui_Pushed | ui_Selected | ui_Disabled)\r
+\r
+typedef enum\r
+ {\r
+ uic_SetupCard,uic_DrawCard,uic_TouchupCard,\r
+ uic_DrawIcon,uic_Draw,uic_Hit\r
+ } UserCall;\r
+\r
+typedef struct UserItem\r
+ {\r
+ UIType type;\r
+ UIFlags flags;\r
+ ScanCode hotkey;\r
+ char *text;\r
+ UComm comm;\r
+ void far *child; // Should be (UserItemGroup *)\r
+\r
+ word x,y;\r
+ } UserItem;\r
+typedef struct UserItemGroup\r
+ {\r
+ word x,y;\r
+ graphicnums title;\r
+ ScanCode hotkey;\r
+ UserItem far *items;\r
+ boolean (*custom)(UserCall,struct UserItem far *); // Custom routine\r
+\r
+ word cursor;\r
+ struct UserItemGroup far *parent;\r
+ } UserItemGroup;\r
+\r
+static char *BottomS1,*BottomS2,*BottomS3;\r
+static UComm Communication;\r
+static ScanCode *KeyMaps[] =\r
+ {\r
+ &KbdDefs[0].button0,\r
+ &KbdDefs[0].button1,\r
+ &firescan,\r
+ &KbdDefs[0].upleft,\r
+ &KbdDefs[0].up,\r
+ &KbdDefs[0].upright,\r
+ &KbdDefs[0].right,\r
+ &KbdDefs[0].downright,\r
+ &KbdDefs[0].down,\r
+ &KbdDefs[0].downleft,\r
+ &KbdDefs[0].left\r
+ };\r
+\r
+// Custom routine prototypes\r
+static boolean USL_ConfigCustom(UserCall call,struct UserItem far *item),\r
+ USL_KeyCustom(UserCall call,struct UserItem far *item),\r
+ USL_KeySCustom(UserCall call,struct UserItem far *item),\r
+ USL_Joy1Custom(UserCall call,struct UserItem far *item),\r
+ USL_Joy2Custom(UserCall call,struct UserItem far *item),\r
+ USL_JoyGCustom(UserCall call,struct UserItem far *item),\r
+ USL_LoadCustom(UserCall call,struct UserItem far *item),\r
+ USL_SaveCustom(UserCall call,struct UserItem far *item),\r
+ USL_ScoreCustom(UserCall call,struct UserItem far *item),\r
+ USL_CompCustom(UserCall call,struct UserItem far *item),\r
+ USL_SmoothCustom(UserCall call,struct UserItem far *item),\r
+#ifdef KEEN\r
+ USL_TwoCustom(UserCall call,struct UserItem far *item),\r
+#endif\r
+ USL_PongCustom(UserCall call,struct UserItem far *item);\r
+\r
+#define DefButton(key,text) uii_Button,ui_Normal,key,text\r
+#define DefRButton(key,text) uii_RadioButton,ui_Normal,key,text\r
+#define DefFolder(key,text,child) uii_Folder,ui_Normal,key,text,uc_None,child\r
+#define CustomGroup(title,key,custom) 0,0,title,key,0,custom\r
+ UserItem far holder[] =\r
+ {\r
+ {DefButton(sc_None,"DEBUG")},\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far holdergroup = {0,0,CP_MAINMENUPIC,sc_None,holder};\r
+\r
+ // Sound menu\r
+ UserItem far soundi[] =\r
+ {\r
+ {DefRButton(sc_N,"NO SOUND EFFECTS")},\r
+ {DefRButton(sc_P,"PC SPEAKER")},\r
+ {DefRButton(sc_A,"ADLIB/SOUNDBLASTER")},\r
+ {DefRButton(sc_Q,"QUIET ADLIB/SOUNDBLASTER")},\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far soundgroup = {8,0,CP_SOUNDMENUPIC,sc_None,soundi};\r
+\r
+ // Music menu\r
+ UserItem far musici[] =\r
+ {\r
+ {DefRButton(sc_N,"NO MUSIC")},\r
+ {DefRButton(sc_A,"ADLIB/SOUNDBLASTER")},\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far musicgroup = {8,0,CP_MUSICMENUPIC,sc_None,musici};\r
+\r
+ // New game menu\r
+ UserItem far newgamei[] =\r
+ {\r
+ {DefButton(sc_E,"BEGIN EASY GAME"),uc_SEasy},\r
+ {DefButton(sc_N,"BEGIN NORMAL GAME"),uc_SNormal},\r
+ {DefButton(sc_H,"BEGIN HARD GAME"),uc_SHard},\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far newgamegroup = {8,0,CP_NEWGAMEMENUPIC,sc_None,newgamei,0,1};\r
+\r
+ // Load/Save game menu\r
+ UserItem far loadsavegamei[] =\r
+ {\r
+#ifdef CAT3D\r
+ {uii_Button,ui_Normal,sc_None},\r
+ {uii_Button,ui_Normal,sc_None},\r
+ {uii_Button,ui_Normal,sc_None},\r
+ {uii_Button,ui_Normal,sc_None},\r
+ {uii_Button,ui_Normal,sc_None},\r
+ {uii_Button,ui_Normal,sc_None},\r
+#else\r
+ {uii_Button,ui_Normal,sc_1},\r
+ {uii_Button,ui_Normal,sc_2},\r
+ {uii_Button,ui_Normal,sc_3},\r
+ {uii_Button,ui_Normal,sc_4},\r
+ {uii_Button,ui_Normal,sc_5},\r
+ {uii_Button,ui_Normal,sc_6},\r
+#endif\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far loadgamegroup = {4,3,CP_LOADMENUPIC,sc_None,loadsavegamei,USL_LoadCustom};\r
+ UserItemGroup far savegamegroup = {4,3,CP_SAVEMENUPIC,sc_None,loadsavegamei,USL_SaveCustom};\r
+\r
+ // Options menu\r
+ UserItemGroup far scoregroup = {0,0,0,sc_None,0,USL_ScoreCustom};\r
+#ifdef KEEN\r
+ UserItemGroup far twogroup = {0,0,0,sc_None,0,USL_TwoCustom};\r
+#endif\r
+#if GRMODE != CGAGR\r
+ UserItemGroup far smoothgroup = {0,0,0,sc_None,0,USL_SmoothCustom};\r
+ UserItemGroup far compgroup = {0,0,0,sc_None,0,USL_CompCustom};\r
+#endif\r
+\r
+ UserItem far optionsi[] =\r
+ {\r
+ {DefFolder(sc_S,"",&scoregroup)},\r
+#ifdef KEEN\r
+ {DefFolder(sc_T,"",&twogroup)},\r
+#endif\r
+#if GRMODE != CGAGR\r
+ {DefFolder(sc_M,"",&smoothgroup)},\r
+ {DefFolder(sc_C,"",&compgroup)},\r
+#endif\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far optionsgroup = {8,0,CP_OPTIONSMENUPIC,sc_None,optionsi};\r
+\r
+ // Keyboard menu\r
+ UserItem far keyi[] =\r
+ {\r
+ {DefButton(sc_None,"UP & LEFT")},\r
+ {DefButton(sc_None,"UP")},\r
+ {DefButton(sc_None,"UP & RIGHT")},\r
+ {DefButton(sc_None,"RIGHT")},\r
+ {DefButton(sc_None,"DOWN & RIGHT")},\r
+ {DefButton(sc_None,"DOWN")},\r
+ {DefButton(sc_None,"DOWN & LEFT")},\r
+ {DefButton(sc_None,"LEFT")},\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far keygroup = {0,0,CP_KEYMOVEMENTPIC,sc_None,keyi,USL_KeyCustom};\r
+ UserItem far keybi[] =\r
+ {\r
+#ifdef KEEN\r
+ {DefButton(sc_J,"JUMP")},\r
+ {DefButton(sc_P,"POGO")},\r
+ {DefButton(sc_F,"FIRE")},\r
+#endif\r
+#ifdef CAT3D\r
+ {DefButton(sc_J,"FIRE")},\r
+ {DefButton(sc_P,"STRAFE")},\r
+#endif\r
+#ifdef CPD\r
+ {DefButton(sc_J,"SHOOT")},\r
+ {DefButton(sc_P,"BOMB")},\r
+#endif\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far keybgroup = {0,0,CP_KEYBUTTONPIC,sc_None,keybi,USL_KeyCustom};\r
+ UserItem far keysi[] =\r
+ {\r
+ {DefFolder(sc_M,"MOVEMENT",&keygroup)},\r
+ {DefFolder(sc_B,"BUTTONS",&keybgroup)},\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far keysgroup = {8,0,CP_KEYBOARDMENUPIC,sc_None,keysi,USL_KeySCustom};\r
+\r
+ // Joystick #1 & #2\r
+ UserItemGroup far joy1group = {CustomGroup(CP_JOYSTICKMENUPIC,sc_None,USL_Joy1Custom)};\r
+ UserItemGroup far joy2group = {CustomGroup(CP_JOYSTICKMENUPIC,sc_None,USL_Joy2Custom)};\r
+ UserItemGroup far gravisgroup = {CustomGroup(CP_JOYSTICKMENUPIC,sc_None,USL_JoyGCustom)};\r
+\r
+ // Config menu\r
+ UserItem far configi[] =\r
+ {\r
+ {DefFolder(sc_S,"SOUND",&soundgroup)},\r
+ {DefFolder(sc_M,"MUSIC",&musicgroup)},\r
+#ifndef CAT3D\r
+ {DefFolder(sc_O,"OPTIONS",&optionsgroup)},\r
+#endif\r
+ {uii_Folder,ui_Separated,sc_K,"USE KEYBOARD",uc_None,&keysgroup},\r
+ {DefFolder(sc_1,"USE JOYSTICK #1",&joy1group)},\r
+ {DefFolder(sc_2,"USE JOYSTICK #2",&joy2group)},\r
+ {DefFolder(sc_G,"",&gravisgroup)},\r
+ {uii_Bad}\r
+ };\r
+#ifdef CAT3D\r
+ UserItemGroup far configgroup = {8,0,CP_CONFIGMENUPIC,sc_None,configi,USL_ConfigCustom};\r
+#else\r
+ UserItemGroup far configgroup = {0,0,CP_CONFIGMENUPIC,sc_None,configi,USL_ConfigCustom};\r
+#endif\r
+\r
+ // Main menu\r
+ UserItemGroup far ponggroup = {0,0,0,sc_None,0,USL_PongCustom};\r
+ UserItem far rooti[] =\r
+ {\r
+ {DefFolder(sc_N,"NEW GAME",&newgamegroup)},\r
+ {DefFolder(sc_L,"LOAD GAME",&loadgamegroup)},\r
+ {DefFolder(sc_S,"SAVE GAME",&savegamegroup)},\r
+ {DefFolder(sc_C,"CONFIGURE",&configgroup)},\r
+ {DefButton(sc_R,nil),uc_Return}, // Return to Game/Demo\r
+ {DefButton(sc_E,"END GAME"),uc_Abort},\r
+#ifdef KEEN\r
+ {DefFolder(sc_P,"PADDLE WAR",&ponggroup)},\r
+#elif defined CAT3D\r
+ {DefFolder(sc_B,"SKULL 'N' BONES",&ponggroup)},\r
+#endif\r
+ {DefButton(sc_Q,"QUIT"),uc_Quit},\r
+ {uii_Bad}\r
+ };\r
+ UserItemGroup far rootgroup = {32,4,CP_MAINMENUPIC,sc_None,rooti};\r
+#undef DefButton\r
+#undef DefFolder\r
+\r
+#define MaxCards 7\r
+ word cstackptr;\r
+ UserItemGroup far *cardstack[MaxCards],\r
+ far *topcard;\r
+\r
+// Card stack code\r
+static void\r
+USL_SetupStack(void)\r
+{\r
+ cstackptr = 0;\r
+ cardstack[0] = topcard = &rootgroup;\r
+}\r
+\r
+static void\r
+USL_PopCard(void)\r
+{\r
+ if (!cstackptr)\r
+ return;\r
+\r
+ topcard = cardstack[--cstackptr];\r
+}\r
+\r
+static void\r
+USL_PushCard(UserItemGroup far *card)\r
+{\r
+ if (cstackptr == MaxCards - 1)\r
+ return;\r
+\r
+ topcard = cardstack[++cstackptr] = card;\r
+}\r
+\r
+static void\r
+USL_DrawItemIcon(UserItem far *item)\r
+{\r
+ word flags,tile;\r
+\r
+ if (topcard->custom && topcard->custom(uic_DrawIcon,item))\r
+ return;\r
+\r
+ flags = item->flags;\r
+ if (flags & ui_Disabled)\r
+ tile = TileBase + ((flags & ui_Selected)? 5 : 4);\r
+ else if ((item->type == uii_RadioButton) && (!(flags & ui_Pushed)))\r
+ tile = TileBase + ((flags & ui_Selected)? 3 : 2);\r
+ else\r
+ tile = TileBase + ((flags & ui_Selected)? 1 : 0);\r
+ VWB_DrawTile8(item->x,item->y,tile);\r
+}\r
+\r
+static void\r
+USL_DrawItem(UserItem far *item)\r
+{\r
+ if (topcard->custom && topcard->custom(uic_Draw,item))\r
+ return;\r
+\r
+ VWB_Bar(CtlPanelSX + 1,item->y,\r
+ CtlPanelEX - CtlPanelSX - 1,8,BackColor); // Clear out background\r
+ USL_DrawItemIcon(item);\r
+ if ((item->flags & ui_Selected) && !(item->flags & ui_Disabled))\r
+ fontcolor = HiliteColor;\r
+ else\r
+ fontcolor = NohiliteColor;\r
+ px = item->x + 8;\r
+ py = item->y + 1;\r
+ USL_DrawString(item->text);\r
+ fontcolor = F_BLACK;\r
+}\r
+\r
+#ifdef KEEN\r
+#if GRMODE == CGAGR\r
+#define MyLine(y) VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,y,3);\r
+#else\r
+#define MyLine(y) VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,y,10);\r
+#endif\r
+#else\r
+#define MyLine(y) VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,y,12);\r
+#endif\r
+\r
+static void\r
+USL_DrawBottom(void)\r
+{\r
+ word w,h;\r
+\r
+ fontcolor = NohiliteColor;\r
+\r
+ px = CtlPanelSX + 4;\r
+ py = CtlPanelEY - 15;\r
+ USL_DrawString(BottomS1);\r
+\r
+ USL_MeasureString(BottomS2,&w,&h);\r
+ px = CtlPanelEX - 4 - w;\r
+ USL_DrawString(BottomS2);\r
+\r
+ USL_MeasureString(BottomS3,&w,&h);\r
+ px = CtlPanelSX + ((CtlPanelEX - CtlPanelSX - w) / 2);\r
+ py += h + 1;\r
+ USL_DrawString(BottomS3);\r
+\r
+ fontcolor = F_WHITE;\r
+ MyLine(CtlPanelEY - 17);\r
+}\r
+\r
+static void\r
+USL_DrawCtlPanelContents(void)\r
+{\r
+ int x,y;\r
+ UserItem far *item;\r
+\r
+ if (topcard->custom && topcard->custom(uic_DrawCard,nil))\r
+ return;\r
+\r
+ if (topcard->title)\r
+ {\r
+ // Draw the title\r
+ MyLine(CtlPanelSY + 7);\r
+ VWB_DrawPic(CtlPanelSX + 6,CtlPanelSY,topcard->title);\r
+ }\r
+\r
+ USL_DrawBottom();\r
+\r
+ if (!topcard->items)\r
+ return;\r
+\r
+ x = topcard->x + CtlPanelSX;\r
+ if (x % 8)\r
+ x += 8 - (x % 8);\r
+ y = topcard->y + CtlPanelSY + 12;\r
+ for (item = topcard->items;item->type != uii_Bad;item++)\r
+ {\r
+ if (item->flags & ui_Separated)\r
+ y += 8;\r
+\r
+ item->x = x;\r
+ item->y = y;\r
+ USL_DrawItem(item);\r
+ y += 8;\r
+ }\r
+ if (topcard->custom)\r
+ topcard->custom(uic_TouchupCard,nil);\r
+}\r
+\r
+static void\r
+USL_DrawCtlPanel(void)\r
+{\r
+ if (topcard->items || topcard->title)\r
+ {\r
+ // Draw the backdrop\r
+ VWB_DrawPic(0,0,CP_MENUSCREENPIC);\r
+\r
+ // Draw the contents\r
+ USL_DrawCtlPanelContents();\r
+ }\r
+\r
+ // Refresh the screen\r
+ VW_UpdateScreen();\r
+}\r
+\r
+static void\r
+USL_DialogSetup(word w,word h,word *x,word *y)\r
+{\r
+ VWB_DrawMPic(CtlPanelSX,CtlPanelSY,CP_MENUMASKPICM);\r
+\r
+ *x = CtlPanelSX + ((CtlPanelW - w) / 2);\r
+ *y = CtlPanelSY + ((CtlPanelH - h) / 2);\r
+ VWB_Bar(*x,*y,w + 1,h + 1,BackColor);\r
+ VWB_Hlin(*x - 1,*x + w + 1,*y - 1,NohiliteColor);\r
+ VWB_Hlin(*x - 1,*x + w + 1,*y + h + 1,NohiliteColor);\r
+ VWB_Vlin(*y - 1,*y + h + 1,*x - 1,NohiliteColor);\r
+ VWB_Vlin(*y - 1,*y + h + 1,*x + w + 1,NohiliteColor);\r
+}\r
+\r
+static void\r
+USL_ShowLoadSave(char *s,char *name)\r
+{\r
+ word x,y,\r
+ w,h,\r
+ tw,sw;\r
+ char msg[MaxGameName + 4];\r
+\r
+ strcpy(msg,"'");\r
+ strcat(msg,name);\r
+ strcat(msg,"'");\r
+ USL_MeasureString(s,&sw,&h);\r
+ USL_MeasureString(msg,&w,&h);\r
+ tw = ((sw > w)? sw : w) + 6;\r
+ USL_DialogSetup(tw,(h * 2) + 2,&x,&y);\r
+ py = y + 2;\r
+ px = x + ((tw - sw) / 2);\r
+ USL_DrawString(s);\r
+ py += h;\r
+ px = x + ((tw - w) / 2);\r
+ USL_DrawString(msg);\r
+\r
+ VW_UpdateScreen();\r
+#ifdef CAT3D\r
+ IN_UserInput(100, true);\r
+#endif\r
+}\r
+\r
+static boolean\r
+USL_CtlDialog(char *s1,char *s2,char *s3)\r
+{\r
+ word w,h,sh,\r
+ w1,w2,w3,\r
+ x,y;\r
+ ScanCode c;\r
+ CursorInfo cursorinfo;\r
+\r
+ USL_MeasureString(s1,&w1,&h);\r
+ USL_MeasureString(s2,&w2,&h);\r
+ if (s3)\r
+ USL_MeasureString(s3,&w3,&h);\r
+ else\r
+ w3 = 0;\r
+ w = (w1 > w2)? ((w1 > w3)? w1 : w3) : ((w2 > w3)? w2 : w3);\r
+ w += 7;\r
+ sh = h;\r
+ h *= s3? 5 : 4;\r
+\r
+ USL_DialogSetup(w,h,&x,&y);\r
+\r
+ fontcolor = HiliteColor;\r
+ px = x + ((w - w1) / 2);\r
+ py = y + sh + 1;\r
+ USL_DrawString(s1);\r
+ py += (sh * 2) - 1;\r
+\r
+ VWB_Hlin(x + 3,x + w - 3,py,NohiliteColor);\r
+ py += 2;\r
+\r
+ fontcolor = NohiliteColor;\r
+ px = x + ((w - w2) / 2);\r
+ USL_DrawString(s2);\r
+ py += sh;\r
+\r
+ if (s3)\r
+ {\r
+ px = x + ((w - w3) / 2);\r
+ USL_DrawString(s3);\r
+ }\r
+\r
+ VW_UpdateScreen();\r
+\r
+ IN_ClearKeysDown();\r
+ do\r
+ {\r
+ IN_ReadCursor(&cursorinfo);\r
+ if (cursorinfo.button0)\r
+ c = sc_Y;\r
+ else if (cursorinfo.button1)\r
+ c = sc_Escape;\r
+ else\r
+ c = LastScan;\r
+ } while (c == sc_None);\r
+ do\r
+ {\r
+ IN_ReadCursor(&cursorinfo);\r
+ } while (cursorinfo.button0 || cursorinfo.button1);\r
+\r
+ IN_ClearKeysDown();\r
+ USL_DrawCtlPanel();\r
+ return(c == sc_Y);\r
+}\r
+\r
+static boolean\r
+USL_ConfirmComm(UComm comm)\r
+{\r
+ boolean confirm,dialog;\r
+ char *s1,*s2,*s3;\r
+\r
+ if (!comm)\r
+ Quit("USL_ConfirmComm() - empty comm");\r
+\r
+ confirm = true;\r
+ dialog = false;\r
+ s3 = "ESC TO BACK OUT";\r
+ switch (comm)\r
+ {\r
+ case uc_Abort:\r
+ s1 = "REALLY END CURRENT GAME?";\r
+ s2 = "PRESS Y TO END IT";\r
+ if (ingame && GameIsDirty)\r
+ dialog = true;\r
+ break;\r
+ case uc_Quit:\r
+ s1 = "REALLY QUIT?";\r
+ s2 = "PRESS Y TO QUIT";\r
+ dialog = true;\r
+ break;\r
+ case uc_Loaded:\r
+ s1 = "YOU'RE IN A GAME";\r
+ s2 = "PRESS Y TO LOAD GAME";\r
+ if (ingame && GameIsDirty)\r
+ dialog = true;\r
+ break;\r
+ case uc_SEasy:\r
+ case uc_SNormal:\r
+ case uc_SHard:\r
+ s1 = "YOU'RE IN A GAME";\r
+ s2 = "PRESS Y FOR NEW GAME";\r
+ if (ingame && GameIsDirty)\r
+ dialog = true;\r
+ break;\r
+ }\r
+\r
+ confirm = dialog? USL_CtlDialog(s1,s2,s3) : true;\r
+ if (confirm)\r
+ {\r
+ Communication = comm;\r
+ CtlPanelDone = true;\r
+ }\r
+ return(confirm);\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
+ USL_CtlDialog(buf,"PRESS ANY KEY",nil);\r
+ VW_UpdateScreen();\r
+\r
+ IN_ClearKeysDown();\r
+ IN_Ack();\r
+\r
+ VW_ShowCursor();\r
+ VW_UpdateScreen();\r
+}\r
+\r
+// Custom routines\r
+#if 0\r
+static boolean\r
+USL_GenericCustom(UserCall call,UserItem far *item)\r
+{\r
+ boolean result;\r
+\r
+ result = false;\r
+ switch (call)\r
+ {\r
+ }\r
+ return(result);\r
+}\r
+#endif\r
+\r
+static void\r
+USL_SetOptionsText(void)\r
+{\r
+ optionsi[0].text = showscorebox? "SCORE BOX (ON)" : "SCORE BOX (OFF)";\r
+ optionsi[1].text = oldshooting? "TWO-BUTTON FIRING (ON)" : "TWO-BUTTON FIRING (OFF)";\r
+#if GRMODE != CGAGR\r
+ optionsi[2].text = jerk? "FIX JERKY MOTION (ON)" : "FIX JERKY MOTION (OFF)";\r
+ optionsi[3].text = compatability? "SVGA COMPATIBILITY (ON)" : "SVGA COMPATIBILITY (OFF)";\r
+#endif\r
+\r
+ keybi[2].flags &= ~ui_Disabled;\r
+ if (oldshooting)\r
+ keybi[2].flags |= ui_Disabled;\r
+\r
+ // gravis option is only enabled when a joystick is selected\r
+ configi[6].flags |= ui_Disabled;\r
+ if (Controls[0] == ctrl_Joystick1 || Controls[0] == ctrl_Joystick2)\r
+ configi[6].flags &= ~ui_Disabled;\r
+\r
+ configi[6].text = GravisGamepad? "USE GRAVIS GAMEPAD (ON)" : "USE GRAVIS GAMEPAD (OFF)";\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_ScoreCustom(UserCall call,UserItem far *item)\r
+{\r
+ if (call != uic_SetupCard)\r
+ return(false);\r
+\r
+ showscorebox ^= true;\r
+ USL_CtlDialog(showscorebox? "Score box now on" : "Score box now off",\r
+ "Press any key",nil);\r
+ USL_SetOptionsText();\r
+ return(true);\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_SmoothCustom(UserCall call,UserItem far *item)\r
+{\r
+ if (call != uic_SetupCard)\r
+ return(false);\r
+\r
+ jerk ^= true;\r
+ USL_CtlDialog(jerk? "Jerky motion fix enabled" : "Jerky motion fix disabled",\r
+ "Press any key",nil);\r
+ USL_SetOptionsText();\r
+ return(true);\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_CompCustom(UserCall call,UserItem far *item)\r
+{\r
+ if (call != uic_SetupCard)\r
+ return(false);\r
+\r
+ compatability ^= true;\r
+ USL_CtlDialog(compatability? "SVGA compatibility now on" : "SVGA compatibility now off",\r
+ "Press any key",nil);\r
+ USL_SetOptionsText();\r
+ return(true);\r
+}\r
+\r
+#ifdef KEEN\r
+#pragma argsused\r
+static boolean\r
+USL_TwoCustom(UserCall call,UserItem far *item)\r
+{\r
+ if (call != uic_SetupCard)\r
+ return(false);\r
+\r
+ oldshooting ^= true;\r
+ USL_CtlDialog(oldshooting? "Two-button firing now on" : "Two-button firing now off",\r
+ "Press any key",nil);\r
+ USL_SetOptionsText();\r
+ return(true);\r
+}\r
+#endif\r
+\r
+static boolean\r
+USL_ConfigCustom(UserCall call,UserItem far *item)\r
+{\r
+static char *CtlNames[] = {"KEYBOARD","KEYBOARD","JOYSTICK #1","JOYSTICK #2","MOUSE"};\r
+ char *s;\r
+ word w,h,\r
+ tw;\r
+\r
+ if (call == uic_TouchupCard)\r
+ {\r
+ s = "CONTROL: ";\r
+ USL_MeasureString(s,&w,&h);\r
+ tw = w;\r
+ USL_MeasureString(CtlNames[Controls[0]],&w,&h);\r
+ tw += w;\r
+ py = CtlPanelEY - 18 - h;\r
+ px = CtlPanelSX + ((CtlPanelW - tw) / 2);\r
+ fontcolor = NohiliteColor;\r
+ USL_DrawString(s);\r
+ USL_DrawString(CtlNames[Controls[0]]);\r
+ }\r
+ item++; // Shut the compiler up\r
+ return(false);\r
+}\r
+\r
+static void\r
+USL_CKSetKey(UserItem far *item,word i)\r
+{\r
+ boolean on;\r
+ word j;\r
+ ScanCode scan;\r
+ longword time;\r
+ CursorInfo cursorinfo;\r
+\r
+ on = false;\r
+ time = 0;\r
+ LastScan = sc_None;\r
+ fontcolor = HiliteColor;\r
+ do\r
+ {\r
+ if (TimeCount >= time)\r
+ {\r
+ on ^= true;\r
+ VWB_Bar(item->x + 90,item->y,40,8,fontcolor ^ BackColor);\r
+ VWB_Bar(item->x + 90 + 1,item->y + 1,40 - 2,8 - 2,BackColor);\r
+ if (on)\r
+ VWB_DrawTile8(item->x + 90 + 16,item->y,TileBase + 8);\r
+ VW_UpdateScreen();\r
+\r
+ time = TimeCount + (TickBase / 2);\r
+ }\r
+\r
+ IN_ReadCursor(&cursorinfo);\r
+ while (cursorinfo.button0 || cursorinfo.button1)\r
+ {\r
+ IN_ReadCursor(&cursorinfo);\r
+ LastScan = sc_Escape;\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
+\r
+ if (scan != sc_Escape)\r
+ {\r
+ for (j = 0,on = false;j < 11;j++)\r
+ {\r
+ if (j == i)\r
+ continue;\r
+ if (*(KeyMaps[j]) == scan)\r
+ {\r
+ on = true;\r
+ break;\r
+ }\r
+ }\r
+ if (on)\r
+#ifdef KEEN\r
+ USL_CtlDialog("Key already used","Press any key",nil);\r
+#else\r
+ USL_CtlDialog("Key already used","Press a key",nil);\r
+#endif\r
+ else\r
+ *(KeyMaps[i]) = scan;\r
+ }\r
+ IN_ClearKeysDown();\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_KeySCustom(UserCall call,UserItem far *item)\r
+{\r
+ if (call == uic_SetupCard)\r
+ {\r
+ Controls[0] = ctrl_Keyboard;\r
+ GravisGamepad = false;\r
+ USL_SetOptionsText();\r
+ }\r
+ return(false);\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_KeyCustom(UserCall call,UserItem far *item)\r
+{\r
+ boolean result;\r
+ word i;\r
+\r
+ result = false;\r
+ i = (topcard == &keygroup)? (3 + (item - keyi)) : (item - keybi);\r
+ switch (call)\r
+ {\r
+ case uic_SetupCard:\r
+ Controls[0] = ctrl_Keyboard;\r
+ break;\r
+ case uic_Draw:\r
+ VWB_Bar(CtlPanelSX + 1,item->y,\r
+ CtlPanelEX - CtlPanelSX - 1,8,BackColor); // Clear out background\r
+ USL_DrawItemIcon(item);\r
+ fontcolor = (item->flags & ui_Selected)? HiliteColor : NohiliteColor;\r
+ px = item->x + 8;\r
+ py = item->y + 1;\r
+ USL_DrawString(item->text);\r
+ VWB_Bar(item->x + 90,item->y,40,8,fontcolor ^ BackColor);\r
+ VWB_Bar(item->x + 90 + 1,item->y + 1,40 - 2,8 - 2,BackColor);\r
+ px = item->x + 90 + 6;\r
+ py = item->y + 1;\r
+ USL_DrawString(IN_GetScanName(*KeyMaps[i]));\r
+ result = true;\r
+ break;\r
+ case uic_Hit:\r
+ USL_KeyCustom(uic_Draw,item);\r
+ USL_CKSetKey(item,i);\r
+ USL_DrawCtlPanel();\r
+ result = true;\r
+ break;\r
+ }\r
+ return(result);\r
+}\r
+\r
+static void\r
+USL_CJDraw(char *s1,char *s2)\r
+{\r
+ word w,h;\r
+\r
+ USL_MeasureString(s1,&w,&h);\r
+ px = CtlPanelSX + ((CtlPanelW - w) / 2);\r
+ py = CtlPanelEY - 34;\r
+ VWB_Bar(CtlPanelSX + 1,py,CtlPanelW - 2,h * 2,BackColor);\r
+ fontcolor = HiliteColor;\r
+ USL_DrawString(s1);\r
+ py += h;\r
+ USL_MeasureString(s2,&w,&h);\r
+ px = CtlPanelSX + ((CtlPanelW - w) / 2);\r
+ USL_DrawString(s2);\r
+}\r
+\r
+static boolean\r
+USL_CJGet(word joy,word button,word x,word y,word *xaxis,word *yaxis)\r
+{\r
+ boolean on;\r
+ longword time;\r
+\r
+ while (IN_GetJoyButtonsDB(joy))\r
+ if (LastScan == sc_Escape)\r
+ return(false);\r
+\r
+ on = false;\r
+ time = 0;\r
+ while (!(IN_GetJoyButtonsDB(joy) & (1 << button)))\r
+ {\r
+ if (TimeCount >= time)\r
+ {\r
+ on ^= true;\r
+ time = TimeCount + (TickBase / 2);\r
+ VWB_DrawTile8(x,y,TileBase + on);\r
+ VW_UpdateScreen();\r
+ }\r
+\r
+ if (LastScan == sc_Escape)\r
+ return(false);\r
+ }\r
+ IN_GetJoyAbs(joy,xaxis,yaxis);\r
+ return(true);\r
+}\r
+\r
+static boolean\r
+USL_ConfigJoystick(word joy)\r
+{\r
+ word x,y,\r
+ minx,miny,\r
+ maxx,maxy;\r
+\r
+ BottomS1 = BottomS2 = "";\r
+#ifdef KEEN\r
+ BottomS3 = "ESC to back out";\r
+#else\r
+ BottomS3 = "Esc to back out";\r
+#endif\r
+ USL_DrawCtlPanel();\r
+ x = CtlPanelSX + 60;\r
+ y = CtlPanelSY + 19;\r
+ VWB_DrawPic(x,y,CP_JOYSTICKPIC);\r
+\r
+ USL_CJDraw("Move Joystick to upper left","and press button #1");\r
+ VWB_DrawTile8(x + 24,y + 8,TileBase + 6);\r
+ VWB_DrawTile8(x + 8,y + 8,TileBase + 1);\r
+ VWB_DrawTile8(x + 8,y + 24,TileBase + 0);\r
+ VW_UpdateScreen();\r
+ if (!USL_CJGet(joy,0,x + 8,y + 8,&minx,&miny))\r
+ return(false);\r
+\r
+ USL_CJDraw("Move Joystick to lower right","and press button #2");\r
+ VWB_DrawTile8(x + 24,y + 8,TileBase - 25);\r
+ VWB_DrawTile8(x + 40,y + 24,TileBase + 7);\r
+ VWB_DrawTile8(x + 8,y + 8,TileBase + 0);\r
+ VWB_DrawTile8(x + 8,y + 24,TileBase + 1);\r
+ VW_UpdateScreen();\r
+ if (!USL_CJGet(joy,1,x + 8,y + 24,&maxx,&maxy))\r
+ return(false);\r
+\r
+ while (IN_GetJoyButtonsDB(joy))\r
+ ;\r
+\r
+#ifdef KEEN\r
+ if (minx != maxx && miny != maxy)\r
+ {\r
+ IN_SetupJoy(joy,minx,maxx,miny,maxy);\r
+ return(true);\r
+ }\r
+ return(false);\r
+#else\r
+ IN_SetupJoy(joy,minx,maxx,miny,maxy);\r
+ return(true);\r
+#endif\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_Joy1Custom(UserCall call,UserItem far *item)\r
+{\r
+ if (call == uic_SetupCard)\r
+ {\r
+ if (USL_ConfigJoystick(0))\r
+ {\r
+ Controls[0] = ctrl_Joystick1;\r
+ USL_CtlDialog("USING JOYSTICK #1","PRESS ANY KEY",nil);\r
+ USL_SetOptionsText();\r
+ }\r
+ return(true);\r
+ }\r
+ else\r
+ return(false);\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_Joy2Custom(UserCall call,UserItem far *item)\r
+{\r
+ if (call == uic_SetupCard)\r
+ {\r
+ if (USL_ConfigJoystick(1))\r
+ {\r
+ Controls[0] = ctrl_Joystick2;\r
+ USL_CtlDialog("USING JOYSTICK #2","PRESS ANY KEY",nil);\r
+ USL_SetOptionsText();\r
+ }\r
+ return(true);\r
+ }\r
+ else\r
+ return(false);\r
+}\r
+\r
+static void\r
+USL_CGDraw(char *s1, char *s2, int buttonsDone)\r
+{\r
+ static char *GButtonNames[4] = {"Red","Blue","Yellow","Green"};\r
+ static char *GActionNames[4] = {"Jump","Pogo","Fire","Status"};\r
+\r
+ int i, n;\r
+ char *actionstr;\r
+ word w, h;\r
+\r
+ VWB_Bar(CtlPanelSX+1, CtlPanelSY+16, CtlPanelW-2, 68, BackColor);\r
+ px = CtlPanelSX+8;\r
+ py = CtlPanelSY+16;\r
+ USL_DrawString("Make sure that the button");\r
+ px = CtlPanelSX+8;\r
+ py = CtlPanelSY+24;\r
+ USL_DrawString("switch is set for 4 buttons");\r
+\r
+ for (i=0; i<4; i++)\r
+ {\r
+ px = CtlPanelSX+8;\r
+ py = i*8 + CtlPanelSY+40;\r
+ USL_DrawString(GButtonNames[i]);\r
+ USL_DrawString(":");\r
+ actionstr = "?";\r
+ for (n=0;n<buttonsDone;n++)\r
+ {\r
+ if (GravisMap[n] == i)\r
+ actionstr = GActionNames[n];\r
+ }\r
+ px = CtlPanelSX+56;\r
+ USL_DrawString(actionstr);\r
+ }\r
+\r
+ USL_MeasureString(s1, &w, &h);\r
+ px = w;\r
+ USL_MeasureString(s2, &w, &h);\r
+ px = (CtlPanelW-px-w)/2 + CtlPanelSX;\r
+ py = CtlPanelSY+76;\r
+ USL_DrawString(s1);\r
+ USL_DrawString(s2);\r
+ VW_UpdateScreen();\r
+}\r
+\r
+static boolean\r
+USL_CGGet(int buttonsDone, char *action)\r
+{\r
+ word buttons, i, n;\r
+\r
+ USL_CGDraw("PRESS BUTTON FOR ", action, buttonsDone);\r
+\r
+redo:\r
+ do\r
+ {\r
+ if (LastScan == sc_Escape)\r
+ {\r
+ Keyboard[sc_Escape] = false;\r
+ if (LastScan == sc_Escape)\r
+ LastScan = sc_None;\r
+ return false;\r
+ }\r
+\r
+ buttons = IN_GetJoyButtonsDB(2);\r
+ if (!buttons)\r
+ continue;\r
+\r
+ for(i=n=0; i<4; i++)\r
+ {\r
+ if (buttons & (1 << i))\r
+ n += i+1;\r
+ }\r
+\r
+ if (!n || n >= 5)\r
+ continue;\r
+\r
+ n--;\r
+ for (i=0; i<buttonsDone; i++)\r
+ {\r
+ if (GravisMap[i] == n)\r
+ goto redo;\r
+ }\r
+\r
+ GravisMap[buttonsDone] = n;\r
+ return true;\r
+ } while (true);\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_JoyGCustom(UserCall call,UserItem far *item)\r
+{\r
+ if (call == uic_SetupCard)\r
+ {\r
+ if (GravisGamepad)\r
+ {\r
+ GravisGamepad = false;\r
+ }\r
+ else\r
+ {\r
+ BottomS1 = BottomS2 = "";\r
+ BottomS3 = "ESC to back out";\r
+ USL_DrawCtlPanel();\r
+ fontcolor = HiliteColor;\r
+ px = CtlPanelSX + 8;\r
+ py = CtlPanelSX + 8;\r
+ fontcolor = HiliteColor; // redundant...\r
+ IN_ClearKeysDown();\r
+ if ( USL_CGGet(0, "JUMP")\r
+ && USL_CGGet(1, "POGO")\r
+ && USL_CGGet(2, "FIRE")\r
+ && USL_CGGet(3, "STATUS") )\r
+ {\r
+ GravisGamepad = true;\r
+ USL_CGDraw("PRESS ANY KEY", "", 4);\r
+ IN_Ack();\r
+ }\r
+ else\r
+ {\r
+ GravisGamepad = false;\r
+ }\r
+ }\r
+ USL_SetOptionsText();\r
+ return true;\r
+ }\r
+ return false;\r
+}\r
+\r
+static void\r
+USL_DrawFileIcon(UserItem far *item)\r
+{\r
+ word color;\r
+\r
+ item->y = topcard->y + CtlPanelSY + 12;\r
+ item->y += (item - loadsavegamei) * 11;\r
+\r
+ fontcolor = (item->flags & ui_Selected)? HiliteColor : NohiliteColor;\r
+ color = fontcolor ^ BackColor; // Blech!\r
+ VWB_Hlin(item->x,item->x + (CtlPanelW - 12),item->y,color);\r
+ VWB_Hlin(item->x,item->x + (CtlPanelW - 12),item->y + 9,color);\r
+ VWB_Vlin(item->y,item->y + 9,item->x,color);\r
+ VWB_Vlin(item->y,item->y + 9,item->x + (CtlPanelW - 12),color);\r
+}\r
+\r
+static void\r
+USL_DoLoadGame(UserItem far *item)\r
+{\r
+ char *filename;\r
+ word n,\r
+ err;\r
+ int file;\r
+ SaveGame *game;\r
+\r
+ if (!USL_ConfirmComm(uc_Loaded))\r
+ return;\r
+\r
+ n = item - loadsavegamei;\r
+ game = &Games[n];\r
+\r
+ USL_ShowLoadSave("Loading",game->name);\r
+\r
+ err = 0;\r
+ filename = USL_GiveSaveName(n);\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
+ {\r
+ abortgame = true;\r
+ Communication = uc_None;\r
+ CtlPanelDone = false;\r
+ }\r
+ else\r
+ loadedgame = true;\r
+ game->present = true;\r
+\r
+ if (loadedgame)\r
+ Paused = true;\r
+\r
+ USL_DrawCtlPanel();\r
+}\r
+\r
+static boolean\r
+USL_LoadCustom(UserCall call,UserItem far *item)\r
+{\r
+ boolean result;\r
+ word i;\r
+\r
+ result = false;\r
+ switch (call)\r
+ {\r
+ case uic_SetupCard:\r
+#ifdef KEEN\r
+ if (getenv("UID"))\r
+ USL_CheckSavedGames();\r
+#endif\r
+ for (i = 0;i < MaxSaveGames;i++)\r
+ {\r
+ if (Games[i].present)\r
+ loadsavegamei[i].flags &= ~ui_Disabled;\r
+ else\r
+ loadsavegamei[i].flags |= ui_Disabled;\r
+ }\r
+ break;\r
+ case uic_DrawIcon:\r
+ USL_DrawFileIcon(item);\r
+ result = true;\r
+ break;\r
+ case uic_Draw:\r
+ USL_DrawFileIcon(item);\r
+ VWB_Bar(item->x + 1,item->y + 2,CtlPanelW - 12 - 2,7,BackColor);\r
+\r
+ i = item - loadsavegamei;\r
+ if (Games[i].present)\r
+ px = item->x + 2;\r
+ else\r
+ px = item->x + 60;\r
+ py = item->y + 2;\r
+ USL_DrawString(Games[i].present? Games[i].name : "Empty");\r
+ result = true;\r
+ break;\r
+ case uic_Hit:\r
+ USL_DoLoadGame(item);\r
+ result = true;\r
+ break;\r
+ }\r
+ return(result);\r
+}\r
+\r
+static void\r
+USL_DoSaveGame(UserItem far *item)\r
+{\r
+ boolean ok;\r
+ char *filename;\r
+ word n,err;\r
+ int file;\r
+ SaveGame *game;\r
+\r
+ BottomS1 = "Type name";\r
+ BottomS2 = "Enter accepts";\r
+ USL_DrawCtlPanel();\r
+\r
+ n = item - loadsavegamei;\r
+ game = &Games[n];\r
+ fontcolor = HiliteColor;\r
+ VWB_Bar(item->x + 1,item->y + 2,CtlPanelW - 12 - 2,7,BackColor);\r
+ game->oldtest = &PrintX;\r
+ ok = US_LineInput(item->x + 2,item->y + 2,\r
+ game->name,game->present? game->name : nil,\r
+ true,MaxGameName,\r
+ CtlPanelW - 22);\r
+ if (!strlen(game->name))\r
+ strcpy(game->name,"Untitled");\r
+ if (ok)\r
+ {\r
+ USL_ShowLoadSave("Saving",game->name);\r
+\r
+ filename = USL_GiveSaveName(n);\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
+\r
+ }\r
+\r
+ if (!game->present)\r
+ game->present = ok;\r
+\r
+ if (ok)\r
+ GameIsDirty = false;\r
+ USL_SetupCard();\r
+}\r
+\r
+static boolean\r
+USL_SaveCustom(UserCall call,UserItem far *item)\r
+{\r
+ word i;\r
+\r
+ switch (call)\r
+ {\r
+ case uic_SetupCard:\r
+#ifdef KEEN\r
+ if (getenv("UID"))\r
+ USL_CheckSavedGames();\r
+#endif\r
+ for (i = 0;i < MaxSaveGames;i++)\r
+ loadsavegamei[i].flags &= ~ui_Disabled;\r
+ return(false);\r
+ case uic_Hit:\r
+ USL_DoSaveGame(item);\r
+ return(true);\r
+// break;\r
+ }\r
+ return(USL_LoadCustom(call,item));\r
+}\r
+\r
+#define PaddleMinX (CtlPanelSX + 4)\r
+#define PaddleMaxX (CtlPanelEX - 15)\r
+#define BallMinX (CtlPanelSX + 4)\r
+#define BallMinY (CtlPanelSY + 12 + 2)\r
+#define BallMaxX (CtlPanelEX - 6)\r
+#define BallMaxY (CtlPanelEY - 13)\r
+#define CPaddleY (BallMinY + 4)\r
+#define KPaddleY (BallMaxY - 2)\r
+void\r
+USL_DrawPongScore(word k,word c)\r
+{\r
+ fontcolor = HiliteColor;\r
+ PrintY = py = CtlPanelSY + 4;\r
+ px = CtlPanelSX + 6;\r
+ VWB_Bar(px,py,42,6,BackColor);\r
+ USL_DrawString("KEEN:");\r
+ PrintX = px;\r
+ US_PrintUnsigned(k);\r
+ px = CtlPanelSX + 108;\r
+ VWB_Bar(px,py,50,6,BackColor);\r
+ USL_DrawString("COMP:");\r
+ PrintX = px;\r
+ US_PrintUnsigned(c);\r
+}\r
+\r
+void\r
+USL_PlayPong(void)\r
+{\r
+ boolean ball,killball,revdir,done,lastscore;\r
+ word cycle,\r
+ x,y,\r
+ kx,cx,\r
+ rx,\r
+ bx,by,\r
+ oldkx,oldcx,oldbx,oldby,\r
+ kscore,cscore,\r
+ speedup;\r
+ int bdx,bdy;\r
+ longword balltime,lasttime,waittime;\r
+ CursorInfo cursorinfo;\r
+\r
+ kx = cx = PaddleMinX + ((PaddleMaxX - PaddleMinX) / 2);\r
+ bx = by = bdx = bdy = 0;\r
+ oldbx = oldcx = oldkx = PaddleMinX;\r
+ oldby = BallMinY;\r
+ kscore = cscore = 0;\r
+ USL_DrawPongScore(0,0);\r
+ cycle = 0;\r
+ revdir = false;\r
+ killball = true;\r
+ done = false;\r
+ lastscore = false;\r
+ lasttime = TimeCount;\r
+ do\r
+ {\r
+ while ((waittime = TimeCount - lasttime) == 0)\r
+ ;\r
+\r
+ lasttime = TimeCount;\r
+ if (waittime > 4)\r
+ waittime = 4;\r
+\r
+ while (waittime-- && !done && LastScan != sc_Escape)\r
+ {\r
+ IN_ReadCursor(&cursorinfo);\r
+ if (((cursorinfo.x < 0) || IN_KeyDown(sc_LeftArrow)) && (kx > PaddleMinX))\r
+ kx -= 2;\r
+ else if (((cursorinfo.x > 0) || IN_KeyDown(sc_RightArrow)) && (kx < PaddleMaxX))\r
+ kx += 2;\r
+\r
+ if (killball)\r
+ {\r
+ ball = false;\r
+ balltime = TickBase;\r
+ speedup = 10;\r
+ killball = false;\r
+ VWB_Bar(oldbx,oldby,5,5,BackColor);\r
+ }\r
+\r
+ if (ball && (cycle++ % 3))\r
+ {\r
+ x = (bx >> 2);\r
+ if (!(x & 1))\r
+ x += (US_RndT() & 1);\r
+\r
+ if ((cx + 6 < x) && (cx < PaddleMaxX))\r
+ cx += 1;\r
+ else if ((cx + 6 > x) && (cx > PaddleMinX))\r
+ cx -= 1;\r
+ }\r
+\r
+ if (!ball && !--balltime)\r
+ {\r
+ ball = true;\r
+ bdx = 1 - (US_RndT() % 3);\r
+ bdy = 3;\r
+ if (lastscore)\r
+ bdy = -bdy;\r
+ bx = (BallMinX + ((BallMaxX - BallMinX) / 2)) << 2;\r
+ by = (BallMinY + ((BallMaxY - BallMinY) / 2)) << 2;\r
+ }\r
+\r
+ if (ball)\r
+ {\r
+ if\r
+ (\r
+ (((bx + bdx) >> 2) > BallMaxX)\r
+ || (((bx + bdx) >> 2) < BallMinX)\r
+ )\r
+ {\r
+ SD_PlaySound(BALLBOUNCESND);\r
+ bdx = -bdx;\r
+ }\r
+ bx += bdx;\r
+\r
+ if (((by + bdy) >> 2) > BallMaxY)\r
+ {\r
+ killball = true;\r
+ lastscore = false;\r
+ cscore++;\r
+ SD_PlaySound(COMPSCOREDSND);\r
+ USL_DrawPongScore(kscore,cscore);\r
+ if (cscore == 21)\r
+ {\r
+ USL_CtlDialog("You lost!","Press any key",nil);\r
+ done = true;\r
+ continue;\r
+ }\r
+ }\r
+ else if (((by + bdy) >> 2) < BallMinY)\r
+ {\r
+ killball = true;\r
+ lastscore = true;\r
+ kscore++;\r
+ SD_PlaySound(KEENSCOREDSND);\r
+ USL_DrawPongScore(kscore,cscore);\r
+ if (kscore == 21)\r
+ {\r
+ USL_CtlDialog("You won!","Press any key",nil);\r
+ done = true;\r
+ continue;\r
+ }\r
+ }\r
+ by += bdy;\r
+\r
+ x = bx >> 2;\r
+ y = by >> 2;\r
+ if (!killball)\r
+ {\r
+ if\r
+ (\r
+ (bdy < 0)\r
+ && ((y >= CPaddleY) && (y < CPaddleY + 3))\r
+ && ((x >= (cx - 5)) && (x < (cx + 11)))\r
+ )\r
+ {\r
+ rx = cx;\r
+ revdir = true;\r
+ SD_PlaySound(COMPPADDLESND);\r
+ }\r
+ else if\r
+ (\r
+ (bdy > 0)\r
+ && ((y >= (KPaddleY - 3)) && (y < KPaddleY))\r
+ && ((x >= (kx - 5)) && (x < (kx + 11)))\r
+ )\r
+ {\r
+ if (((bdy >> 2) < 3) && !(--speedup))\r
+ {\r
+ bdy++;\r
+ speedup = 10;\r
+ }\r
+ rx = kx;\r
+ revdir = true;\r
+ SD_PlaySound(KEENPADDLESND);\r
+ }\r
+ if (revdir)\r
+ {\r
+ bdy = -bdy;\r
+ bdx = ((x + 5 - rx) >> 1) - (1 << 2);\r
+ if (!bdx)\r
+ bdx--;\r
+ revdir = false;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ if (ball)\r
+ {\r
+ VWB_Bar(oldbx,oldby,5,5,BackColor);\r
+ oldbx = x;\r
+ oldby = y;\r
+#if GRMODE == CGAGR\r
+ {\r
+ static int ballsprites[4] = {BALLSPR, BALL1PIXELTOTHERIGHTSPR, BALL2PIXELSTOTHERIGHTSPR, BALL3PIXELSTOTHERIGHTSPR};\r
+ VWB_DrawSprite(x,y,ballsprites[x & 3]);\r
+ }\r
+#else\r
+ VWB_DrawSprite(x,y,(x & 1)? BALL1PIXELTOTHERIGHTSPR : BALLSPR);\r
+#endif\r
+ }\r
+ VWB_Bar(oldcx-3,CPaddleY,16,3,BackColor);\r
+ oldcx = cx;\r
+ VWB_DrawSprite(cx,CPaddleY,PADDLESPR);\r
+ VWB_Bar(oldkx-3,KPaddleY,16,3,BackColor);\r
+ oldkx = kx;\r
+ VWB_DrawSprite(kx,KPaddleY,PADDLESPR);\r
+\r
+ VW_UpdateScreen();\r
+ } while ((LastScan != sc_Escape) && !done);\r
+ IN_ClearKeysDown();\r
+}\r
+\r
+#pragma argsused\r
+static boolean\r
+USL_PongCustom(UserCall call,struct UserItem far *item)\r
+{\r
+ if (call != uic_SetupCard)\r
+ return(false);\r
+\r
+ VWB_DrawPic(0,0,CP_MENUSCREENPIC);\r
+ VWB_DrawPic(CtlPanelSX + 56,CtlPanelSY,CP_PADDLEWARPIC);\r
+ VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelSY + 12,HiliteColor ^ BackColor);\r
+ VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelEY - 7,HiliteColor ^ BackColor);\r
+ USL_PlayPong();\r
+\r
+ return(true);\r
+}\r
+\r
+// Flag management stuff\r
+static void\r
+USL_ClearFlags(UserItemGroup far *node)\r
+{\r
+ UserItem far *i;\r
+\r
+ if (!node->items)\r
+ return;\r
+\r
+ for (i = node->items;i->type != uii_Bad;i++)\r
+ {\r
+ i->flags &= ~UISelectFlags;\r
+ if (i->child)\r
+ USL_ClearFlags((UserItemGroup far *)i->child);\r
+ }\r
+}\r
+\r
+static int\r
+USL_FindPushedItem(UserItemGroup far *group)\r
+{\r
+ word i;\r
+ UserItem far *item;\r
+\r
+ for (item = group->items,i = 0;item->type != uii_Bad;item++,i++)\r
+ if (item->flags & ui_Pushed)\r
+ return(i);\r
+ return(-1);\r
+}\r
+\r
+static void\r
+USL_SelectItem(UserItemGroup far *group,word index,boolean draw)\r
+{\r
+ UserItem far *item;\r
+\r
+ if (index != group->cursor)\r
+ {\r
+ item = &group->items[group->cursor];\r
+ item->flags &= ~ui_Selected;\r
+ if (draw)\r
+ USL_DrawItem(item);\r
+ }\r
+\r
+ group->cursor = index;\r
+ item = &group->items[group->cursor];\r
+ group->items[group->cursor].flags |= ui_Selected;\r
+ if (draw)\r
+ USL_DrawItem(item);\r
+}\r
+\r
+static void\r
+USL_PushItem(UserItemGroup far *group,word index,boolean draw)\r
+{\r
+ word i;\r
+ UserItem far *item;\r
+\r
+ USL_SelectItem(group,index,draw);\r
+ for (item = group->items,i = 0;item->type != uii_Bad;item++,i++)\r
+ {\r
+ if (item->type != uii_RadioButton)\r
+ continue;\r
+\r
+ if (i == index)\r
+ {\r
+ item->flags |= ui_Pushed;\r
+ if (draw)\r
+ USL_DrawItem(item);\r
+ }\r
+ else if (item->flags & ui_Pushed)\r
+ {\r
+ item->flags &= ~ui_Pushed;\r
+ if (draw)\r
+ USL_DrawItem(item);\r
+ }\r
+ }\r
+}\r
+\r
+static void\r
+USL_NextItem(void)\r
+{\r
+ if (topcard->items[topcard->cursor + 1].type == uii_Bad)\r
+ return;\r
+ USL_SelectItem(topcard,topcard->cursor + 1,true);\r
+}\r
+\r
+static void\r
+USL_PrevItem(void)\r
+{\r
+ if (!topcard->cursor)\r
+ return;\r
+ USL_SelectItem(topcard,topcard->cursor - 1,true);\r
+}\r
+\r
+static void\r
+USL_SetupCard(void)\r
+{\r
+ BottomS1 = "Arrows move";\r
+ BottomS2 = "Enter selects";\r
+ BottomS3 = cstackptr? "ESC to back out" : "ESC to quit";\r
+\r
+ USL_SelectItem(topcard,topcard->cursor,false);\r
+ USL_DrawCtlPanel(); // Contents?\r
+}\r
+\r
+static void\r
+USL_DownLevel(UserItemGroup far *group)\r
+{\r
+ if (!group)\r
+ Quit("USL_DownLevel() - nil card");\r
+ USL_PushCard(group);\r
+ if (group->custom && group->custom(uic_SetupCard,nil))\r
+ USL_PopCard();\r
+ USL_SetupCard();\r
+}\r
+\r
+static void\r
+USL_UpLevel(void)\r
+{\r
+ if (!cstackptr)\r
+ {\r
+ USL_ConfirmComm(uc_Quit);\r
+ return;\r
+ }\r
+\r
+ if (topcard->items)\r
+ topcard->items[topcard->cursor].flags &= ~ui_Selected;\r
+ USL_PopCard();\r
+ USL_SetupCard();\r
+}\r
+\r
+static void\r
+USL_DoItem(void)\r
+{\r
+ // DEBUG - finish this routine\r
+ UserItem far *item;\r
+\r
+ item = &topcard->items[topcard->cursor];\r
+ if (item->flags & ui_Disabled)\r
+ SD_PlaySound(NOWAYSND);\r
+ else\r
+ {\r
+ switch (item->type)\r
+ {\r
+ case uii_Button:\r
+ if (!(topcard->custom && topcard->custom(uic_Hit,item)))\r
+ USL_ConfirmComm(item->comm);\r
+ break;\r
+ case uii_RadioButton:\r
+ USL_PushItem(topcard,topcard->cursor,true);\r
+ break;\r
+ case uii_Folder:\r
+ USL_DownLevel(item->child);\r
+ break;\r
+ }\r
+ }\r
+}\r
+\r
+static void\r
+USL_SetControlValues(void)\r
+{\r
+ int sndindex;\r
+\r
+ sndindex = SoundMode;\r
+ if (sndindex == sdm_AdLib && QuietFX)\r
+ sndindex++;\r
+\r
+ USL_PushItem(&soundgroup,sndindex,false);\r
+ USL_PushItem(&musicgroup,MusicMode,false);\r
+ if (!AdLibPresent)\r
+ {\r
+ soundi[2].flags |= ui_Disabled; // AdLib sound effects\r
+ soundi[3].flags |= ui_Disabled; // Quiet AdLib sound effects\r
+ musici[1].flags |= ui_Disabled; // AdLib music\r
+ }\r
+\r
+#ifdef CAT3D\r
+ if (!JoysPresent[0])\r
+ configi[3].flags |= ui_Disabled;\r
+ if (!JoysPresent[1])\r
+ configi[4].flags |= ui_Disabled;\r
+#else\r
+ if (!JoysPresent[0])\r
+ configi[4].flags |= ui_Disabled;\r
+ if (!JoysPresent[1])\r
+ configi[5].flags |= ui_Disabled;\r
+ if (!JoysPresent[0] && !JoysPresent[1])\r
+ configi[6].flags |= ui_Disabled;\r
+#endif\r
+\r
+ rooti[4].text = ingame? "RETURN TO GAME" : "RETURN TO DEMO";\r
+ if (!ingame)\r
+ {\r
+ rooti[2].flags |= ui_Disabled; // Save Game\r
+ rooti[5].flags |= ui_Disabled; // End Game\r
+ }\r
+ rootgroup.cursor = ingame? 4 : 0;\r
+ USL_SetOptionsText();\r
+ // DEBUG - write the rest of this\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
+ int i;\r
+\r
+ // Cache in all of the stuff for the control panel\r
+ CA_UpLevel();\r
+ for (i = CONTROLS_LUMP_START;i <= CONTROLS_LUMP_END;i++)\r
+ CA_MarkGrChunk(i);\r
+ for (i = PADDLE_LUMP_START;i <= PADDLE_LUMP_END;i++)\r
+ CA_MarkGrChunk(i);\r
+ CA_MarkGrChunk(STARTFONT+1); // Little font\r
+ CA_MarkGrChunk(CP_MENUMASKPICM); // Mask for dialogs\r
+ CA_CacheMarks("Control Panel");\r
+ CA_LoadAllSounds();\r
+\r
+ // Do some other setup\r
+ fontnumber = 1;\r
+ US_SetPrintRoutines(VW_MeasurePropString,VWB_DrawPropString);\r
+ fontcolor = F_BLACK;\r
+#ifdef CAT3D\r
+ VW_Bar (0,0,320,200,3); // CAT3D patch\r
+#else\r
+ VW_ClearVideo(3);\r
+#endif\r
+ RF_FixOfs();\r
+ VW_InitDoubleBuffer();\r
+\r
+ Communication = uc_None;\r
+ USL_ClearFlags(&rootgroup);\r
+ USL_SetControlValues();\r
+ USL_SetupStack();\r
+ USL_SetupCard();\r
+\r
+ if (ingame)\r
+ GameIsDirty = true;\r
+\r
+ IN_ClearKeysDown();\r
+}\r
+\r
+static void\r
+USL_HandleComm(UComm comm)\r
+{\r
+ switch (comm)\r
+ {\r
+ case uc_Loaded:\r
+ case uc_Return:\r
+ break;\r
+ case uc_Abort:\r
+ abortgame = true;\r
+ break;\r
+ case uc_Quit:\r
+ QuitToDos = true;\r
+ break;\r
+ case uc_SEasy:\r
+ restartgame = gd_Easy;\r
+ break;\r
+ case uc_SNormal:\r
+ restartgame = gd_Normal;\r
+ break;\r
+ case uc_SHard:\r
+ restartgame = gd_Hard;\r
+ break;\r
+\r
+ default:\r
+ Quit("USL_HandleComm() - unknown");\r
+ break;\r
+ }\r
+}\r
+\r
+static void\r
+USL_GetControlValues(void)\r
+{\r
+ int i;\r
+\r
+ // DEBUG - write the rest of this\r
+ i = USL_FindPushedItem(&soundgroup);\r
+ if (i == 3)\r
+ {\r
+ QuietFX = true;\r
+ i--;\r
+ }\r
+ else\r
+ {\r
+ QuietFX = false;\r
+ }\r
+ if (i != SoundMode)\r
+ SD_SetSoundMode(i);\r
+\r
+ i = USL_FindPushedItem(&musicgroup);\r
+ if (i != MusicMode)\r
+ SD_SetMusicMode(i);\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
+ USL_GetControlValues();\r
+ if (Communication)\r
+ USL_HandleComm(Communication);\r
+\r
+ fontnumber = 0; // Normal font\r
+ fontcolor = F_BLACK;\r
+ if (restartgame && USL_ResetGame)\r
+ USL_ResetGame();\r
+ else if (QuitToDos)\r
+ {\r
+ if (tedlevel)\r
+ TEDDeath();\r
+ else\r
+ {\r
+ US_CenterWindow(20,3);\r
+ fontcolor = F_SECONDCOLOR;\r
+ US_PrintCentered("Quitting...");\r
+ fontcolor = F_BLACK;\r
+ VW_UpdateScreen();\r
+ Quit(nil);\r
+ }\r
+ }\r
+\r
+ IN_ClearKeysDown();\r
+ SD_WaitSoundDone();\r
+#ifdef CAT3D\r
+ VW_Bar (0,0,320,200,3); // CAT3D patch\r
+#else\r
+ VW_ClearVideo(3);\r
+#endif\r
+ CA_DownLevel();\r
+ CA_LoadAllSounds();\r
+}\r
+\r
+///////////////////////////////////////////////////////////////////////////\r
+//\r
+// US_ControlPanel() - This is the main routine for the control panel\r
+//\r
+///////////////////////////////////////////////////////////////////////////\r
+#define MoveMin 40\r
+void\r
+US_ControlPanel(void)\r
+{\r
+extern void HelpScreens(void);\r
+\r
+ boolean resetitem,on;\r
+ word i;\r
+ int ydelta;\r
+ longword flashtime;\r
+ UserItem far *item;\r
+ CursorInfo cursorinfo;\r
+\r
+#if 0\r
+ // DEBUG!!!\r
+ {\r
+ USL_SetUpCtlPanel();\r
+ Communication = uc_Loaded;\r
+ CtlPanelDone = true;\r
+ loadedgame = true;\r
+ USL_TearDownCtlPanel();\r
+ return;\r
+ }\r
+#endif\r
+\r
+ if ((LastScan < sc_F1) || (LastScan > sc_F10))\r
+ IN_ClearKeysDown();\r
+\r
+ USL_SetUpCtlPanel();\r
+ USL_DrawCtlPanel();\r
+\r
+ ydelta = 0;\r
+ for (CtlPanelDone = false,resetitem = on = true;!CtlPanelDone;)\r
+ {\r
+ item = &(topcard->items[topcard->cursor]);\r
+\r
+ if (resetitem)\r
+ {\r
+ flashtime = TimeCount + (TickBase / 2);\r
+ resetitem = false;\r
+ }\r
+\r
+ if (TimeCount >= flashtime)\r
+ {\r
+ on ^= true;\r
+ resetitem = true;\r
+ if (!on)\r
+ item->flags &= ~ui_Selected;\r
+ USL_DrawItemIcon(item);\r
+ item->flags |= ui_Selected;\r
+ }\r
+\r
+ VW_UpdateScreen();\r
+\r
+ if (LastScan)\r
+ {\r
+ switch (LastScan)\r
+ {\r
+ case sc_UpArrow:\r
+ USL_PrevItem();\r
+ resetitem = true;\r
+ break;\r
+ case sc_DownArrow:\r
+ USL_NextItem();\r
+ resetitem = true;\r
+ break;\r
+ case sc_Return:\r
+ USL_DoItem();\r
+ resetitem = true;\r
+ break;\r
+ case sc_Escape:\r
+ USL_UpLevel();\r
+ resetitem = true;\r
+ break;\r
+#ifndef KEEN6\r
+ case sc_F1:\r
+ HelpScreens();\r
+ USL_DrawCtlPanel();\r
+ resetitem = true;\r
+ break;\r
+#endif\r
+ }\r
+\r
+ if\r
+ (\r
+ (!resetitem)\r
+ && (\r
+ (LastScan == KbdDefs[0].button0)\r
+ || (LastScan == KbdDefs[0].button1)\r
+ )\r
+ )\r
+ {\r
+ USL_DoItem();\r
+ resetitem = true;\r
+ }\r
+\r
+ if (!resetitem)\r
+ {\r
+ for (item = topcard->items,i = 0;item->type != uii_Bad;item++,i++)\r
+ {\r
+ if (item->hotkey == LastScan)\r
+ {\r
+ USL_SelectItem(topcard,i,true);\r
+ resetitem = true;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ IN_ClearKeysDown();\r
+ }\r
+ else\r
+ {\r
+ IN_ReadCursor(&cursorinfo);\r
+ ydelta += cursorinfo.y;\r
+ if (cursorinfo.button0)\r
+ {\r
+ do\r
+ {\r
+ IN_ReadCursor(&cursorinfo);\r
+ } while (cursorinfo.button0);\r
+ USL_DoItem();\r
+ resetitem = true;\r
+ }\r
+ else if (cursorinfo.button1)\r
+ {\r
+ do\r
+ {\r
+ IN_ReadCursor(&cursorinfo);\r
+ } while (cursorinfo.button1);\r
+ USL_UpLevel();\r
+ resetitem = true;\r
+ }\r
+ else if (ydelta < -MoveMin)\r
+ {\r
+ ydelta += MoveMin;\r
+ USL_PrevItem();\r
+ resetitem = true;\r
+ }\r
+ else if (ydelta > MoveMin)\r
+ {\r
+ ydelta -= MoveMin;\r
+ USL_NextItem();\r
+ resetitem = true;\r
+ }\r
+ }\r
+ }\r
+\r
+ USL_TearDownCtlPanel();\r
+}\r
+\r
+#ifdef KEEN6\r
+\r
+boolean US_ManualCheck(void)\r
+{\r
+ typedef struct {\r
+ char far *name;\r
+ int shapenum;\r
+ int x, y;\r
+ } creatureinfo;\r
+\r
+ static creatureinfo list[] = {\r
+ {"BIP", BIPSHIPRSPR, -2, 0},\r
+ {"BABOBBA", BABOBBAR1SPR, 0, 0},\r
+ {"BLORB", BLORB1SPR, -2, 0},\r
+ {"GIK", GIKWALKR1SPR, -1, 0},\r
+ {"CEILICK", CEILICK1SPR, 0, 0},\r
+ {"BLOOGLET", RBLOOGLETWALKR1SPR, -2, 0},\r
+ {"BLOOGUARD", BLOOGUARDWALKL1SPR, -3, -1},\r
+ {"FLECT", FLECTSTANDSPR, -1, 0},\r
+ {"BOBBA", BOBBAR1SPR, -2, 0},\r
+ {"NOSPIKE", NOSPIKESTANDSPR, -2, 0},\r
+ {"ORBATRIX", ORBATRIXR1SPR, -2, 1},\r
+ {"FLEEX", FLEEXWALKR1SPR, -2, 0}\r
+ };\r
+\r
+ boolean correct;\r
+ char far *name;\r
+ char c;\r
+ char *ptr;\r
+ unsigned spriteheight, spritewidth;\r
+ int x, y;\r
+ int editwidth;\r
+ creatureinfo info;\r
+ char strbuf[16];\r
+\r
+ if (checkpassed)\r
+ return true;\r
+\r
+ correct = false;\r
+ if (listindex == -1)\r
+ {\r
+ _AH = 0x2C; // get time\r
+ geninterrupt(0x21);\r
+ x = _CH; // store hours\r
+ _AH = 0x2A; // get date\r
+ geninterrupt(0x21);\r
+ y = _DL; // store day\r
+\r
+ listindex = (x + y) % (int)(sizeof(list)/sizeof(creatureinfo));\r
+ }\r
+\r
+ CA_UpLevel();\r
+ info = list[listindex];\r
+ name = info.name;\r
+ CA_ClearMarks();\r
+ CA_MarkGrChunk(info.shapenum);\r
+ CA_CacheMarks(NULL);\r
+\r
+ VWB_Bar(0, 0, 320, 200, BackColor);\r
+ spritewidth = spritetable[info.shapenum - STARTSPRITES].width;\r
+ spriteheight = spritetable[info.shapenum - STARTSPRITES].height;\r
+ US_CenterWindow(30, (spriteheight+41)/8 + 1);\r
+ PrintY = WindowY + 2;\r
+ US_CPrint("What is the name of this creature?");\r
+\r
+ x = WindowX + (WindowW-spritewidth)/2 + info.x*8;\r
+ y = WindowY + 15;\r
+ if (info.shapenum == CEILICK1SPR)\r
+ {\r
+ y++;\r
+ }\r
+ else\r
+ {\r
+ y += info.y * 8;\r
+ }\r
+ VWB_DrawSprite(x, y, info.shapenum);\r
+\r
+ y = WindowY + WindowH - 16;\r
+ editwidth = 100;\r
+ x = WindowX + (WindowW - 100) / 2;\r
+ VWB_Bar(x, y, editwidth, 14, BLACK);\r
+ VWB_Bar(x+1, y+1, editwidth-2, 12, WHITE);\r
+ x += 2;\r
+ y += 2;\r
+ editwidth -= 8;\r
+ VW_UpdateScreen();\r
+\r
+ if (US_LineInput(x, y, strbuf, NULL, true, sizeof(strbuf), editwidth))\r
+ {\r
+ ptr = strbuf;\r
+ correct = true;\r
+ while (*name)\r
+ {\r
+ c = *ptr;\r
+ if ((islower(c)? _toupper(c) : c) != *name)\r
+ {\r
+ correct = false;\r
+ }\r
+\r
+ ptr++;\r
+ name++;\r
+ }\r
+ if (*ptr)\r
+ {\r
+ correct = false;\r
+ }\r
+\r
+ if (!correct)\r
+ {\r
+ VWB_Bar(0, 0, 320, 200, BackColor);\r
+ US_CenterWindow(35, 5);\r
+ PrintY += 11;\r
+ US_CPrint("Sorry, that's not quite right.");\r
+ US_CPrint("Please check your manual and try again.");\r
+ VW_UpdateScreen();\r
+ IN_Ack();\r
+ }\r
+ }\r
+\r
+ VWB_Bar(0, 0, 320, 200, BackColor);\r
+ CA_DownLevel();\r
+ checkpassed = correct;\r
+ return correct;\r
+}\r
+\r
+#endif
\ No newline at end of file