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