convert line ends
[canaan.git] / prj / cam / src / dark / drksavui.cpp
bloba7ac3c3aed7ff50bd633fe873c992e977b0dfd16
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/dark/drksavui.cpp,v 1.23 2000/02/26 16:49:55 toml Exp $
8 #include <appagg.h>
9 #include <drksavui.h>
10 #include <gadtext.h>
11 #include <drkpanl.h>
12 #include <drkmislp.h>
13 #include <drksave.h>
14 #include <drkuires.h>
15 #include <uigame.h>
16 #include <tagfile.h>
17 #include <gcompose.h>
18 #include <scrnman.h>
19 #include <direct.h>
20 #include <simtime.h>
21 #include <gen_bind.h>
22 #include <keydefs.h>
23 #include <metasnd.h>
24 #include <diskfree.h>
25 #include <drkdebrf.h>
26 #include <mprintf.h>
28 #include <panltool.h>
29 #include <command.h>
30 #include <uianim.h>
31 #include <filepanl.h>
33 #include <btffact.h>
35 #include <dbmem.h>
37 //============================================================
38 // Base file panel, derived from cFilePanel
41 class cDarkFilePanel: public cFilePanel
43 public:
44 cDarkFilePanel(const sDarkPanelDesc* desc)
45 : cFilePanel(desc)
49 virtual const char* SlotFileName(int which);
50 virtual void ComputeSlot(int which);
51 virtual void TotalFailure();
56 //----------------------------------------
59 const char* cDarkFilePanel::SlotFileName(int which)
61 if (which == kQuickSlot)
62 return SAVE_PATH"\\"QUICK_SAVE;
63 static char buf[64];
64 sprintf(buf,"%s\\game%04d.sav",SAVE_PATH,which);
65 return buf;
68 //----------------------------------------
70 void cDarkFilePanel::ComputeSlot(int which)
72 sSlot& slot = mpSlots[which];
73 if (!(slot.flags & kNoCompute))
75 slot.flags = 0;
76 ITagFile* file = TagFileOpen(SlotFileName(which),kTagOpenRead);
77 BOOL read = FALSE;
78 if (file)
79 read = DarkLoadGameDescription(file,slot.buf,sizeof(slot.buf));
80 if (!read)
82 strncpy(slot.buf,FetchUIString(panel_name,"unused",mResPath),sizeof(slot.buf));
83 slot.flags |= kUnused;
85 SafeRelease(file);
87 LGadUpdateTextBox(&slot.box);
91 void cDarkFilePanel::TotalFailure()
93 MissionLoopReset(kMissLoopMainMenu);
94 UnwindToMissionLoop();
98 //============================================================
99 // Load File Panel
102 class cLoadPanel: public cDarkFilePanel
105 public:
106 cLoadPanel() : cDarkFilePanel(&gDesc) {};
108 protected:
109 static sDarkPanelDesc gDesc;
111 void InitUI()
113 cDarkFilePanel::InitUI();
114 MessageNamed("initial");
117 void DoFileOp(int which);
118 void OnSelect(int which);
121 //----------------------------------------
123 void cLoadPanel::DoFileOp(int which)
125 if (mpSlots[which].flags & kUnused)
126 return;
127 MessageNamed("loading");
129 const char* fname = SlotFileName(which);
131 HRESULT result = DarkQuickLoadGameFile(fname);
132 if (FAILED(result))
134 MessageNamed("failed");
135 if (result == kQuickLoadFailed)
137 mTotalFailure = TRUE;
138 EnableFileOp(FALSE);
145 //----------------------------------------
147 void cLoadPanel::OnSelect(int which)
149 sSlot& slot = mpSlots[which];
150 LGadTextBoxClrFlag(&slot.box,TEXTBOX_EDIT_EDITABLE);
151 LGadUnfocusTextBox(&slot.box);
152 if (slot.flags & kUnused)
153 EnableFileOp(FALSE);
157 //----------------------------------------
159 static const char* load_strings[] =
161 "load",
162 "done",
165 sDarkPanelDesc cLoadPanel::gDesc =
167 "gamelod",
168 cLoadPanel::kNumButts,
169 cLoadPanel::kNumRects,
170 cLoadPanel::kNumButts,
171 load_strings,
172 NULL,
174 kMetaSndPanelSaveLoad,
177 //----------------------------------------
179 static cLoadPanel* gpLoadPanel = NULL;
181 void SwitchToLoadGameMode(BOOL push)
183 if (!gpLoadPanel)
184 gpLoadPanel = new cLoadPanel;
185 if (gpLoadPanel)
187 cAutoIPtr<IPanelMode> mode = gpLoadPanel->GetPanelMode();
188 mode->Switch(push ? kLoopModePush : kLoopModeSwitch);
193 //============================================================
194 // Save File Panel
197 class cSavePanel: public cDarkFilePanel
200 public:
201 cSavePanel() : cDarkFilePanel(&gDesc) {};
203 protected:
204 static sDarkPanelDesc gDesc;
206 void InitUI()
208 cDarkFilePanel::InitUI();
209 MessageNamed("initial");
212 void DoFileOp(int which);
213 void OnSelect(int which);
214 void OnDeselect(int which);
218 //----------------------------------------
220 #define MIN_SAVE_FREE_STORAGE (5 << 20)
222 void cSavePanel::DoFileOp(int which)
224 int space;
225 const char* fname = SlotFileName(which);
227 // ok, this isn't really right, because if we're
228 // overwriting an existing save, we don't need free
229 // space, or not as much, right? really, maybe
230 // we shouldn't do this, we should just let the
231 // save detect that it failed
232 space = compute_free_diskspace(NULL);
233 if (space >= 0 && space < MIN_SAVE_FREE_STORAGE) {
234 MessageNamed("no_disk_space");
235 return;
238 mkdir(SAVE_PATH);
240 ITagFile* file = TagFileOpen(fname,kTagOpenWrite);
241 HRESULT retval = E_FAIL;
242 if (file)
244 MessageNamed("saving");
245 retval = DarkSaveGame(mpSlots[which].buf,file);
246 SafeRelease(file);
249 MessageNamed(SUCCEEDED(retval)? "success" : "failure" );
251 if (SUCCEEDED(retval))
252 mpPanelMode->Exit();
255 //----------------------------------------
257 void cSavePanel::OnDeselect(int which)
259 sSlot& slot = mpSlots[which];
260 LGadTextBoxClrFlag(&slot.box,TEXTBOX_EDIT_EDITABLE);
261 LGadUnfocusTextBox(&slot.box);
262 slot.flags &= ~kNoCompute;
265 //------------------------------------------------------------
267 void cSavePanel::OnSelect(int which)
269 sSlot& slot = mpSlots[which];
271 // slot zero is the quick save, don't edit it
272 if (which == kQuickSlot)
273 strncpy(slot.buf,FetchUIString(panel_name,"quick_save"),sizeof(slot.buf));
274 else
276 LGadTextBoxSetFlag(&slot.box,TEXTBOX_EDIT_EDITABLE|TEXTBOX_EDIT_BRANDNEW);
277 LGadFocusTextBox(&slot.box);
279 // Fill slot with a default title
280 // Start with the mission name
281 int miss = GetNextMission();
282 char buf[64];
284 sprintf(buf,"short_%d",miss);
285 cStr title = FetchUIString("titles",buf,"strings");
287 #define CONDITIONAL_FILL
288 #ifdef CONDITIONAL_FILL
289 #ifdef MAHKS_WAY
290 BOOL fill = slot.flags & kUnused;
291 // if the slot is used, only fill if it matches the title
292 if (!fill)
293 fill = strncmp(title,slot.buf,strlen(title)) == 0;
294 #else
295 BOOL fill = slot.flags & kUnused;
296 if (!fill)
297 { // if end of string in our time format, go ahead and do the fill
298 char *p=slot.buf;
299 char *colon1, *colon2;
300 colon2=strrchr(p,':');
301 if (colon2)
303 *colon2='\0';
304 colon1=strrchr(p,':');
305 *colon2=':';
306 if (colon1&&colon2)
308 char *eos=p+strlen(p);
309 if ((colon2==eos-3)&&(colon1==eos-6))
310 fill=TRUE;
314 #endif
315 #else
316 BOOL fill = TRUE;
317 #endif // CONDITIONAL FILL
319 if (fill)
321 strncpy(slot.buf,title,sizeof(slot.buf));
323 // Add in sim time
324 int time = GetSimTime()/SIM_TIME_SECOND;
325 // I wonder if the compiler will optimize this math?
326 sprintf(buf," %d:%02d:%02d",time/(60*60),(time/60)%60,time%60);
328 int len = strlen(slot.buf);
329 strncpy(slot.buf + len,buf,sizeof(slot.buf)-len);
333 slot.flags |= kNoCompute;
335 LGadUpdateTextBox(&slot.box);
340 //----------------------------------------
342 static const char* save_strings[] =
344 "save",
345 "done",
348 sDarkPanelDesc cSavePanel::gDesc =
350 "gamesav",
351 cSavePanel::kNumButts,
352 cSavePanel::kNumRects,
353 cSavePanel::kNumButts,
354 save_strings,
355 NULL,
357 kMetaSndPanelSaveLoad,
360 //----------------------------------------
362 static cSavePanel* gpSavePanel = NULL;
364 void SwitchToSaveGameMode(BOOL push)
366 if (!gpSavePanel)
367 gpSavePanel = new cSavePanel;
369 if (gpSavePanel)
371 cAutoIPtr<IPanelMode> mode = gpSavePanel->GetPanelMode();
372 mode->Switch(push ? kLoopModePush : kLoopModeSwitch);
381 //============================================================
382 // Load Bind File Panel
385 class cLoadBndPanel: public cDarkFilePanel
388 public:
389 cLoadBndPanel() : cDarkFilePanel(&gDesc) {};
391 protected:
392 static sDarkPanelDesc gDesc;
394 void InitUI()
396 cDarkFilePanel::InitUI();
397 MessageNamed("initial");
400 const char* SlotFileName(int which);
401 void ComputeSlot(int which);
402 void DoFileOp(int which);
403 void OnSelect(int which);
406 //----------------------------------------
408 const char* cLoadBndPanel::SlotFileName(int which)
410 static char buf[64];
411 sprintf(buf,"%s\\cfg%04d.bnd",SAVE_PATH,which);
412 return buf;
415 //----------------------------------------
417 void cLoadBndPanel::ComputeSlot(int which)
419 sSlot& slot = mpSlots[which];
420 if (!(slot.flags & kNoCompute))
422 slot.flags = 0;
423 static char str[128], *p_str;
424 FILE *fp = fopen (SlotFileName (which), "rb");
425 if (fp) {
426 fgets (str, 127, fp);
427 fclose (fp);
428 for (p_str = str; ((*p_str == ';' || *p_str == ' ') && *p_str != '\n'); p_str++);
429 strncpy (slot.buf, p_str, sizeof (slot.buf));
432 else {
433 strncpy(slot.buf,FetchUIString(panel_name,"unused",mResPath),sizeof(slot.buf));
434 slot.flags |= kUnused;
437 LGadUpdateTextBox(&slot.box);
441 //----------------------------------------
443 void cLoadBndPanel::DoFileOp(int which)
445 if (mpSlots[which].flags & kUnused)
446 return;
447 const char* fname = SlotFileName(which);
449 MessageNamed("loading");
451 g_pInputBinder->LoadBndFile ((char *)fname, HK_GAME_MODE, NULL);
452 mpPanelMode->Exit();
455 //----------------------------------------
457 void cLoadBndPanel::OnSelect(int which)
459 sSlot& slot = mpSlots[which];
460 LGadTextBoxClrFlag(&slot.box,TEXTBOX_EDIT_EDITABLE);
461 LGadUnfocusTextBox(&slot.box);
462 if (slot.flags & kUnused)
463 EnableFileOp(FALSE);
467 //----------------------------------------
469 static const char* loadbnd_strings[] =
471 "load",
472 "done",
475 sDarkPanelDesc cLoadBndPanel::gDesc =
477 "bndload",
478 cLoadBndPanel::kNumButts,
479 cLoadBndPanel::kNumRects,
480 cLoadBndPanel::kNumButts,
481 loadbnd_strings,
484 //----------------------------------------
486 static cLoadBndPanel* gpLoadBndPanel = NULL;
488 void SwitchToLoadBndMode(BOOL push)
490 if (!gpLoadBndPanel)
491 gpLoadBndPanel = new cLoadBndPanel;
492 if (gpLoadBndPanel)
494 cAutoIPtr<IPanelMode> mode = gpLoadBndPanel->GetPanelMode();
495 mode->Switch(push ? kLoopModePush : kLoopModeSwitch);
500 //============================================================
501 // Save Bind File Panel
504 class cSaveBndPanel: public cDarkFilePanel
507 public:
508 cSaveBndPanel() : cDarkFilePanel(&gDesc) {};
510 protected:
511 static sDarkPanelDesc gDesc;
513 void InitUI()
515 cDarkFilePanel::InitUI();
516 MessageNamed("initial");
519 const char* cSaveBndPanel::SlotFileName(int which);
520 void cSaveBndPanel::ComputeSlot(int which);
521 void DoFileOp(int which);
522 void BndAppendControls (char *fname);
523 void OnSelect(int which);
524 void OnDeselect(int which);
528 //----------------------------------------
530 const char* cSaveBndPanel::SlotFileName(int which)
532 static char buf[64];
533 sprintf(buf,"%s\\cfg%04d.bnd",SAVE_PATH,which);
534 return buf;
537 //----------------------------------------
539 void cSaveBndPanel::ComputeSlot(int which)
541 sSlot& slot = mpSlots[which];
542 if (!(slot.flags & kNoCompute))
544 slot.flags = 0;
545 static char str[128], *p_str;
546 FILE *fp = fopen (SlotFileName (which), "rb");
547 if (fp) {
548 fgets (str, 127, fp);
549 fclose (fp);
550 for (p_str = str; ((*p_str == ';' || *p_str == ' ') && *p_str != '\n'); p_str++);
551 strncpy (slot.buf, p_str, sizeof (slot.buf));
554 else {
555 strncpy(slot.buf,FetchUIString(panel_name,"unused",mResPath),sizeof(slot.buf));
556 slot.flags |= kUnused;
559 LGadUpdateTextBox(&slot.box);
563 //----------------------------------------
565 void cSaveBndPanel::DoFileOp(int which)
567 const char* fname = SlotFileName(which);
569 mkdir(SAVE_PATH);
570 MessageNamed("saving");
572 //get header
573 char header[128];
574 strcpy (header, "; ");
575 strcat (header, mpSlots[which].buf);
578 //change to game context
579 ulong old_context;
580 g_pInputBinder->GetContext (&old_context);
581 g_pInputBinder->SetContext (HK_GAME_MODE,TRUE);
582 g_pInputBinder->SaveBndFile ((char *)fname, header);
583 //plop in input variable control settings
584 BndAppendControls ((char *)fname);
585 g_pInputBinder->SetContext (old_context,TRUE);
587 MessageNamed("success");
590 //----------------------------------------
592 void cSaveBndPanel::BndAppendControls (char *fname)
594 FILE *fp = fopen (fname, "ab");
596 if (fp)
598 fprintf (fp, "\n");
600 char *controls[] = { "bow_zoom", "joystick_enable", "mouse_invert", "lookspring",
601 "freelook", "mouse_sensitivity", "joy_rotate", "joystick_sensitivity",
602 "joystick_deadzone", "rudder_sensitivity", "rudder_deadzone",
603 "auto_equip", "auto_search", "goal_notify", "climb_touch", "\0"};
605 char str[32];
606 char **p_control = controls;
608 while (**p_control) {
609 sprintf (str, "echo $%s", *p_control);
610 fprintf (fp, "%s %s\n", *p_control, g_pInputBinder->ProcessCmd (str));
611 p_control++;
614 fclose (fp);
619 //----------------------------------------
621 void cSaveBndPanel::OnDeselect(int which)
623 sSlot& slot = mpSlots[which];
624 LGadTextBoxClrFlag(&slot.box,TEXTBOX_EDIT_EDITABLE);
625 LGadUnfocusTextBox(&slot.box);
626 slot.flags &= ~kNoCompute;
629 //------------------------------------------------------------
631 void cSaveBndPanel::OnSelect(int which)
633 sSlot& slot = mpSlots[which];
635 LGadTextBoxSetFlag(&slot.box,TEXTBOX_EDIT_EDITABLE|TEXTBOX_EDIT_BRANDNEW);
636 LGadFocusTextBox(&slot.box);
638 // Fill slot with stuff
639 strncpy(slot.buf,FetchUIString(panel_name,"my_binds",mResPath),sizeof(slot.buf));
641 slot.flags |= kNoCompute;
642 LGadUpdateTextBox(&slot.box);
647 //----------------------------------------
649 static const char* savebnd_strings[] =
651 "save",
652 "done",
655 sDarkPanelDesc cSaveBndPanel::gDesc =
657 "bndsave",
658 cSaveBndPanel::kNumButts,
659 cSaveBndPanel::kNumRects,
660 cSaveBndPanel::kNumButts,
661 savebnd_strings,
664 //----------------------------------------
666 static cSaveBndPanel* gpSaveBndPanel = NULL;
668 void SwitchToSaveBndMode(BOOL push)
670 if (!gpSaveBndPanel)
671 gpSaveBndPanel = new cSaveBndPanel;
673 if (gpSaveBndPanel)
675 cAutoIPtr<IPanelMode> mode = gpSaveBndPanel->GetPanelMode();
676 mode->Switch(push ? kLoopModePush : kLoopModeSwitch);
684 //------------------------------------------------------------
685 // Init/Term
688 void init_commands();
690 void DarkSaveInitUI()
692 init_commands();
695 void DarkSaveTermUI()
697 delete gpLoadPanel;
698 delete gpSavePanel;
699 delete gpLoadBndPanel;
700 delete gpSaveBndPanel;
704 //------------------------------------------------------------
705 // Commands
708 static void do_load()
710 SwitchToLoadGameMode(TRUE);
713 static void do_save()
715 SwitchToSaveGameMode(TRUE);
719 static Command commands[] =
721 { "load_game", FUNC_VOID, do_load, "Go to the game load UI", HK_ALL },
722 { "save_game", FUNC_VOID, do_save, "Go to the game save UI", HK_ALL },
727 static void init_commands()
729 COMMANDS(commands,HK_ALL);