convert line ends
[canaan.git] / prj / cam / src / deepc / ui / dpcmenu.cpp
blob68e69be1a0487ee171d54aa84ee68849abeb1980
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 ////////////////////////////////////////////////////////////
7 // Deep Cover METAGAME MENUS
8 //
10 #include <dpcmenu.h>
11 #include <appagg.h>
12 #include <drkpanl.h>
13 #include <dpcoptmn.h>
14 #include <dpcsavui.h>
15 #include <dpcnetui.h>
17 #include <resapi.h>
18 #include <imgrstyp.h>
19 #include <schema.h>
21 #include <drawelem.h>
22 #include <gcompose.h>
23 #include <questapi.h>
24 #include <drkdiff.h>
25 #include <config.h>
26 #include <uigame.h>
28 #include <panltool.h>
29 #include <appapi.h>
30 #include <mprintf.h>
31 #include <campaign.h>
32 #include <metasnd.h>
34 #include <command.h>
35 #include <uiamov.h>
36 #include <uianim.h>
38 #include <netman.h>
40 #include <dpcmulti.h>
41 #include <dpcgame.h>
42 #include <dpcutils.h>
43 #include <playrobj.h>
44 #include <dpclding.h>
45 #include <dpcpgapi.h>
48 #include <netsynch.h>
52 // Base Menu class
54 // Some day, I expect this will
55 // deal with levers and other festoonery
58 class cMenuBase: public cDarkPanel, public cUiAnim
60 public:
61 cMenuBase(const sDarkPanelDesc* desc)
62 : cDarkPanel(desc), cUiAnim(desc->panel_name,INTERFACE_PATH)
66 ~cMenuBase() {};
68 protected:
69 void InitUI()
71 cDarkPanel::InitUI();
72 cUiAnim::InitUI();
75 void TermUI()
77 cUiAnim::TermUI();
78 cDarkPanel::TermUI();
81 void OnLoopMsg(eLoopMessage msg, tLoopMessageData data)
83 cUiAnim::OnLoopMsg(msg,data);
84 cDarkPanel::OnLoopMsg(msg,data);
88 //------------------------------------------------------------
89 // MAIN MENU
92 // Avoid name conflicts
93 class cDPCMainMenu;
94 typedef cDPCMainMenu cMainMenu;
96 EXTERN void SwitchToDPCNewGameMode(BOOL push);
99 class cDPCMainMenu: public cMenuBase
101 static sDarkPanelDesc gDesc;
103 public:
104 cMainMenu() : cMenuBase(&gDesc)
108 cMainMenu(const sDarkPanelDesc* pdesc) : cMenuBase(pdesc)
113 enum eRects
115 kNewGame,
116 kLoadGame,
117 kOptions,
118 kCredits,
119 kIntro,
120 kQuit,
122 kNumRects
126 protected:
128 void OnButtonList(ushort action, int button)
130 if (!(action & BUTTONGADG_LCLICK))
131 return ;
133 //SchemaPlay((Label *)"menubutt",NULL);
135 switch (button)
137 case kNewGame:
138 SwitchToDPCNewGameMode(TRUE);
139 break;
141 case kLoadGame:
142 SwitchToDPCLoadGameMode(TRUE);
143 break;
145 case kOptions:
146 SwitchToDPCOptionsMode(TRUE);
147 break;
149 case kCredits:
150 MoviePanel("credits.avi");
151 break;
153 case kIntro:
154 MoviePanel("cs1.avi");
155 break;
157 case kQuit:
159 AutoAppIPtr_(Application,pApp);
160 pApp->Quit();
161 return;
163 break;
171 void OnEscapeKey() // trap escape
177 // Main Menu descriptor
180 static const char* main_button_names[] =
182 "new_game",
183 "load_game",
184 "options",
185 "credits",
186 "intro",
187 "quit",
190 sDarkPanelDesc cMainMenu::gDesc =
192 "main",
193 cMainMenu::kNumRects,
194 cMainMenu::kNumRects,
195 cMainMenu::kNumRects,
196 main_button_names,
197 NULL, // font
199 kMetaSndPanelMain,
202 //------------------------------------------------------------
203 // NET MAIN MENU
206 class cDPCNetMainMenu: public cDPCMainMenu
208 static sDarkPanelDesc gDesc;
209 typedef cDPCMainMenu cParent;
211 public:
212 cDPCNetMainMenu() : cParent(&gDesc)
216 enum eRects
218 kNewGame,
219 kLoadGame,
220 kOptions,
221 kCredits,
222 kIntro,
223 kQuit,
224 kMultiPlayer,
226 kNumRects
230 protected:
232 void OnButtonList(ushort action, int button)
234 if (!(action & BUTTONGADG_LCLICK))
235 return ;
237 switch (button)
239 case kMultiPlayer:
240 SwitchToDPCMultiplayUIMode(TRUE);
241 break;
243 default:
244 cParent::OnButtonList(action,button);
245 break;
250 void OnLoopMsg(eLoopMessage msg, tLoopMessageData data)
252 cParent::OnLoopMsg(msg,data);
253 switch (msg)
255 case kMsgEnterMode:
256 case kMsgResumeMode:
258 // Disconnect any net session we may be in
259 AutoAppIPtr(NetManager);
260 pNetManager->Leave();
261 // If we had network synch disabled, make sure it's normal
262 // again:
263 NetSynchEnable();
265 break;
274 // Main Menu descriptor
277 static const char* netmain_button_names[] =
279 "new_game",
280 "load_game",
281 "options",
282 "credits",
283 "intro",
284 "quit",
285 "multiplayer",
288 sDarkPanelDesc cDPCNetMainMenu::gDesc =
290 "netmain",
291 cDPCNetMainMenu::kNumRects,
292 cDPCNetMainMenu::kNumRects,
293 cDPCNetMainMenu::kNumRects,
294 netmain_button_names,
295 NULL, // font
297 kMetaSndPanelMain,
303 static cMainMenu* gpMainMenu = NULL;
305 void SwitchToDPCMainMenuMode(BOOL push)
307 if (gpMainMenu)
309 cAutoIPtr<IPanelMode> panel = gpMainMenu->GetPanelMode();
310 panel->Switch((push) ? kLoopModePush : kLoopModeSwitch);
315 const sLoopInstantiator* DescribeDPCMainMenuMode(void)
317 if (gpMainMenu)
319 cAutoIPtr<IPanelMode> panel = gpMainMenu->GetPanelMode();
320 return panel->Instantiator();
322 return NULL;
325 //------------------------------------------------------------
326 // SIM MENU
329 // Avoid name conflicts
330 class cDPCSimMenu;
331 typedef cDPCSimMenu cSimMenu;
333 class cDPCSimMenu: public cMenuBase
335 static sDarkPanelDesc gDesc;
337 public:
338 cSimMenu() : cMenuBase(&gDesc)
342 enum eRects
344 kContinue,
345 kOptions,
346 kSaveGame,
347 kLoadGame,
348 kQuit,
350 kNumRects
353 protected:
355 void OnButtonList(ushort action, int button)
357 if (!(action & BUTTONGADG_LCLICK))
358 return ;
360 //SchemaPlay((Label *)"menubutt",NULL);
362 AutoAppIPtr(NetManager);
364 switch (button)
366 case kContinue:
368 cAutoIPtr<IPanelMode> mode = GetPanelMode();
369 mode->Exit();
371 break;
374 case kOptions:
375 SwitchToDPCOptionsMode(TRUE);
376 break;
378 case kSaveGame:
379 if (pNetManager->IsNetworkGame())
381 char levelname[64];
382 DPCGetLevelName(levelname,sizeof(levelname));
383 // okay this is hack-a-riffic
384 if ((stricmp(levelname,"station") == 0) || (stricmp(levelname,"earth") == 0))
385 break;
387 SwitchToDPCSaveGameMode(TRUE);
388 break;
390 case kLoadGame:
391 SwitchToDPCLoadGameMode(TRUE);
392 break;
394 case kQuit:
396 if (gpMainMenu)
398 // Unwind to the main menu
399 cAutoIPtr<IPanelMode> panel = gpMainMenu->GetPanelMode();
400 panel->Switch(kLoopModeUnwindTo);
405 break;
407 default:
408 Warning(("%s button is unimplemented\n",gDesc.string_names[button]));
409 break;
416 // Sim Menu descriptor
419 static const char* sim_button_names[] =
421 "continue",
422 "options",
423 "save_game",
424 "load_game",
425 "quit",
428 sDarkPanelDesc cSimMenu::gDesc =
430 "sim",
431 cSimMenu::kNumRects,
432 cSimMenu::kNumRects,
433 cSimMenu::kNumRects,
434 sim_button_names,
438 static cSimMenu* gpSimMenu = NULL;
440 void SwitchToDPCSimMenuMode(BOOL push)
442 if (gpSimMenu)
444 cAutoIPtr<IPanelMode> panel = gpSimMenu->GetPanelMode();
445 panel->Switch((push) ? kLoopModePush : kLoopModeSwitch);
450 const sLoopInstantiator* DescribeDPCSimMenuMode(void)
452 if (gpSimMenu)
454 cAutoIPtr<IPanelMode> panel = gpSimMenu->GetPanelMode();
455 return panel->Instantiator();
457 return NULL;
461 //------------------------------------------------------------
462 // NewGame MENU
465 #define MIN_DIFF 1
466 extern int g_diff;
467 #define DIFF2BUTT(x) (((x) < MIN_DIFF) ? MIN_DIFF - 1 : (x) - 1)
468 #define BUTT2DIFF(x) ((x) + 1)
470 class cDPCNewGame: public cDarkPanel
472 static sDarkPanelDesc gDesc;
474 public:
475 cDPCNewGame()
476 : cDarkPanel(&gDesc)
478 memset(&mDiffButtons,0,sizeof(mDiffButtons));
481 enum eRects
483 kStart,
484 kOptions,
485 kCancel,
486 kNumButts,
488 kDifficulty = kNumButts,
489 kDiff0,
490 kDiff1,
491 kDiff2,
492 kDiff3,
494 kNumRects,
496 kNumDiffs = kNumRects - kDiff0,
500 protected:
501 guiStyle mDiffStyle;
502 LGadButtonList mDiffButtons;
503 DrawElement mDiffElems[kNumDiffs];
504 cStr mDiffStrs[kNumDiffs];
506 static bool DiffCB (ushort action, int button, void *data, LGadBox *)
508 g_diff = BUTT2DIFF(button);
509 return FALSE;
512 void InitUI()
514 cDarkPanel::InitUI();
516 // default to current style colors
517 AssertMsg(GetCurrentStyle(),"No current style for diff defaults");
518 memset(&mDiffStyle,0,sizeof(mDiffStyle));
519 memcpy(mDiffStyle.colors,GetCurrentStyle()->colors,sizeof(mDiffStyle.colors));
520 uiGameLoadStyle("diff_",&mDiffStyle,mResPath);
522 // set up drawlelems for diff
523 for (int i = 0; i < kNumDiffs; i++)
525 DrawElement& elem = mDiffElems[i];
526 memset(&elem,0,sizeof(elem));
528 char buf[16];
529 sprintf(buf,"diff_%d",i);
530 mDiffStrs[i] = FetchUIString(panel_name,buf,mResPath);
531 elem.draw_type = DRAWTYPE_TEXT;
532 elem.draw_data = (void*)(const char*)mDiffStrs[i];
533 elem.draw_flags = INTERNAL(DRAWFLAG_INT_TRANSP);
536 LGadButtonListDesc desc =
538 kNumDiffs,
539 &mRects[(int)kDiff0],
540 mDiffElems,
541 DiffCB,
543 BUTTONLIST_RADIO_FLAG,
546 LGadCreateButtonListDesc(&mDiffButtons,LGadCurrentRoot(),&desc);
548 //set the current difficulty setting
549 if (g_diff < MIN_DIFF) g_diff = MIN_DIFF;
550 LGadRadioButtonSelect (&mDiffButtons, DIFF2BUTT(g_diff));
551 int flags = LGadBoxFlags(&mDiffButtons);
552 LGadBoxSetFlags(&mDiffButtons, flags | BOXFLAG_CLEAR);
553 LGadBoxSetStyle(&mDiffButtons,&mDiffStyle);
556 void TermUI()
558 g_diff = BUTT2DIFF(LGadRadioButtonSelection(&mDiffButtons));
559 LGadDestroyButtonList(&mDiffButtons);
560 memset(&mDiffElems,0,sizeof(mDiffElems));
561 for (int i = 0; i < kNumDiffs; i++)
562 mDiffStrs[i] = "";
564 uiGameUnloadStyle(&mDiffStyle);
565 cDarkPanel::TermUI();
568 void RedrawDisplay()
571 // Draw the difficulty string. This is a lot of code to draw a lousy string.
573 cStr str = FetchUIString(panel_name,"difficulty",mResPath); // copy the string
574 char* s = (char*)(const char*)str; // get a mutable pointer
576 Rect& r = mRects[(int)kDifficulty];
578 GUIcompose c;
579 GUIsetup(&c,&r,GUIcomposeFlags(ComposeFlagClear|ComposeFlagRead),GUI_CANV_ANY);
581 guiStyleSetupFont(&mDiffStyle,StyleFontTitle);
582 gr_set_fcolor(guiStyleGetColor(&mDiffStyle,StyleColorText));
584 gr_font_string_wrap(gr_get_font(),s,RectWidth(&r));
586 short w,h;
587 gr_string_size(s,&w,&h);
589 gr_string(s,(RectWidth(&r) - w)/2,(RectHeight(&r) - h)/2);
590 // gr_string(s,gr_char_width('X'),(RectHeight(&r) - h)/2);
592 guiStyleCleanupFont(&mDiffStyle,StyleFontTitle) ;
594 GUIdone(&c);
597 // Make sure the buttonlist gets drawn
599 region_expose(LGadBoxRegion(&mDiffButtons),LGadBoxRect(&mDiffButtons));
603 // Actually do the work of starting a game
605 void StartGame()
608 // Push the init game mode, and the initial cutscene
609 // mode to the mode stack. That way the cutscene happens first.
610 SwitchToDPCInitGame(FALSE);
611 MoviePanel("cs1.avi");
615 BOOL mGo;
617 void OnButtonList(ushort action, int button)
619 if (!(action & BUTTONGADG_LCLICK))
620 return ;
622 //SchemaPlay((Label *)"menubutt",NULL);
624 switch (button)
626 case kStart:
628 mGo = TRUE;
630 break;
632 case kOptions:
633 SwitchToDPCOptionsMode(TRUE);
634 break;
636 case kCancel:
638 cAutoIPtr<IPanelMode> mode = GetPanelMode();
639 mode->Exit();
641 break;
647 void OnLoopMsg(eLoopMessage msg, tLoopMessageData data)
649 switch(msg)
651 case kMsgEnterMode:
652 mGo = FALSE;
653 break;
654 case kMsgNormalFrame:
655 if (mGo) StartGame();
656 break;
659 cDarkPanel::OnLoopMsg(msg,data);
666 // NewGame Menu descriptor
669 static const char* newgame_button_names[] =
671 "start",
672 "options",
673 "cancel"
676 sDarkPanelDesc cDPCNewGame::gDesc =
678 "newgame",
679 cDPCNewGame::kNumButts,
680 cDPCNewGame::kNumRects,
681 cDPCNewGame::kNumButts,
682 newgame_button_names,
683 NULL,
685 kMetaSndPanelMain,
689 static cDPCNewGame* gpNewGame = NULL;
691 void SwitchToDPCNewGameMode(BOOL push)
693 if (gpNewGame)
695 cAutoIPtr<IPanelMode> panel = gpNewGame->GetPanelMode();
696 panel->Switch((push) ? kLoopModePush : kLoopModeSwitch);
701 const sLoopInstantiator* DescribeDPCNewGameMode(void)
703 if (gpNewGame)
705 cAutoIPtr<IPanelMode> panel = gpNewGame->GetPanelMode();
706 return panel->Instantiator();
708 return NULL;
711 //------------------------------------------------------------------
712 // INIT/TERM
716 void init_commands();
719 void DPCMenusInit()
721 if (config_is_defined("netplay_ui"))
722 gpMainMenu = new cDPCNetMainMenu;
723 else
724 gpMainMenu = new cMainMenu;
725 gpSimMenu = new cSimMenu;
726 gpNewGame = new cDPCNewGame;
728 init_commands();
730 // default difficulty
731 g_diff = MIN_DIFF + 1;
733 // What the hell. Initialize the loading screens too
734 DPCLoadingInit();
735 DPCMultiplayUIInit();
738 void DPCMenusTerm()
740 delete gpMainMenu;
741 delete gpSimMenu;
742 delete gpNewGame;
744 DPCLoadingTerm();
745 DPCMultiplayUITerm();
749 //----------------------------------------
750 // COMMANDS
753 static void do_mainmenu()
755 SwitchToDPCMainMenuMode(TRUE);
758 static void do_simmenu()
760 // don't do anything if the trigger is pulled
761 AutoAppIPtr(PlayerGun);
762 ObjID gun = pPlayerGun->Get();
763 if ((gun != OBJ_NULL) && pPlayerGun->IsTriggerPulled())
764 return;
766 // throw any objects on the cursor into the world
767 if (drag_obj != OBJ_NULL)
769 ThrowObj(drag_obj,PlayerObject());
770 ClearCursor();
772 SwitchToDPCSimMenuMode(TRUE);
777 static Command commands[] =
779 { "main_menu", FUNC_VOID, do_mainmenu, "Go to main menu.", HK_ALL },
780 { "sim_menu", FUNC_VOID, do_simmenu, "Go to sim menu.", HK_ALL },
785 static void init_commands()
787 COMMANDS(commands,HK_ALL);