1 /* Catacomb Armageddon Source Code
\r
2 * Copyright (C) 1993-2014 Flat Rock Software
\r
4 * This program is free software; you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation; either version 2 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License along
\r
15 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
21 // ID_US.c - User Manager - User interface
\r
23 // By Jason Blochowiak
\r
24 // Hacked up for Catacomb 3D
\r
27 #include "ID_HEADS.H"
\r
33 extern boolean showscorebox;
\r
35 extern boolean oldshooting;
\r
36 extern ScanCode firescan;
\r
42 boolean ingame,abortgame,loadedgame;
\r
43 GameDiff restartgame = gd_Continue;
\r
45 // Internal variables
\r
46 static boolean GameIsDirty,
\r
50 // Forward reference prototypes
\r
51 static void USL_SetupCard(void);
\r
53 // Control panel data
\r
55 #define CtlPanelSX 74
\r
56 #define CtlPanelSY 48
\r
57 #define CtlPanelEX 234
\r
58 #define CtlPanelEY 150
\r
59 #define CtlPanelW (CtlPanelEX - CtlPanelSX)
\r
60 #define CtlPanelH (CtlPanelEY - CtlPanelSY)
\r
66 #define HiliteColor (BackColor ^ 12)
\r
67 #define NohiliteColor (BackColor ^ 4)
\r
83 uii_Button,uii_RadioButton,uii_Folder
\r
93 #define UISelectFlags (ui_Pushed | ui_Selected | ui_Disabled)
\r
97 uic_SetupCard,uic_DrawCard,uic_TouchupCard,
\r
98 uic_DrawIcon,uic_Draw,uic_Hit
\r
101 typedef struct UserItem
\r
108 void far *child; // Should be (UserItemGroup *)
\r
112 typedef struct UserItemGroup
\r
117 UserItem far *items;
\r
118 boolean (*custom)(UserCall,struct UserItem far *); // Custom routine
\r
121 struct UserItemGroup far *parent;
\r
124 static char *BottomS1,*BottomS2,*BottomS3;
\r
125 static UComm Communication;
\r
126 static ScanCode *KeyMaps[] =
\r
128 &KbdDefs[0].button0,
\r
129 &KbdDefs[0].button1,
\r
131 &KbdDefs[0].upleft,
\r
133 &KbdDefs[0].upright,
\r
135 &KbdDefs[0].downright,
\r
137 &KbdDefs[0].downleft,
\r
141 // Custom routine prototypes
\r
142 static boolean USL_ConfigCustom(UserCall call,struct UserItem far *item),
\r
143 USL_KeyCustom(UserCall call,struct UserItem far *item),
\r
144 USL_KeySCustom(UserCall call,struct UserItem far *item),
\r
145 USL_Joy1Custom(UserCall call,struct UserItem far *item),
\r
146 USL_Joy2Custom(UserCall call,struct UserItem far *item),
\r
147 USL_LoadCustom(UserCall call,struct UserItem far *item),
\r
148 USL_SaveCustom(UserCall call,struct UserItem far *item),
\r
149 USL_ScoreCustom(UserCall call,struct UserItem far *item),
\r
150 USL_CompCustom(UserCall call,struct UserItem far *item);
\r
152 USL_TwoCustom(UserCall call,struct UserItem far *item),
\r
154 // USL_PongCustom(UserCall call,struct UserItem far *item);
\r
156 #define DefButton(key,text) uii_Button,ui_Normal,key,text
\r
157 #define DefRButton(key,text) uii_RadioButton,ui_Normal,key,text
\r
158 #define DefFolder(key,text,child) uii_Folder,ui_Normal,key,text,uc_None,child
\r
159 #define CustomGroup(title,key,custom) 0,0,title,key,0,custom
\r
160 UserItem far holder[] =
\r
162 {DefButton(sc_None,"DEBUG")},
\r
165 UserItemGroup far holdergroup = {0,0,CP_MAINMENUPIC,sc_None,holder};
\r
168 UserItem far soundi[] =
\r
170 {DefRButton(sc_N,"NO SOUND EFFECTS")},
\r
171 {DefRButton(sc_P,"PC SPEAKER")},
\r
172 {DefRButton(sc_A,"ADLIB/SOUNDBLASTER")},
\r
175 UserItemGroup far soundgroup = {8,0,CP_SOUNDMENUPIC,sc_None,soundi};
\r
178 UserItem far musici[] =
\r
180 {DefRButton(sc_N,"NO MUSIC")},
\r
181 {DefRButton(sc_A,"ADLIB/SOUNDBLASTER")},
\r
184 UserItemGroup far musicgroup = {8,0,CP_MUSICMENUPIC,sc_None,musici};
\r
187 UserItem far newgamei[] =
\r
189 {DefButton(sc_E,"BEGIN EASY GAME"),uc_SEasy},
\r
190 {DefButton(sc_N,"BEGIN NORMAL GAME"),uc_SNormal},
\r
191 {DefButton(sc_H,"BEGIN HARD GAME"),uc_SHard},
\r
194 UserItemGroup far newgamegroup = {8,0,CP_NEWGAMEMENUPIC,sc_None,newgamei,0,1};
\r
196 // Load/Save game menu
\r
197 UserItem far loadsavegamei[] =
\r
199 {uii_Button,ui_Normal,sc_None},
\r
200 {uii_Button,ui_Normal,sc_None},
\r
201 {uii_Button,ui_Normal,sc_None},
\r
202 {uii_Button,ui_Normal,sc_None},
\r
203 {uii_Button,ui_Normal,sc_None},
\r
204 {uii_Button,ui_Normal,sc_None},
\r
207 UserItemGroup far loadgamegroup = {4,3,CP_LOADMENUPIC,sc_None,loadsavegamei,USL_LoadCustom};
\r
208 UserItemGroup far savegamegroup = {4,3,CP_SAVEMENUPIC,sc_None,loadsavegamei,USL_SaveCustom};
\r
211 UserItemGroup far scoregroup = {0,0,0,sc_None,0,USL_ScoreCustom};
\r
212 UserItemGroup far compgroup = {0,0,0,sc_None,0,USL_CompCustom};
\r
214 UserItemGroup far twogroup = {0,0,0,sc_None,0,USL_TwoCustom};
\r
216 UserItem far optionsi[] =
\r
218 {DefFolder(sc_S,"",&scoregroup)},
\r
219 {DefFolder(sc_C,"",&compgroup)},
\r
221 {DefFolder(sc_T,"",&twogroup)},
\r
225 UserItemGroup far optionsgroup = {8,0,CP_OPTIONSMENUPIC,sc_None,optionsi};
\r
228 UserItem far keyi[] =
\r
230 {DefButton(sc_None,"UP & LEFT")},
\r
231 {DefButton(sc_None,"UP")},
\r
232 {DefButton(sc_None,"UP & RIGHT")},
\r
233 {DefButton(sc_None,"RIGHT")},
\r
234 {DefButton(sc_None,"DOWN & RIGHT")},
\r
235 {DefButton(sc_None,"DOWN")},
\r
236 {DefButton(sc_None,"DOWN & LEFT")},
\r
237 {DefButton(sc_None,"LEFT")},
\r
240 UserItemGroup far keygroup = {0,0,CP_KEYMOVEMENTPIC,sc_None,keyi,USL_KeyCustom};
\r
241 UserItem far keybi[] =
\r
244 {DefButton(sc_J,"JUMP")},
\r
245 {DefButton(sc_P,"POGO")},
\r
246 {DefButton(sc_F,"FIRE")},
\r
249 {DefButton(sc_J,"FIRE")},
\r
250 {DefButton(sc_P,"STRAFE")},
\r
253 {DefButton(sc_J,"SHOOT")},
\r
254 {DefButton(sc_P,"BOMB")},
\r
258 UserItemGroup far keybgroup = {0,0,CP_KEYBUTTONPIC,sc_None,keybi,USL_KeyCustom};
\r
259 UserItem far keysi[] =
\r
261 {DefFolder(sc_M,"MOVEMENT",&keygroup)},
\r
262 {DefFolder(sc_B,"BUTTONS",&keybgroup)},
\r
265 UserItemGroup far keysgroup = {8,0,CP_KEYBOARDMENUPIC,sc_None,keysi,USL_KeySCustom};
\r
267 // Joystick #1 & #2
\r
268 UserItemGroup far joy1group = {CustomGroup(CP_JOYSTICKMENUPIC,sc_None,USL_Joy1Custom)};
\r
269 UserItemGroup far joy2group = {CustomGroup(CP_JOYSTICKMENUPIC,sc_None,USL_Joy2Custom)};
\r
272 UserItem far configi[] =
\r
274 {DefFolder(sc_S,"SOUND",&soundgroup)},
\r
275 {DefFolder(sc_M,"MUSIC",&musicgroup)},
\r
276 {uii_Folder,ui_Separated,sc_K,"USE KEYBOARD",uc_None,&keysgroup},
\r
277 {DefFolder(sc_None,"USE JOYSTICK #1",&joy1group)},
\r
278 {DefFolder(sc_None,"USE JOYSTICK #2",&joy2group)},
\r
281 UserItemGroup far configgroup = {8,0,CP_CONFIGMENUPIC,sc_None,configi,USL_ConfigCustom};
\r
284 // UserItemGroup far ponggroup = {0,0,0,sc_None,0,USL_PongCustom};
\r
285 UserItem far rooti[] =
\r
287 {DefFolder(sc_N,"NEW GAME",&newgamegroup)},
\r
288 {DefFolder(sc_L,"LOAD GAME",&loadgamegroup)},
\r
289 {DefFolder(sc_S,"SAVE GAME",&savegamegroup)},
\r
290 {DefFolder(sc_C,"CONFIGURE",&configgroup)},
\r
291 {DefButton(sc_R,nil),uc_Return}, // Return to Game/Demo
\r
292 {DefButton(sc_E,"END GAME"),uc_Abort},
\r
293 // {DefFolder(sc_B,"SKULL 'N' BONES",&ponggroup)},
\r
294 {DefButton(sc_Q,"QUIT"),uc_Quit},
\r
297 UserItemGroup far rootgroup = {32,4,CP_MAINMENUPIC,sc_None,rooti};
\r
303 UserItemGroup far *cardstack[MaxCards],
\r
308 USL_SetupStack(void)
\r
311 cardstack[0] = topcard = &rootgroup;
\r
320 topcard = cardstack[--cstackptr];
\r
324 USL_PushCard(UserItemGroup far *card)
\r
326 if (cstackptr == MaxCards - 1)
\r
329 topcard = cardstack[++cstackptr] = card;
\r
333 USL_DrawItemIcon(UserItem far *item)
\r
337 if (topcard->custom && topcard->custom(uic_DrawIcon,item))
\r
340 flags = item->flags;
\r
341 if (flags & ui_Disabled)
\r
342 tile = TileBase + ((flags & ui_Selected)? 5 : 4);
\r
343 else if ((item->type == uii_RadioButton) && (!(flags & ui_Pushed)))
\r
344 tile = TileBase + ((flags & ui_Selected)? 3 : 2);
\r
346 tile = TileBase + ((flags & ui_Selected)? 1 : 0);
\r
347 VWB_DrawTile8(item->x,item->y,tile);
\r
351 USL_DrawItem(UserItem far *item)
\r
353 if (topcard->custom && topcard->custom(uic_Draw,item))
\r
356 VWB_Bar(CtlPanelSX + 1,item->y,
\r
357 CtlPanelEX - CtlPanelSX - 1,8,BackColor); // Clear out background
\r
358 USL_DrawItemIcon(item);
\r
359 if ((item->flags & ui_Selected) && !(item->flags & ui_Disabled))
\r
360 fontcolor = HiliteColor;
\r
362 fontcolor = NohiliteColor;
\r
365 USL_DrawString(item->text);
\r
366 fontcolor = F_BLACK;
\r
369 #define MyLine(y) VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,y,12);
\r
372 USL_DrawBottom(void)
\r
376 fontcolor = NohiliteColor;
\r
378 px = CtlPanelSX + 4;
\r
379 py = CtlPanelEY - 15;
\r
380 USL_DrawString(BottomS1);
\r
382 USL_MeasureString(BottomS2,&w,&h);
\r
383 px = CtlPanelEX - 4 - w;
\r
384 USL_DrawString(BottomS2);
\r
386 USL_MeasureString(BottomS3,&w,&h);
\r
387 px = CtlPanelSX + ((CtlPanelEX - CtlPanelSX - w) / 2);
\r
389 USL_DrawString(BottomS3);
\r
391 fontcolor = F_WHITE;
\r
392 MyLine(CtlPanelEY - 17);
\r
396 USL_DrawCtlPanelContents(void)
\r
399 UserItem far *item;
\r
401 if (topcard->custom && topcard->custom(uic_DrawCard,nil))
\r
404 if (topcard->title)
\r
407 MyLine(CtlPanelSY + 7);
\r
408 VWB_DrawPic(CtlPanelSX + 6,CtlPanelSY,topcard->title);
\r
413 if (!topcard->items)
\r
416 x = topcard->x + CtlPanelSX;
\r
419 y = topcard->y + CtlPanelSY + 12;
\r
420 for (item = topcard->items;item->type != uii_Bad;item++)
\r
422 if (item->flags & ui_Separated)
\r
427 USL_DrawItem(item);
\r
430 if (topcard->custom)
\r
431 topcard->custom(uic_TouchupCard,nil);
\r
435 USL_DrawCtlPanel(void)
\r
437 if (topcard->items || topcard->title)
\r
439 // Draw the backdrop
\r
440 VWB_DrawPic(0,0,CP_MENUSCREENPIC);
\r
442 // Draw the contents
\r
443 USL_DrawCtlPanelContents();
\r
446 // Refresh the screen
\r
451 USL_DialogSetup(word w,word h,word *x,word *y)
\r
453 VWB_DrawMPic(CtlPanelSX,CtlPanelSY,CP_MENUMASKPICM);
\r
455 *x = CtlPanelSX + ((CtlPanelW - w) / 2);
\r
456 *y = CtlPanelSY + ((CtlPanelH - h) / 2);
\r
457 VWB_Bar(*x,*y,w + 1,h + 1,BackColor);
\r
458 VWB_Hlin(*x - 1,*x + w + 1,*y - 1,NohiliteColor);
\r
459 VWB_Hlin(*x - 1,*x + w + 1,*y + h + 1,NohiliteColor);
\r
460 VWB_Vlin(*y - 1,*y + h + 1,*x - 1,NohiliteColor);
\r
461 VWB_Vlin(*y - 1,*y + h + 1,*x + w + 1,NohiliteColor);
\r
465 USL_ShowLoadSave(char *s,char *name)
\r
470 char msg[MaxGameName + 4];
\r
475 USL_MeasureString(s,&sw,&h);
\r
476 USL_MeasureString(msg,&w,&h);
\r
477 tw = ((sw > w)? sw : w) + 6;
\r
478 USL_DialogSetup(tw,(h * 2) + 2,&x,&y);
\r
480 px = x + ((tw - sw) / 2);
\r
483 px = x + ((tw - w) / 2);
\r
484 USL_DrawString(msg);
\r
488 IN_UserInput(100, true);
\r
492 USL_CtlDialog(char *s1,char *s2,char *s3)
\r
498 CursorInfo cursorinfo;
\r
500 USL_MeasureString(s1,&w1,&h);
\r
501 USL_MeasureString(s2,&w2,&h);
\r
503 USL_MeasureString(s3,&w3,&h);
\r
506 w = (w1 > w2)? ((w1 > w3)? w1 : w3) : ((w2 > w3)? w2 : w3);
\r
511 USL_DialogSetup(w,h,&x,&y);
\r
513 fontcolor = HiliteColor;
\r
514 px = x + ((w - w1) / 2);
\r
516 USL_DrawString(s1);
\r
517 py += (sh * 2) - 1;
\r
519 VWB_Hlin(x + 3,x + w - 3,py,NohiliteColor);
\r
522 fontcolor = NohiliteColor;
\r
523 px = x + ((w - w2) / 2);
\r
524 USL_DrawString(s2);
\r
529 px = x + ((w - w3) / 2);
\r
530 USL_DrawString(s3);
\r
535 IN_ClearKeysDown();
\r
538 IN_ReadCursor(&cursorinfo);
\r
539 if (cursorinfo.button0)
\r
541 else if (cursorinfo.button1)
\r
545 } while (c == sc_None);
\r
548 IN_ReadCursor(&cursorinfo);
\r
549 } while (cursorinfo.button0 || cursorinfo.button1);
\r
551 IN_ClearKeysDown();
\r
552 USL_DrawCtlPanel();
\r
557 USL_ConfirmComm(UComm comm)
\r
559 boolean confirm,dialog;
\r
563 Quit("USL_ConfirmComm() - empty comm");
\r
567 s3 = "ESC TO BACK OUT";
\r
571 s1 = "REALLY END CURRENT GAME?";
\r
572 s2 = "PRESS Y TO END IT";
\r
573 if (ingame && GameIsDirty)
\r
577 s1 = "REALLY QUIT?";
\r
578 s2 = "PRESS Y TO QUIT";
\r
582 s1 = "YOU'RE IN A GAME";
\r
583 s2 = "PRESS Y TO LOAD GAME";
\r
584 if (ingame && GameIsDirty)
\r
590 s1 = "YOU'RE IN A GAME";
\r
591 s2 = "PRESS Y FOR NEW GAME";
\r
592 if (ingame && GameIsDirty)
\r
597 confirm = dialog? USL_CtlDialog(s1,s2,s3) : true;
\r
600 Communication = comm;
\r
601 CtlPanelDone = true;
\r
606 ///////////////////////////////////////////////////////////////////////////
\r
608 // USL_HandleError() - Handles telling the user that there's been an error
\r
610 ///////////////////////////////////////////////////////////////////////////
\r
612 USL_HandleError(int num)
\r
616 strcpy(buf,"Error: ");
\r
618 strcat(buf,"Unknown");
\r
619 else if (num == ENOMEM)
\r
620 strcat(buf,"Disk is Full");
\r
621 else if (num == EINVFMT)
\r
622 strcat(buf,"File is Incomplete");
\r
624 strcat(buf,sys_errlist[num]);
\r
628 USL_CtlDialog(buf,"PRESS ANY KEY",nil);
\r
631 IN_ClearKeysDown();
\r
641 USL_GenericCustom(UserCall call,UserItem far *item)
\r
654 USL_SetOptionsText(void)
\r
656 optionsi[0].text = showscorebox? "SCORE BOX (ON)" : "SCORE BOX (OFF)";
\r
657 optionsi[1].text = compatability? "SVGA COMPATIBILITY (ON)" : "SVGA COMPATIBILITY (OFF)";
\r
659 optionsi[2].text = oldshooting? "TWO-BUTTON FIRING (ON)" : "TWO-BUTTON FIRING (OFF)";
\r
661 keybi[2].flags &= ~ui_Disabled;
\r
663 keybi[2].flags |= ui_Disabled;
\r
669 USL_ScoreCustom(UserCall call,UserItem far *item)
\r
671 if (call != uic_SetupCard)
\r
674 showscorebox ^= true;
\r
675 USL_CtlDialog(showscorebox? "Score box now on" : "Score box now off",
\r
676 "Press any key",nil);
\r
677 USL_SetOptionsText();
\r
683 USL_CompCustom(UserCall call,UserItem far *item)
\r
685 if (call != uic_SetupCard)
\r
688 compatability ^= true;
\r
689 USL_CtlDialog(compatability? "SVGA compatibility now on" : "SVGA compatibility now off",
\r
690 "Press any key",nil);
\r
691 USL_SetOptionsText();
\r
698 USL_TwoCustom(UserCall call,UserItem far *item)
\r
700 if (call != uic_SetupCard)
\r
703 oldshooting ^= true;
\r
704 USL_CtlDialog(oldshooting? "Two-button firing now on" : "Two-button firing now off",
\r
705 "Press any key",nil);
\r
706 USL_SetOptionsText();
\r
712 USL_ConfigCustom(UserCall call,UserItem far *item)
\r
714 static char *CtlNames[] = {"KEYBOARD","KEYBOARD","JOYSTICK #1","JOYSTICK #2","MOUSE"};
\r
719 if (call == uic_TouchupCard)
\r
722 USL_MeasureString(s,&w,&h);
\r
724 USL_MeasureString(CtlNames[Controls[0]],&w,&h);
\r
726 py = CtlPanelEY - 18 - h;
\r
727 px = CtlPanelSX + ((CtlPanelW - tw) / 2);
\r
728 fontcolor = NohiliteColor;
\r
730 USL_DrawString(CtlNames[Controls[0]]);
\r
732 item++; // Shut the compiler up
\r
737 USL_CKSetKey(UserItem far *item,word i)
\r
743 CursorInfo cursorinfo;
\r
747 LastScan = sc_None;
\r
748 fontcolor = HiliteColor;
\r
751 if (TimeCount >= time)
\r
754 VWB_Bar(item->x + 90,item->y,40,8,fontcolor ^ BackColor);
\r
755 VWB_Bar(item->x + 90 + 1,item->y + 1,40 - 2,8 - 2,BackColor);
\r
757 VWB_DrawTile8(item->x + 90 + 16,item->y,TileBase + 8);
\r
760 time = TimeCount + (TickBase / 2);
\r
763 IN_ReadCursor(&cursorinfo);
\r
764 while (cursorinfo.button0 || cursorinfo.button1)
\r
766 IN_ReadCursor(&cursorinfo);
\r
767 LastScan = sc_Escape;
\r
772 if (LastScan == sc_LShift)
\r
773 LastScan = sc_None;
\r
775 } while (!(scan = LastScan));
\r
777 if (scan != sc_Escape)
\r
779 for (j = 0,on = false;j < 11;j++)
\r
783 if (*(KeyMaps[j]) == scan)
\r
790 USL_CtlDialog("Key already used","Press a key",nil);
\r
792 *(KeyMaps[i]) = scan;
\r
794 IN_ClearKeysDown();
\r
799 USL_KeySCustom(UserCall call,UserItem far *item)
\r
801 if (call == uic_SetupCard)
\r
802 Controls[0] = ctrl_Keyboard;
\r
808 USL_KeyCustom(UserCall call,UserItem far *item)
\r
814 i = (topcard == &keygroup)? (3 + (item - keyi)) : (item - keybi);
\r
817 case uic_SetupCard:
\r
818 Controls[0] = ctrl_Keyboard;
\r
821 VWB_Bar(CtlPanelSX + 1,item->y,
\r
822 CtlPanelEX - CtlPanelSX - 1,8,BackColor); // Clear out background
\r
823 USL_DrawItemIcon(item);
\r
824 fontcolor = (item->flags & ui_Selected)? HiliteColor : NohiliteColor;
\r
827 USL_DrawString(item->text);
\r
828 VWB_Bar(item->x + 90,item->y,40,8,fontcolor ^ BackColor);
\r
829 VWB_Bar(item->x + 90 + 1,item->y + 1,40 - 2,8 - 2,BackColor);
\r
830 px = item->x + 90 + 6;
\r
832 USL_DrawString(IN_GetScanName(*KeyMaps[i]));
\r
836 USL_KeyCustom(uic_Draw,item);
\r
837 USL_CKSetKey(item,i);
\r
838 USL_DrawCtlPanel();
\r
846 USL_CJDraw(char *s1,char *s2)
\r
850 USL_MeasureString(s1,&w,&h);
\r
851 px = CtlPanelSX + ((CtlPanelW - w) / 2);
\r
852 py = CtlPanelEY - 34;
\r
853 VWB_Bar(CtlPanelSX + 1,py,CtlPanelW - 2,h * 2,BackColor);
\r
854 fontcolor = HiliteColor;
\r
855 USL_DrawString(s1);
\r
857 USL_MeasureString(s2,&w,&h);
\r
858 px = CtlPanelSX + ((CtlPanelW - w) / 2);
\r
859 USL_DrawString(s2);
\r
863 USL_CJGet(word joy,word button,word x,word y,word *xaxis,word *yaxis)
\r
868 while (IN_GetJoyButtonsDB(joy))
\r
869 if (LastScan == sc_Escape)
\r
874 while (!(IN_GetJoyButtonsDB(joy) & (1 << button)))
\r
876 if (TimeCount >= time)
\r
879 time = TimeCount + (TickBase / 2);
\r
880 VWB_DrawTile8(x,y,TileBase + on);
\r
884 if (LastScan == sc_Escape)
\r
887 IN_GetJoyAbs(joy,xaxis,yaxis);
\r
892 USL_ConfigJoystick(word joy)
\r
898 BottomS1 = BottomS2 = "";
\r
899 BottomS3 = "Esc to back out";
\r
900 USL_DrawCtlPanel();
\r
901 x = CtlPanelSX + 60;
\r
902 y = CtlPanelSY + 19;
\r
903 VWB_DrawPic(x,y,CP_JOYSTICKPIC);
\r
905 USL_CJDraw("Move Joystick to upper left","and press button #1");
\r
906 VWB_DrawTile8(x + 24,y + 8,TileBase + 6);
\r
907 VWB_DrawTile8(x + 8,y + 8,TileBase + 1);
\r
908 VWB_DrawTile8(x + 8,y + 24,TileBase + 0);
\r
910 if (!USL_CJGet(joy,0,x + 8,y + 8,&minx,&miny))
\r
913 USL_CJDraw("Move Joystick to lower right","and press button #2");
\r
914 VWB_DrawTile8(x + 24,y + 8,TileBase - 25);
\r
915 VWB_DrawTile8(x + 40,y + 24,TileBase + 7);
\r
916 VWB_DrawTile8(x + 8,y + 8,TileBase + 0);
\r
917 VWB_DrawTile8(x + 8,y + 24,TileBase + 1);
\r
919 if (!USL_CJGet(joy,1,x + 8,y + 24,&maxx,&maxy))
\r
922 while (IN_GetJoyButtonsDB(joy))
\r
925 IN_SetupJoy(joy,minx,maxx,miny,maxy);
\r
931 USL_Joy1Custom(UserCall call,UserItem far *item)
\r
933 if (call == uic_SetupCard)
\r
935 if (USL_ConfigJoystick(0))
\r
937 Controls[0] = ctrl_Joystick1;
\r
938 USL_CtlDialog("USING JOYSTICK #1","PRESS ANY KEY",nil);
\r
948 USL_Joy2Custom(UserCall call,UserItem far *item)
\r
950 if (call == uic_SetupCard)
\r
952 if (USL_ConfigJoystick(1))
\r
954 Controls[0] = ctrl_Joystick2;
\r
955 USL_CtlDialog("USING JOYSTICK #2","PRESS ANY KEY",nil);
\r
964 USL_DrawFileIcon(UserItem far *item)
\r
968 item->y = topcard->y + CtlPanelSY + 12;
\r
969 item->y += (item - loadsavegamei) * 11;
\r
971 fontcolor = (item->flags & ui_Selected)? HiliteColor : NohiliteColor;
\r
972 color = fontcolor ^ BackColor; // Blech!
\r
973 VWB_Hlin(item->x,item->x + (CtlPanelW - 12),item->y,color);
\r
974 VWB_Hlin(item->x,item->x + (CtlPanelW - 12),item->y + 9,color);
\r
975 VWB_Vlin(item->y,item->y + 9,item->x,color);
\r
976 VWB_Vlin(item->y,item->y + 9,item->x + (CtlPanelW - 12),color);
\r
980 USL_DoLoadGame(UserItem far *item)
\r
988 if (!USL_ConfirmComm(uc_Loaded))
\r
991 n = item - loadsavegamei;
\r
994 USL_ShowLoadSave("Loading",game->name);
\r
997 filename = USL_GiveSaveName(n);
\r
998 if ((file = open(filename,O_BINARY | O_RDONLY)) != -1)
\r
1000 if (read(file,game,sizeof(*game)) == sizeof(*game))
\r
1003 if (!USL_LoadGame(file))
\r
1004 USL_HandleError(err = errno);
\r
1007 USL_HandleError(err = errno);
\r
1011 USL_HandleError(err = errno);
\r
1015 Communication = uc_None;
\r
1016 CtlPanelDone = false;
\r
1019 loadedgame = true;
\r
1020 game->present = true;
\r
1025 USL_DrawCtlPanel();
\r
1029 USL_LoadCustom(UserCall call,UserItem far *item)
\r
1037 case uic_SetupCard:
\r
1038 for (i = 0;i < MaxSaveGames;i++)
\r
1040 if (Games[i].present)
\r
1041 loadsavegamei[i].flags &= ~ui_Disabled;
\r
1043 loadsavegamei[i].flags |= ui_Disabled;
\r
1046 case uic_DrawIcon:
\r
1047 USL_DrawFileIcon(item);
\r
1051 USL_DrawFileIcon(item);
\r
1052 VWB_Bar(item->x + 1,item->y + 2,CtlPanelW - 12 - 2,7,BackColor);
\r
1054 i = item - loadsavegamei;
\r
1055 if (Games[i].present)
\r
1058 px = item->x + 60;
\r
1060 USL_DrawString(Games[i].present? Games[i].name : "Empty");
\r
1064 USL_DoLoadGame(item);
\r
1072 USL_DoSaveGame(UserItem far *item)
\r
1080 BottomS1 = "Type name";
\r
1081 BottomS2 = "Enter accepts";
\r
1082 USL_DrawCtlPanel();
\r
1084 n = item - loadsavegamei;
\r
1086 fontcolor = HiliteColor;
\r
1087 VWB_Bar(item->x + 1,item->y + 2,CtlPanelW - 12 - 2,7,BackColor);
\r
1088 game->oldtest = &PrintX;
\r
1089 ok = US_LineInput(item->x + 2,item->y + 2,
\r
1090 game->name,game->present? game->name : nil,
\r
1093 if (!strlen(game->name))
\r
1094 strcpy(game->name,"Untitled");
\r
1097 USL_ShowLoadSave("Saving",game->name);
\r
1099 filename = USL_GiveSaveName(n);
\r
1101 file = open(filename,O_CREAT | O_BINARY | O_WRONLY,
\r
1102 S_IREAD | S_IWRITE | S_IFREG);
\r
1105 if (write(file,game,sizeof(*game)) == sizeof(*game))
\r
1108 ok = USL_SaveGame(file);
\r
1110 USL_HandleError(err = errno);
\r
1113 USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));
\r
1117 USL_HandleError(err = ((errno == ENOENT)? ENOMEM : errno));
\r
1126 if (!game->present)
\r
1127 game->present = ok;
\r
1130 GameIsDirty = false;
\r
1135 USL_SaveCustom(UserCall call,UserItem far *item)
\r
1141 case uic_SetupCard:
\r
1142 for (i = 0;i < MaxSaveGames;i++)
\r
1143 loadsavegamei[i].flags &= ~ui_Disabled;
\r
1146 USL_DoSaveGame(item);
\r
1150 return(USL_LoadCustom(call,item));
\r
1155 #define PaddleMinX (CtlPanelSX + 3)
\r
1156 #define PaddleMaxX (CtlPanelEX - 15)
\r
1157 #define BallMinX (CtlPanelSX + 2)
\r
1158 #define BallMinY (CtlPanelSY + 12 + 2)
\r
1159 #define BallMaxX (CtlPanelEX - 6)
\r
1160 #define BallMaxY (CtlPanelEY - 13)
\r
1161 #define CPaddleY (BallMinY + 4)
\r
1162 #define KPaddleY (BallMaxY - 2)
\r
1164 USL_DrawPongScore(word k,word c)
\r
1166 fontcolor = HiliteColor;
\r
1167 PrintY = py = CtlPanelSY + 4;
\r
1168 px = CtlPanelSX + 6;
\r
1169 VWB_Bar(px,py,42,6,BackColor);
\r
1170 USL_DrawString("YOU:");
\r
1172 US_PrintUnsigned(k);
\r
1173 px = CtlPanelSX + 108;
\r
1174 VWB_Bar(px,py,50,6,BackColor);
\r
1175 USL_DrawString("COMP:");
\r
1177 US_PrintUnsigned(c);
\r
1181 USL_PlayPong(void)
\r
1183 boolean ball,killball,revdir,done,lastscore;
\r
1192 longword balltime,waittime;
\r
1193 CursorInfo cursorinfo;
\r
1195 kx = cx = PaddleMinX + ((PaddleMaxX - PaddleMinX) / 2);
\r
1196 bx = by = bdx = bdy = 0;
\r
1197 kscore = cscore = 0;
\r
1198 USL_DrawPongScore(0,0);
\r
1203 lastscore = false;
\r
1206 waittime = TimeCount;
\r
1208 IN_ReadCursor(&cursorinfo);
\r
1209 if (((cursorinfo.x < 0) || IN_KeyDown(sc_LeftArrow)) && (kx > PaddleMinX))
\r
1211 else if (((cursorinfo.x > 0) || IN_KeyDown(sc_RightArrow)) && (kx < PaddleMaxX))
\r
1217 balltime = TimeCount + TickBase;
\r
1222 if (ball && (cycle++ % 3))
\r
1226 x += (US_RndT() & 1);
\r
1228 if ((cx + 6 < x) && (cx < PaddleMaxX))
\r
1230 else if ((cx + 6 > x) && (cx > PaddleMinX))
\r
1234 VWB_Bar(BallMinX,BallMinY - 1,
\r
1235 BallMaxX - BallMinX + 5,BallMaxY - BallMinY + 7,
\r
1237 VWB_DrawSprite(cx,CPaddleY,PADDLESPR);
\r
1238 VWB_DrawSprite(kx,KPaddleY,PADDLESPR);
\r
1243 (((bx + bdx) >> 2) > BallMaxX)
\r
1244 || (((bx + bdx) >> 2) < BallMinX)
\r
1247 SD_PlaySound(BALLBOUNCESND);
\r
1252 if (((by + bdy) >> 2) > BallMaxY)
\r
1255 lastscore = false;
\r
1257 SD_PlaySound(COMPSCOREDSND);
\r
1258 USL_DrawPongScore(kscore,cscore);
\r
1261 USL_CtlDialog("You lost!","Press any key",nil);
\r
1266 else if (((by + bdy) >> 2) < BallMinY)
\r
1271 SD_PlaySound(KEENSCOREDSND);
\r
1272 USL_DrawPongScore(kscore,cscore);
\r
1275 USL_CtlDialog("You won!","Press any key",nil);
\r
1289 && ((y >= CPaddleY) && (y < CPaddleY + 3))
\r
1290 && ((x >= (cx - 5)) && (x < (cx + 11)))
\r
1295 SD_PlaySound(COMPPADDLESND);
\r
1300 && ((y >= (KPaddleY - 3)) && (y < KPaddleY))
\r
1301 && ((x >= (kx - 5)) && (x < (kx + 11)))
\r
1304 if (((bdy >> 2) < 3) && !(--speedup))
\r
1311 SD_PlaySound(KEENPADDLESND);
\r
1316 bdx = ((x + 5 - rx) >> 1) - (1 << 2);
\r
1322 VWB_DrawSprite(x,y,(x & 1)? BALL1PIXELTOTHERIGHTSPR : BALLSPR);
\r
1324 else if (TimeCount >= balltime)
\r
1327 bdx = 1 - (US_RndT() % 3);
\r
1331 bx = (BallMinX + ((BallMaxX - BallMinX) / 2)) << 2;
\r
1332 by = (BallMinY + ((BallMaxY - BallMinY) / 2)) << 2;
\r
1334 VW_UpdateScreen();
\r
1335 while (waittime == TimeCount)
\r
1336 ; // DEBUG - do adaptiveness
\r
1337 } while ((LastScan != sc_Escape) && !done);
\r
1338 IN_ClearKeysDown();
\r
1343 USL_PongCustom(UserCall call,struct UserItem far *item)
\r
1345 if (call != uic_SetupCard)
\r
1348 VWB_DrawPic(0,0,CP_MENUSCREENPIC);
\r
1349 VWB_DrawPic(CtlPanelSX + 56,CtlPanelSY,CP_PADDLEWARPIC);
\r
1350 VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelSY + 12,HiliteColor ^ BackColor);
\r
1351 VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelEY - 7,HiliteColor ^ BackColor);
\r
1359 // Flag management stuff
\r
1361 USL_ClearFlags(UserItemGroup far *node)
\r
1368 for (i = node->items;i->type != uii_Bad;i++)
\r
1370 i->flags &= ~UISelectFlags;
\r
1372 USL_ClearFlags((UserItemGroup far *)i->child);
\r
1377 USL_FindPushedItem(UserItemGroup far *group)
\r
1380 UserItem far *item;
\r
1382 for (item = group->items,i = 0;item->type != uii_Bad;item++,i++)
\r
1383 if (item->flags & ui_Pushed)
\r
1389 USL_SelectItem(UserItemGroup far *group,word index,boolean draw)
\r
1391 UserItem far *item;
\r
1393 if (index != group->cursor)
\r
1395 item = &group->items[group->cursor];
\r
1396 item->flags &= ~ui_Selected;
\r
1398 USL_DrawItem(item);
\r
1401 group->cursor = index;
\r
1402 item = &group->items[group->cursor];
\r
1403 group->items[group->cursor].flags |= ui_Selected;
\r
1405 USL_DrawItem(item);
\r
1409 USL_PushItem(UserItemGroup far *group,word index,boolean draw)
\r
1412 UserItem far *item;
\r
1414 USL_SelectItem(group,index,draw);
\r
1415 for (item = group->items,i = 0;item->type != uii_Bad;item++,i++)
\r
1417 if (item->type != uii_RadioButton)
\r
1422 item->flags |= ui_Pushed;
\r
1424 USL_DrawItem(item);
\r
1426 else if (item->flags & ui_Pushed)
\r
1428 item->flags &= ~ui_Pushed;
\r
1430 USL_DrawItem(item);
\r
1436 USL_NextItem(void)
\r
1438 if (topcard->items[topcard->cursor + 1].type == uii_Bad)
\r
1440 USL_SelectItem(topcard,topcard->cursor + 1,true);
\r
1444 USL_PrevItem(void)
\r
1446 if (!topcard->cursor)
\r
1448 USL_SelectItem(topcard,topcard->cursor - 1,true);
\r
1452 USL_SetupCard(void)
\r
1454 BottomS1 = "Arrows move";
\r
1455 BottomS2 = "Enter selects";
\r
1456 BottomS3 = cstackptr? "ESC to back out" : "ESC to quit";
\r
1458 USL_SelectItem(topcard,topcard->cursor,false);
\r
1459 USL_DrawCtlPanel(); // Contents?
\r
1463 USL_DownLevel(UserItemGroup far *group)
\r
1466 Quit("USL_DownLevel() - nil card");
\r
1467 USL_PushCard(group);
\r
1468 if (group->custom && group->custom(uic_SetupCard,nil))
\r
1478 USL_ConfirmComm(uc_Quit);
\r
1482 if (topcard->items)
\r
1483 topcard->items[topcard->cursor].flags &= ~ui_Selected;
\r
1491 // DEBUG - finish this routine
\r
1492 UserItem far *item;
\r
1494 item = &topcard->items[topcard->cursor];
\r
1495 if (item->flags & ui_Disabled)
\r
1496 SD_PlaySound(NOWAYSND);
\r
1499 switch (item->type)
\r
1502 if (!(topcard->custom && topcard->custom(uic_Hit,item)))
\r
1503 USL_ConfirmComm(item->comm);
\r
1505 case uii_RadioButton:
\r
1506 USL_PushItem(topcard,topcard->cursor,true);
\r
1509 USL_DownLevel(item->child);
\r
1516 USL_SetControlValues(void)
\r
1518 USL_PushItem(&soundgroup,SoundMode,false);
\r
1519 USL_PushItem(&musicgroup,MusicMode,false);
\r
1520 if (!AdLibPresent)
\r
1522 soundi[2].flags |= ui_Disabled; // AdLib sound effects
\r
1523 musici[1].flags |= ui_Disabled; // AdLib music
\r
1526 if (!JoysPresent[0])
\r
1527 configi[3].flags |= ui_Disabled;
\r
1528 if (!JoysPresent[1])
\r
1529 configi[4].flags |= ui_Disabled;
\r
1531 rooti[4].text = ingame? "RETURN TO GAME" : "RETURN TO DEMO";
\r
1534 rooti[2].flags |= ui_Disabled; // Save Game
\r
1535 rooti[5].flags |= ui_Disabled; // End Game
\r
1537 rootgroup.cursor = ingame? 4 : 0;
\r
1538 USL_SetOptionsText();
\r
1539 // DEBUG - write the rest of this
\r
1542 ///////////////////////////////////////////////////////////////////////////
\r
1544 // USL_SetUpCtlPanel() - Sets the states of the UserItems to reflect the
\r
1545 // values of all the appropriate variables
\r
1547 ///////////////////////////////////////////////////////////////////////////
\r
1549 USL_SetUpCtlPanel(void)
\r
1553 // Cache in all of the stuff for the control panel
\r
1555 for (i = CONTROLS_LUMP_START;i <= CONTROLS_LUMP_END;i++)
\r
1556 CA_MarkGrChunk(i);
\r
1557 // for (i = PADDLE_LUMP_START;i <= PADDLE_LUMP_END;i++)
\r
1558 // CA_MarkGrChunk(i);
\r
1559 CA_MarkGrChunk(STARTFONT+1); // Little font
\r
1560 CA_MarkGrChunk(CP_MENUMASKPICM); // Mask for dialogs
\r
1561 CA_CacheMarks("Control Panel");
\r
1562 CA_LoadAllSounds();
\r
1564 // Do some other setup
\r
1566 US_SetPrintRoutines(VW_MeasurePropString,VWB_DrawPropString);
\r
1567 fontcolor = F_BLACK;
\r
1568 VW_Bar (0,0,320,200,3); // CAT3D patch
\r
1570 VW_InitDoubleBuffer();
\r
1572 Communication = uc_None;
\r
1573 USL_ClearFlags(&rootgroup);
\r
1574 USL_SetControlValues();
\r
1579 GameIsDirty = true;
\r
1581 IN_ClearKeysDown();
\r
1585 USL_HandleComm(UComm comm)
\r
1599 restartgame = gd_Easy;
\r
1602 restartgame = gd_Normal;
\r
1605 restartgame = gd_Hard;
\r
1609 Quit("USL_HandleComm() - unknown");
\r
1615 USL_GetControlValues(void)
\r
1619 // DEBUG - write the rest of this
\r
1620 i = USL_FindPushedItem(&soundgroup);
\r
1621 if (i != SoundMode)
\r
1622 SD_SetSoundMode(i);
\r
1624 i = USL_FindPushedItem(&musicgroup);
\r
1625 if (i != MusicMode)
\r
1626 SD_SetMusicMode(i);
\r
1629 ///////////////////////////////////////////////////////////////////////////
\r
1631 // USL_TearDownCtlPanel() - Given the state of the control panel, sets the
\r
1632 // modes and values as appropriate
\r
1634 ///////////////////////////////////////////////////////////////////////////
\r
1636 USL_TearDownCtlPanel(void)
\r
1638 USL_GetControlValues();
\r
1639 if (Communication)
\r
1640 USL_HandleComm(Communication);
\r
1642 fontnumber = 0; // Normal font
\r
1643 fontcolor = F_BLACK;
\r
1644 if (restartgame && USL_ResetGame)
\r
1646 else if (QuitToDos)
\r
1652 US_CenterWindow(20,3);
\r
1653 fontcolor = F_SECONDCOLOR;
\r
1654 US_PrintCentered("Quitting...");
\r
1655 fontcolor = F_BLACK;
\r
1656 VW_UpdateScreen();
\r
1661 IN_ClearKeysDown();
\r
1662 SD_WaitSoundDone();
\r
1663 VW_Bar (0,0,320,200,3); // CAT3D patch
\r
1665 CA_LoadAllSounds();
\r
1668 ///////////////////////////////////////////////////////////////////////////
\r
1670 // US_ControlPanel() - This is the main routine for the control panel
\r
1672 ///////////////////////////////////////////////////////////////////////////
\r
1673 #define MoveMin 40
\r
1675 US_ControlPanel(void)
\r
1677 extern void HelpScreens(void);
\r
1679 boolean resetitem,on;
\r
1682 longword flashtime;
\r
1683 UserItem far *item;
\r
1684 CursorInfo cursorinfo;
\r
1689 USL_SetUpCtlPanel();
\r
1690 Communication = uc_Loaded;
\r
1691 CtlPanelDone = true;
\r
1692 loadedgame = true;
\r
1693 USL_TearDownCtlPanel();
\r
1698 if ((LastScan < sc_F1) || (LastScan > sc_F10))
\r
1699 IN_ClearKeysDown();
\r
1701 USL_SetUpCtlPanel();
\r
1702 USL_DrawCtlPanel();
\r
1705 for (CtlPanelDone = false,resetitem = on = true;!CtlPanelDone;)
\r
1707 item = &(topcard->items[topcard->cursor]);
\r
1711 flashtime = TimeCount + (TickBase / 2);
\r
1712 resetitem = false;
\r
1715 if (TimeCount >= flashtime)
\r
1720 item->flags &= ~ui_Selected;
\r
1721 USL_DrawItemIcon(item);
\r
1722 item->flags |= ui_Selected;
\r
1725 VW_UpdateScreen();
\r
1735 case sc_DownArrow:
\r
1750 USL_DrawCtlPanel();
\r
1760 (LastScan == KbdDefs[0].button0)
\r
1761 || (LastScan == KbdDefs[0].button1)
\r
1771 for (item = topcard->items,i = 0;item->type != uii_Bad;item++,i++)
\r
1773 if (item->hotkey == LastScan)
\r
1775 USL_SelectItem(topcard,i,true);
\r
1782 IN_ClearKeysDown();
\r
1786 IN_ReadCursor(&cursorinfo);
\r
1787 ydelta += cursorinfo.y;
\r
1788 if (cursorinfo.button0)
\r
1792 IN_ReadCursor(&cursorinfo);
\r
1793 } while (cursorinfo.button0);
\r
1797 else if (cursorinfo.button1)
\r
1801 IN_ReadCursor(&cursorinfo);
\r
1802 } while (cursorinfo.button1);
\r
1806 else if (ydelta < -MoveMin)
\r
1808 ydelta += MoveMin;
\r
1812 else if (ydelta > MoveMin)
\r
1814 ydelta -= MoveMin;
\r
1821 USL_TearDownCtlPanel();
\r