2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
58 #define kVolumeSliderNotches 25
59 #define kOneOverVolumeSliderNotches ((1.0)/(float)kVolumeSliderNotches)
61 static void TouchGamma (float gamma
)
68 //is the difficulty setting greyed out or not?
69 static BOOL g_diff_active
= TRUE
;
76 inline int DIFF2BUTT(int x
)
79 if (x
< kDPCFirstDiff
)
87 #define BUTT2DIFF(x) ((x) + 1)
90 EXTERN BOOL g_zbuffer_toggle
;
91 extern int sfx_use_channels
;
96 #define MAX_NUM_BINDABLE 64
97 #define QUICKCONFIG_BINDNUM 15 /*number of quick configurable commands*/
98 #define NUM_BIND_SLOTS 13
99 //max cmds we will display per a given cmd
100 #define MAX_BINDS_PER_CMD 3
104 #define SLIDER_BMPRES 0
105 #define BINDUP_BMPRES 1
106 #define BINDDN_BMPRES 2
109 #define FILL_SUBPANEL 666
111 #define LRMOD(x) (!strcmp (x, "lalt") || !strcmp (x, "ralt") || \
112 !strcmp (x, "lctrl") || !strcmp (x, "rctrl") || \
113 !strcmp (x, "lshift") || !strcmp (x, "rshift"))
117 #define MIN_RES_X 640
118 #define MIN_RES_Y 480
119 #define MAX_RES_Y 768
121 //all 8-bit for software
122 static short soft_modes
[] = {
131 //#define CanChangeEAX() (SFX_Is_EAX_Available())
132 #define CanChangeEAX() (SFX_Is_EAX_Available() && (SFX_GetSoundDevice () == SFXDEVICE_A3D))
136 AutoAppIPtr(SimManager
);
137 return (pSimManager
->LastMsg() & (kSimInit
| kSimResume
)) != 0;
140 #define CanChangeSoundDeviceNow() (!InSim())
143 BOOL
CanChangeDifficultyNow()
145 AutoAppIPtr(NetManager
);
146 return !pNetManager
->IsNetworkGame();
150 static const DrawElement def_draw_elem
=
152 0, 0, 0, // type, data, data2
153 0, 0, // fcolor bcolor
154 INTERNAL(DRAWFLAG_INT_TRANSP
), // flags
157 static void InitDrawElem(DrawElement
* elem
)
159 *elem
= def_draw_elem
;
163 //------------------------------------------------------------
167 typedef class cDPCOptions cOptions
;
169 static cOptions
*gpOptions
= NULL
;
172 class cDPCOptions
: public cDarkPanel
174 static sDarkPanelDesc gDesc
;
177 cOptions() : cDarkPanel(&gDesc
)
179 memset(&mTabButtons
,0,sizeof(mTabButtons
));
180 memset(mSubPanelButtons
,0,sizeof(mSubPanelButtons
));
181 memset(&mListButtons
,0,sizeof(mListButtons
));
182 memset(&mBindButtons
,0,sizeof(mBindButtons
));
183 memset(&mBindScrollers
,0,sizeof(mBindScrollers
));
184 memset(mSliders
,0,sizeof(mSliders
));
188 void SetInitialSub ()
190 mCurSub
= kSubControls
;
193 //Will stuff retrieve_num many controls bound to cmd into the dest
194 //string array, and will return how many actually got stuff
195 int GetCmdBinds (const char *cmd
, cStr
*dest
, int retrieve_num
, cStr
* raw_dest
= NULL
)
197 char control_buf
[64];
198 char controls
[4][32];
199 long num_controls
, i
, cur_control
;
201 g_pInputBinder
->GetControlFromCmdStart ((char *)cmd
, control_buf
);
204 for (cur_control
= 0; *control_buf
!= '\0' && cur_control
< retrieve_num
;) {
205 g_pInputBinder
->DecomposeControl (control_buf
, controls
, &num_controls
);
206 //we don't want to throw in the l/r mods
207 for (i
= 0; i
< num_controls
&& !LRMOD (controls
[i
]); i
++);
209 //no l/r's, this control is cool. fetch names
210 if (i
== num_controls
)
212 cStr
& cur_dest
= dest
[cur_control
];
214 cStr temp_raw
; // We might not have a raw_dest
215 cStr
& cur_raw
= (raw_dest
) ? raw_dest
[cur_control
] : temp_raw
;
219 for (i
= 0; i
< num_controls
; i
++)
227 cStr str
= FetchUIString ("controls", controls
[i
], mResPath
);
229 //does this key have a translated string?
230 cur_dest
+= (*str
) ? str
: controls
[i
];
231 cur_raw
+= controls
[i
];
237 g_pInputBinder
->GetControlFromCmdNext (control_buf
);
247 kSubFillRect
= kNumButts
,
263 kCustomize
= kFirstControlButt
,
270 kMouseSensSliderRect
= kFirstControlRect
,
273 kNumControlButts
= kFirstControlRect
- kFirstControlButt
,
274 kNumControlRects
= kLimControlRect
- kFirstControlButt
,
277 kFirstBasicVideoButt
= kLimControlRect
,
278 kScreenRes
= kFirstBasicVideoButt
,
281 kFirstBasicVideoRect
,
282 kGammaSliderRect
= kFirstBasicVideoRect
,
285 kNumBasicVideoButts
= kFirstBasicVideoRect
- kFirstBasicVideoButt
,
286 kNumBasicVideoRects
= kLimBasicVideoRect
- kFirstBasicVideoRect
,
288 kFirstAdvancedVideoButt
= kLimBasicVideoRect
,
289 kHardwareDriverOld
= kFirstAdvancedVideoButt
,
292 kLimAdvancedVideoRect
,
293 kNumAdvancedVideoRects
= kLimAdvancedVideoRect
- kFirstAdvancedVideoButt
,
295 //audio buttons/rects
296 kFirstAudioButt
= kLimAdvancedVideoRect
,
297 kSpeakerTest
= kFirstAudioButt
,
304 kVolumeSliderRect
= kFirstAudioRect
,
312 kNumAudioButts
= kFirstAudioRect
- kFirstAudioButt
,
313 kNumAudioRects
= kLimAudioRect
- kFirstAudioButt
,
315 //game buttons (Note irregularity)
316 kFirstGameRect
= kLimAudioRect
,
317 kDiffTextRect
= kFirstGameRect
,
319 kDiff0
= kFirstGameButt
,
324 kNumGameButts
= kLimGameRect
- kFirstGameButt
,
325 kNumGameRects
= kLimGameRect
- kFirstGameRect
,
328 kFirstBindButt
= kLimGameRect
,
329 kBindLoad
= kFirstBindButt
,
335 kBindButt0
,//0 to NUM_BIND_SLOTS - 1
337 kBindScrollUp
= kBindButt0
+ NUM_BIND_SLOTS
,
340 kNumBindButts
= kBindButt0
- kFirstBindButt
,
341 kNumBindRects
= kLimBindRects
- kFirstBindButt
,
343 kFirstListButt
= kLimBindRects
,
344 kListBack
= kFirstListButt
,
345 kList0
,//13 of these, just add what is needed.
346 kNumListButts
= kList0
- kFirstListButt
,
347 kNumListRects
= NUM_LIST
+ kNumListButts
,
350 kNumSubPanelRects
= kNumControlRects
+ kNumBasicVideoRects
+ kNumAdvancedVideoRects
351 + kNumAudioRects
+ kNumGameRects
+ kNumBindRects
+ kNumListRects
,
359 kMouseSensSlider
= kNumVolumeSliders
,
383 kMiscStrForwardBackward
,
389 static int gFirstSubRect
[];
396 cStr mMiscStrs
[kNumMiscStrs
];
398 IRes
*mButtBmpRes
[3][4];//4 button draw states
399 DrawElement mButtDrawElem
[3];
402 LGadButtonList mTabButtons
;
403 LGadButtonListDesc mTabDesc
;
404 cRectArray mTabRects
;
405 DrawElement mTabElems
[kNumTabs
];
406 cStr mTabStrs
[kNumTabs
];
410 LGadButtonList mSubPanelButtons
[kNumSubs
];
411 LGadButtonListDesc mSubPanelDesc
[kNumSubs
];
412 cRectArray mSubPanelRects
;
413 DrawElement mSubPanelElems
[kNumSubPanelRects
];
414 cStr mSubPanelStrs
[kNumSubPanelRects
];
421 LGadButtonList mListButtons
;
422 LGadButtonListDesc mListButtonDesc
;
423 DrawElement mListButtonElems
[NUM_LIST
];
424 cStr mListButtonStrs
[NUM_LIST
];
431 //binding-related data
436 LGadButtonList mBindButtons
;
437 LGadButtonListDesc mBindButtonDesc
;
438 DrawElement mBindButtonElems
[NUM_BIND_SLOTS
];
439 cStr mBindButtonStrs
[MAX_NUM_BINDABLE
];
440 cStr mBindCmd
[MAX_NUM_BINDABLE
];
441 bool mBindButtsFilled
[MAX_NUM_BINDABLE
];
443 LGadButtonList mBindScrollers
;
444 LGadButtonListDesc mBindScrollerDesc
;
450 LGadSlider mSliders
[kNumSubPanelSlides
];
451 bool mSlidersOn
[kNumSubPanelSlides
];
452 DrawElement mSliderBaseBmp
;
458 int m_volume
[kNumVolumeSliders
];
462 typedef bool (*ButtListCB
)(ushort
, int, void *, LGadBox
*);
465 //////////////////////////////////////////////////////
467 void SetBoxData(LGadBox
* box
)
469 LGadBoxSetUserData (box
, this);
471 int flags
= LGadBoxFlags(box
);
472 LGadBoxSetFlags(box
, flags
| BOXFLAG_CLEAR
);
475 typedef int (*vol_get_func
)(void);
477 uint
MillibelToSlider(int vol
)
479 uint retval
= (uint
) ( VolMillibelToLinear((float)vol
) * kVolumeSliderNotches
);
480 if (retval
>= kVolumeSliderNotches
)
481 retval
= kVolumeSliderNotches
- 1;
486 // get slider volume, in slider notches
487 uint
GetVolume(uint which
)
489 static vol_get_func funcs
[] =
496 if (which
== k3dVolumeSlider
)
498 uint vol3d
= MillibelToSlider(SFX_Get3dVolume());
499 uint vol2d
= MillibelToSlider(SFX_Get2dVolume());
502 vol2d
= kVolumeSliderNotches
- vol2d
;
503 return (kVolumeSliderNotches
+ vol2d
)/2;
509 int vol
= funcs
[which
]();
510 return MillibelToSlider(vol
);
514 typedef void (*vol_set_func
)(int);
516 // set volume, in slider notches
517 void SetVolume(int which
, int vol
)
519 static vol_set_func funcs
[] =
526 vol_set_func func
= funcs
[which
];
527 // the 3d volume slider is really a "mix" between 2d and 3d
528 if (which
== k3dVolumeSlider
)
530 int half
= (kVolumeSliderNotches
+ 1)/2;
534 func
= SFX_Set3dVolume
;
540 func
= SFX_Set2dVolume
;
541 vol
= (kVolumeSliderNotches
- vol
)*2;
545 Assert_(which
< kNumVolumeSliders
);
547 float fvol
= VolLinearToMillibel((float)vol
* kOneOverVolumeSliderNotches
);
553 static int gVolSliderRects
[];
558 cDarkPanel::InitUI();
560 //load in the tab and subpanel rectangles
561 AppendRects ("optiontr", mTabRects
);//tabs
562 AppendRects ("optioncr", mSubPanelRects
);//controls
563 AppendRects ("optnbvr", mSubPanelRects
);//basic video
564 AppendRects ("optnavr", mSubPanelRects
);//advanced video
565 AppendRects ("optionar", mSubPanelRects
);//audio
566 AppendRects ("optiongr", mSubPanelRects
);//game
567 AppendRects ("optionbr", mSubPanelRects
);//bindings
568 AppendRects ("optionlr", mSubPanelRects
);//list
570 //load miscellaneous strings
572 for (long i
= 0; i
< kNumMiscStrs
; i
++) {
573 sprintf (buf
, "misc_%d", i
);
574 mMiscStrs
[i
] = FetchUIString (panel_name
, buf
, mResPath
);
577 //create our "tabs" at the top of the menu for the different major categories
578 InitButtonList (&mTabDesc
, &mTabRects
[0], mTabElems
, OnTabButton
, mTabStrs
, "tab_", kNumTabs
, BUTTONLIST_RADIO_FLAG
);
579 LGadCreateButtonListDesc (&mTabButtons
, LGadCurrentRoot(), &mTabDesc
);
580 SetBoxData(VB(&mTabButtons
));
582 int sub_tabs
[] = {0, 1, 1, 2, 3, 0, 1};
583 LGadRadioButtonSelect (&mTabButtons
, sub_tabs
[mCurSub
]);
585 // default to current style colors
586 AssertMsg (GetCurrentStyle (), "No current style for diff defaults");
587 memset (&mTextStyle
, 0, sizeof (guiStyle
));
588 memcpy (mTextStyle
.colors
, GetCurrentStyle ()->colors
, sizeof(mTextStyle
.colors
));
589 uiGameLoadStyle ("opttext_", &mTextStyle
, mResPath
);
591 // style for greyed area
592 AssertMsg (GetCurrentStyle (), "No current style for diff defaults");
593 memcpy (&mGreyStyle
, GetCurrentStyle (), sizeof(guiStyle
));
594 uiGameLoadStyle ("grey_", &mGreyStyle
, mResPath
);
596 //get our slider button bitmap
597 AutoAppIPtr (ResMan
);
598 for (i
= 0; i
< 4; i
++) {
599 mButtBmpRes
[SLIDER_BMPRES
][i
] = pResMan
->Bind ("slidbutt", RESTYPE_IMAGE
, NULL
, mResPath
);
600 if (!mButtBmpRes
[SLIDER_BMPRES
][i
])
601 AssertMsg (0, "Error loading button bitmap");
603 InitDrawElem(&mButtDrawElem
[SLIDER_BMPRES
]);
604 mButtDrawElem
[SLIDER_BMPRES
].draw_data
= (void *)mButtBmpRes
[SLIDER_BMPRES
];
605 mButtDrawElem
[SLIDER_BMPRES
].draw_type
= DRAWTYPE_RESOFFSET
;
607 InitDrawElem(&mSliderBaseBmp
);
608 mSliderBaseBmp
.draw_type
= DRAWTYPE_RES
;
609 mSliderBaseBmp
.draw_data
= (void *)pResMan
->Bind ("slidbase", RESTYPE_IMAGE
, NULL
, mResPath
);
611 for (i
= 0; i
< kNumSubPanelSlides
; i
++)
612 mSlidersOn
[i
] = FALSE
;
614 //set sliders initial vals
615 m_sens
= int((atof (g_pInputBinder
->ProcessCmd ("echo $mouse_sensitivity")) - 0.5) * 2.0);
617 for (int v
= 0; v
< kNumVolumeSliders
; v
++)
618 m_volume
[v
] = GetVolume(v
);
619 m_gamma
= 20-(20.0 / (MAX_GAMMA
- MIN_GAMMA
)) * (g_gamma
- MIN_GAMMA
);
622 if (config_is_defined("d3d_driver_index"))
623 config_get_int("d3d_driver_index", &m3dDriver
);
625 //initialize our subpanels
628 InitControlOptions ();
635 //our handler for handling keyboard arrows and enter in the binding menu
637 uiGetCurrentSlab (&slab
);
639 uiInstallRegionHandler (slab
->creg
, UI_EVENT_KBD_COOKED
, StaticBindKeyHandler
, NULL
, &m_cookie
);
642 //////////////////////////////////////////////////////
646 LGadDestroyButtonList(&mTabButtons
);
648 memset(&mTabElems
,0,sizeof(mTabElems
));
649 for (int i
= 0, j
; i
< kNumTabs
; i
++)
653 uiGameUnloadStyle (&mBindStyle
);
654 uiGameUnloadStyle (&mTextStyle
);
656 for (i
= 0; i
< 3; i
++)
657 for (j
= 0; j
< 4; j
++)
658 mButtBmpRes
[i
][j
]->Release ();
660 ((IRes
*)(mSliderBaseBmp
.draw_data
))->Release ();
662 //save the current bindings upon exit of the options menu
663 //change to game context
665 g_pInputBinder
->GetContext (&old_context
);
666 g_pInputBinder
->SetContext (HK_GAME_MODE
,FALSE
);
667 cStr header
= FetchUIString (panel_name
, "bnd_header", mResPath
);
668 g_pInputBinder
->SaveBndFile ("user.bnd", (char *)(const char *)header
);
669 //plop in input variable control settings
670 BndAppendControls ();
672 g_pInputBinder
->SetContext (HK_GAME2_MODE
,FALSE
);
673 g_pInputBinder
->SaveBndFile ("user2.bnd", (char *)(const char *)header
);
674 g_pInputBinder
->SetContext (old_context
,FALSE
);
676 //remove the binding keyboard handler
678 uiGetCurrentSlab (&slab
);
679 uiRemoveRegionHandler (LGadBoxRegion (slab
->creg
), m_cookie
);
681 cDarkPanel::TermUI();
685 //////////////////////////////////////////////////////
689 LGadDestroyButtonList (&mSubPanelButtons
[mCurSub
]);
691 if (mCurSub
== kSubBind
) {
692 LGadDestroyButtonList (&mBindButtons
);
693 LGadDestroyButtonList (&mBindScrollers
);
696 memset (mSubPanelElems
, 0, kNumSubPanelRects
* sizeof(DrawElement
));
697 for (int i
= 0; i
< kNumSubPanelRects
; i
++)
698 mSubPanelStrs
[i
] = "";
700 //if there are any sliders, kill them
701 DestroyAllSliders ();
703 mTabRects
.SetSize (0);
704 mSubPanelRects
.SetSize (0);
707 //////////////////////////////////////////////////////
711 if (mCurSub
== kSubBind
) {
712 LGadDestroyButtonList (&mBindButtons
);
713 LGadDestroyButtonList (&mBindScrollers
);
716 else if (mCurSub
== kSubList
) {
717 if (mListSub
== kSubBasicVideo
) {
721 LGadDestroyButtonList (&mListButtons
);
725 //////////////////////////////////////////////////////
727 void OnLoopMsg (eLoopMessage msg
, tLoopMessageData msg_data
)
729 if (SFX_GetSoundDevice () == SFXDEVICE_A3D
) {
730 mxs_vector origin
= {0.0, 0.0, 0.0};
731 SFX_Frame (&origin
, (mxs_angvec
*)&origin
);
734 SFX_Frame (NULL
, NULL
);
737 SwapSubPanel (mSwap
);
748 for (int i
= 0; i
< kNumVolumeSliders
; i
++)
749 SetVolume(i
,m_volume
[i
]);
756 sprintf (buf
, "mouse_sensitivity %8.8f", ((double)m_sens
/ 2.0) + 0.5);//slide goes from 0.5 (slow) to 10.5 (fast)
757 g_pInputBinder
->ProcessCmd (buf
);
765 static int prev_gamma
;
766 if (prev_gamma
!= m_gamma
) {
767 TouchGamma ((((MAX_GAMMA
- MIN_GAMMA
) / 20.0) * (float)(20-m_gamma
)) + MIN_GAMMA
);
768 prev_gamma
= m_gamma
;
776 //////////////////////////////////////////////////////
778 void InitControlOptions ()
780 InitButtonList(&mSubPanelDesc
[kSubControls
], &mSubPanelRects
[(int)kCustomize
], &mSubPanelElems
[(int)kCustomize
], OnSubPanelButton
,
781 &mSubPanelStrs
[(int)kCustomize
], "control_", kNumControlButts
, 0);
783 //set starting button strings
785 // watch me factor code like the dickens.
786 static const char* cmds
[] =
790 "echo $mouse_invert",
795 for (int i
= kLookspring
; i
< kFirstControlRect
; i
++)
797 int idx
= i
- kFirstControlButt
;
799 char *str
= g_pInputBinder
->ProcessCmd((char*)cmds
[idx
]); // command value
800 cStr
& substr
= mSubPanelStrs
[i
]; // button string
801 DrawElement
& elem
= mSubPanelElems
[i
]; // button elem
803 sprintf(res_str
,"control_%d",i
);
805 BOOL state
= atof(str
) != 0.0;
806 const char* state_str
;
808 if (i
== kJoyRotate
) // exception
810 if (g_joystickActive
)
811 state_str
= mMiscStrs
[(state
) ? kMiscStrLeftRight
: kMiscStrForwardBackward
];
819 state_str
= mMiscStrs
[(state
) ? kMiscStrOn
: kMiscStrOff
];
821 SetUIString(substr
,elem
,res_str
,(char*)state_str
);
827 //////////////////////////////////////////////////////
829 void BndAppendControls ()
831 FILE *fp
= fopen ("user.bnd", "at");
836 char *controls
[] = {"lookspring", "mouse_invert", "freelook", "mouse_sensitivity", "\0"};
838 char **p_control
= controls
;
840 while (**p_control
) {
841 sprintf (str
, "echo $%s", *p_control
);
842 fprintf (fp
, "%s %s\r\n", *p_control
, g_pInputBinder
->ProcessCmd (str
));
850 //////////////////////////////////////////////////////
852 void InitVideoOptions ()
854 InitButtonList (&mSubPanelDesc
[kSubBasicVideo
], &mSubPanelRects
[(int)kFirstBasicVideoButt
], &mSubPanelElems
[(int)kFirstBasicVideoButt
],
855 OnSubPanelButton
, &mSubPanelStrs
[(int)kFirstBasicVideoButt
], "videob_", kNumBasicVideoButts
, 0);
857 int first
= kFirstAdvancedVideoButt
;
858 InitButtonList (&mSubPanelDesc
[kSubAdvancedVideo
], &mSubPanelRects
[first
], &mSubPanelElems
[first
],
859 OnSubPanelButton
, &mSubPanelStrs
[(int)first
], "videoa_", kNumAdvancedVideoRects
, 0);
864 //let's get some info about the video card
865 mNumVidDevices
= lgd3d_enumerate_devices ();
867 sScrnMode mode
= *GetGameScreenMode();
869 if (mNumVidDevices
> 0 && (mode
.flags
& kScrnMode3dDriver
)) {
870 g_zbuffer_toggle
= TRUE
;
871 mode
.flags
|= kScrnMode3dDriver
;
872 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
873 (char *)(const char *)mMiscStrs
[(g_zbuffer_toggle
&& (mode
.flags
& kScrnMode3dDriver
) != 0) ? kMiscStrOn
: kMiscStrOff
]);
877 g_zbuffer_toggle
= FALSE
;
878 mode
.flags
&= ~kScrnMode3dDriver
;
879 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
880 (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
883 SetGameScreenMode (&mode
);
887 //////////////////////////////////////////////////////
889 void InitAudioOptions ()
891 InitButtonList (&mSubPanelDesc
[kSubAudio
], &mSubPanelRects
[(int)kSpeakerTest
], &mSubPanelElems
[(int)kSpeakerTest
], OnSubPanelButton
,
892 &mSubPanelStrs
[(int)kSpeakerTest
], "audio_", kNumAudioButts
, 0);
894 SetUIString (mSubPanelStrs
[(int)kStereoToggle
], mSubPanelElems
[(int)kStereoToggle
], "audio_1",
895 (char *)(const char *)mMiscStrs
[(SFX_StereoReversed ()) ? kMiscStrOn
: kMiscStrOff
]);
897 SetUIString (mSubPanelStrs
[(int)kA3DToggle
], mSubPanelElems
[(int)kA3DToggle
], "audio_2",
898 (char *)(const char *)mMiscStrs
[(SFX_GetSoundDevice () == SFXDEVICE_A3D
) ? kMiscStrOn
: kMiscStrOff
]);
901 sprintf (buf
, "%d", sfx_use_channels
);
902 mSubPanelStrs
[(int)kAudioChannels
] += buf
;
903 SetUIString (mSubPanelStrs
[(int)kAudioChannels
], mSubPanelElems
[(int)kAudioChannels
], "audio_3", buf
);
905 BOOL isEAXOn
= SFX_Is_EAX_Enabled();
906 SetUIString (mSubPanelStrs
[(int)kAudioEAXToggle
], mSubPanelElems
[(int)kAudioEAXToggle
], "audio_4",
907 (char *)(const char *)mMiscStrs
[isEAXOn
? kMiscStrOn
: kMiscStrOff
]);
910 //////////////////////////////////////////////////////
912 void InitGameOptions ()
914 int first
= kFirstGameButt
;
915 InitButtonList (&mSubPanelDesc
[kSubGame
], &mSubPanelRects
[first
], &mSubPanelElems
[first
], OnSubPanelButton
,
916 &mSubPanelStrs
[first
], "game_", kNumGameButts
, BUTTONLIST_RADIO_FLAG
);
919 //////////////////////////////////////////////////////
921 void InitBindOptions ()
923 InitButtonList (&mSubPanelDesc
[kSubBind
], &mSubPanelRects
[(int)kBindLoad
], &mSubPanelElems
[(int)kBindLoad
], OnSubPanelButton
,
924 &mSubPanelStrs
[(int)kBindLoad
], "bind_", kNumBindButts
, 0);
926 //set up description for binding buttons. joy.
927 //rearrange a few rects
929 cRectArray tmp_rects
;
930 tmp_rects
.SetSize (NUM_BIND_SLOTS
);
931 for (long i
= 0; i
< (NUM_BIND_SLOTS
- 2); i
++)
932 tmp_rects
[i
] = mSubPanelRects
[(int)kBindButt0
+ 2 + i
];
933 tmp_rects
[NUM_BIND_SLOTS
- 2] = mSubPanelRects
[(int)kBindScrollUp
];
934 tmp_rects
[NUM_BIND_SLOTS
- 1] = mSubPanelRects
[(int)kBindButt0
+ 1];
935 for (i
= 0; i
< NUM_BIND_SLOTS
; i
++)
937 mSubPanelRects
[(int)kBindButt0
+ 1 + i
] = tmp_rects
[i
];
938 InitDrawElem(&mBindButtonElems
[i
]);
939 mBindButtonElems
[i
].draw_type
= DRAWTYPE_TEXT
;
941 //description of binding radio buttons
943 LGadButtonListDesc tmp_desc
= {NUM_BIND_SLOTS
, (Rect
*)&mSubPanelRects
[(int)kBindButt0
],
944 mBindButtonElems
, OnBindButton
, 0, BUTTONLIST_RADIO_FLAG
};
945 memcpy (&mBindButtonDesc
, &tmp_desc
, sizeof (LGadButtonListDesc
));
948 // default to current style colors
949 AssertMsg (GetCurrentStyle (), "No current style for diff defaults");
950 memset (&mBindStyle
, 0, sizeof (mBindStyle
));
951 memcpy (mBindStyle
.colors
, GetCurrentStyle()->colors
, sizeof (mBindStyle
.colors
));
952 uiGameLoadStyle("bind_", &mBindStyle
, mResPath
);
959 sprintf (buf
, "bindcmd_%d", mNumBindable
);
960 bind_cmd
= FetchUIString ("bindcmds", buf
, mResPath
);
962 if (bind_cmd
== "" || mNumBindable
>= MAX_NUM_BINDABLE
)
965 mBindCmd
[mNumBindable
] = bind_cmd
;
966 mBindButtsFilled
[mNumBindable
] = FALSE
;
973 //load bitmaps for up/down scroll arrows
974 LoadButtBmp (mButtBmpRes
[BINDUP_BMPRES
], &mButtDrawElem
[BINDUP_BMPRES
], "bup_");
975 LoadButtBmp (mButtBmpRes
[BINDDN_BMPRES
], &mButtDrawElem
[BINDDN_BMPRES
], "bdn_");
977 //description of binding scroll buttons
979 LGadButtonListDesc tmp_desc
= {2, (Rect
*)&mSubPanelRects
[(int)kBindScrollUp
],
980 &mButtDrawElem
[BINDUP_BMPRES
], OnScrollButton
, 0, 0};
981 memcpy (&mBindScrollerDesc
, &tmp_desc
, sizeof (LGadButtonListDesc
));
986 //////////////////////////////////////////////////////
988 void InitListOptions ()
990 //description of back button
992 LGadButtonListDesc tmp_desc
= {kNumListButts
, (Rect
*)&mSubPanelRects
[(int)kListBack
],
993 &mSubPanelElems
[(int)kListBack
], OnSubPanelButton
, 0, 0};
994 mSubPanelDesc
[kSubList
] = tmp_desc
;
997 mSubPanelStrs
[(int)kListBack
] = FetchUIString (panel_name
, "bind_1", mResPath
);
999 DrawElement
& backelem
= mSubPanelElems
[(int)kListBack
];
1000 InitDrawElem(&backelem
);
1001 backelem
.draw_data
= (void *)(const char *)mSubPanelStrs
[(int)kListBack
];
1002 backelem
.draw_type
= DRAWTYPE_TEXT
;
1004 //description of list buttons
1006 LGadButtonListDesc tmp_desc
= {NUM_LIST
, (Rect
*)&mSubPanelRects
[(int)kList0
],
1007 mListButtonElems
, OnListButton
, 0, BUTTONLIST_RADIO_FLAG
};
1008 mListButtonDesc
= tmp_desc
;
1016 //////////////////////////////////////////////////////
1018 void FillBindStr (long bind_num
, long butt_num
)
1020 if (bind_num
>= mNumBindable
) {
1021 static char *dummy
= "";
1022 mBindButtonElems
[butt_num
].draw_data
= dummy
;
1026 if (mBindButtsFilled
[bind_num
]) {
1027 mBindButtonElems
[butt_num
].draw_data
= (void*)(const char*)mBindButtonStrs
[bind_num
];
1030 mBindButtsFilled
[bind_num
] = TRUE
;
1033 g_pInputBinder
->GetContext (&old_context
);
1034 if (old_context
!= HK_GAME_MODE
)
1035 g_pInputBinder
->SetContext (HK_GAME_MODE
,FALSE
);
1039 sprintf (buf
, "bindname_%d", bind_num
);
1041 mBindButtonStrs
[bind_num
] = FetchUIString (panel_name
, buf
, mResPath
);
1042 mBindButtonStrs
[bind_num
] += " = ";
1044 cStr controls
[MAX_BINDS_PER_CMD
];
1045 cStr raw_controls
[MAX_BINDS_PER_CMD
];
1046 int num
= GetCmdBinds (mBindCmd
[bind_num
], controls
, MAX_BINDS_PER_CMD
, raw_controls
);
1048 for (long i
= 0; i
< num
; i
++) {
1050 mBindButtonStrs
[bind_num
] += ", ";
1051 mBindButtonStrs
[bind_num
] += controls
[i
];
1054 //there were no controls
1056 mBindButtonStrs
[bind_num
] += mMiscStrs
[kMiscStrEmpty
];
1059 // Copy the controls over to game2
1060 g_pInputBinder
->SetContext(HK_GAME2_MODE
,FALSE
);
1061 for (int i
= 0; i
< num
; i
++)
1063 const char* cmd
= mBindCmd
[bind_num
];
1064 const char* ctrl
= raw_controls
[i
];
1066 // if cmd has a space, we have to quote it, because the binder is stupid
1068 if (strchr(cmd
,' ') != NULL
)
1076 // Check the config to make sure we can bind this stuff in game2
1077 BOOL can_bind
= TRUE
;
1079 sprintf(varbuf
,"%s_bind_game2",ctrl
);
1080 config_get_int(varbuf
,&can_bind
);
1083 g_pInputBinder
->Bind((char*)ctrl
,(char*)cmd
);
1087 if (old_context
!= HK_GAME2_MODE
)
1088 g_pInputBinder
->SetContext (old_context
,FALSE
);
1090 mBindButtonElems
[butt_num
].draw_data
= (void*)(const char*)mBindButtonStrs
[bind_num
];
1093 //////////////////////////////////////////////////////
1095 void FillBindStrs ()
1097 AutoAppIPtr(ResMan
);
1098 IRes
* ctrls
= pResMan
->Bind("controls",RESTYPE_STRING
,NULL
,mResPath
);
1101 IRes
* panel
= pResMan
->Bind(panel_name
,RESTYPE_STRING
,NULL
,mResPath
);
1105 g_pInputBinder
->GetContext (&old_context
);
1106 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
1109 for (long i
= 0, j
= mTopBind
; i
< NUM_BIND_SLOTS
; i
++, j
++) {
1119 //change back to previous mode
1120 g_pInputBinder
->SetContext (old_context
,TRUE
);
1124 //////////////////////////////////////////////////////
1126 static bool StaticBindKeyHandler (uiEvent
*p_event
, Region
*p_reg
, void *state
)
1129 if (gpOptions
->mCurSub
== gpOptions
->kSubBind
&& p_event
->type
== UI_EVENT_KBD_COOKED
)
1130 ret
= gpOptions
->BindKeyHandler ((uiCookedKeyEvent
*)p_event
);
1134 bool BindKeyHandler (uiCookedKeyEvent
*event
)
1136 //only use up actions
1137 if (event
->code
& KB_FLAG_DOWN
)
1142 int cur_selected
= LGadRadioButtonSelection (&mBindButtons
);
1144 switch (event
->code
) {
1147 if (cur_selected
> 0)
1148 LGadRadioButtonSelect (&mBindButtons
, cur_selected
- 1);
1149 else if (mTopBind
> 0) {
1161 if (cur_selected
< (NUM_BIND_SLOTS
- 1))
1162 LGadRadioButtonSelect (&mBindButtons
, cur_selected
+ 1);
1163 else if (mTopBind
< mNumBindable
- NUM_BIND_SLOTS
) {
1174 mTopBind
-= NUM_BIND_SLOTS
;
1177 LGadRadioButtonSelect (&mBindButtons
, 0);
1186 mTopBind
+= NUM_BIND_SLOTS
;
1187 if (mTopBind
>= (mNumBindable
- NUM_BIND_SLOTS
)) {
1188 mTopBind
= mNumBindable
- NUM_BIND_SLOTS
;
1189 LGadRadioButtonSelect (&mBindButtons
, NUM_BIND_SLOTS
- 1);
1199 LGadRadioButtonSelect (&mBindButtons
, 0);
1200 if (mTopBind
!= 0) {
1209 LGadRadioButtonSelect (&mBindButtons
, NUM_BIND_SLOTS
- 1);
1210 if (mTopBind
!= (mNumBindable
- NUM_BIND_SLOTS
)) {
1211 mTopBind
= mNumBindable
- NUM_BIND_SLOTS
;
1218 case KEY_GREY_ENTER
:
1219 OnSubPanelButtonList (BUTTONGADG_LCLICK
, kBind
- kBindLoad
);
1228 FillBlack (FILL_SUBPANEL
);
1236 //////////////////////////////////////////////////////
1241 if (mSelectedRes
== -1)
1244 sScrnMode mode
= *GetGameScreenMode();
1246 char *mode_desc
= (char *)(const char *)mListButtonStrs
[mSelectedRes
];
1247 sscanf (mode_desc
, "%dx%dx%d", &mode
.w
, &mode
.h
, &mode
.bitdepth
);
1249 SetGameScreenMode (&mode
);
1254 // Set the resolution string
1257 int residx
= kScreenRes
;
1258 cStr
& resstr
= mSubPanelStrs
[residx
];
1259 DrawElement
& elem
= mSubPanelElems
[residx
];
1262 const sScrnMode
& mode
= *GetGameScreenMode();
1263 sprintf(buf
,"%dx%dx%d",mode
.w
,mode
.h
,mode
.bitdepth
);
1265 SetUIString(resstr
,elem
,"videob_0",buf
);
1269 //////////////////////////////////////////////////////
1271 void FillVidResStrs ()
1274 const sScrnMode
*mode
= GetGameScreenMode ();
1275 lgd3ds_device_info
*info
;
1277 int idx
= mNumVidDevices
- 1;
1278 if (config_is_defined("d3d_driver_index"))
1279 config_get_int("d3d_driver_index", &idx
);
1280 info
= lgd3d_get_device_info (idx
);
1284 char buf
[32], mode_str
[32];
1286 if (mNumVidDevices
> 0 && (mode
->flags
& kScrnMode3dDriver
)) {
1287 cur_mode
= &info
->supported_modes
[mTopList
];
1291 cur_mode
= &soft_modes
[mTopList
];
1295 //get current mode string so we know what to select
1296 sprintf (mode_str
, "%dx%dx%d", mode
->w
, mode
->h
, mode
->bitdepth
);
1297 //dunny button will be default selection if we dont have a matching res for some reason
1298 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
= NUM_LIST
- 1);
1301 for (long i
= 0, inc
= 0; i
< NUM_LIST
; i
+= inc
) {
1303 if (*cur_mode
!= -1 && i
< NUM_LIST
- 1)
1305 grs_mode_info
& info
= grd_mode_info
[*cur_mode
];
1307 if (info
.bitDepth
== bpp
1308 && info
.w
>= MIN_RES_X
1309 && info
.h
>= MIN_RES_Y
1310 && info
.h
<= MAX_RES_Y
)
1314 sprintf (buf
, "%dx%dx%d", grd_mode_info
[*cur_mode
].w
,
1315 grd_mode_info
[*cur_mode
].h
, grd_mode_info
[*cur_mode
].bitDepth
);
1317 mListButtonStrs
[i
] = buf
;
1319 if (!strcmp (buf
, mode_str
))
1320 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
= i
);
1328 mListButtonStrs
[i
] = "";
1332 DrawElement
& elem
= mListButtonElems
[i
];
1333 InitDrawElem(&elem
);
1334 elem
.draw_data
= (void *)(const char *)mListButtonStrs
[i
];
1335 elem
.draw_type
= DRAWTYPE_TEXT
;
1341 //////////////////////////////////////////////////////
1343 void FillVidDevStrs ()
1345 lgd3ds_device_info
*info
;
1347 for (long i
= 0; i
< NUM_LIST
; i
++) {
1348 if (i
< mNumVidDevices
) {
1349 info
= lgd3d_get_device_info (i
);
1350 mListButtonStrs
[i
] = info
->p_ddraw_desc
;
1353 mListButtonStrs
[i
] = "";
1355 DrawElement
& elem
= mListButtonElems
[i
];
1356 InitDrawElem(&elem
);
1357 elem
.draw_data
= (void *)(const char *)mListButtonStrs
[i
];
1358 elem
.draw_type
= DRAWTYPE_TEXT
;
1361 int idx
= mNumVidDevices
- 1;
1362 if (config_is_defined("d3d_driver_index"))
1363 config_get_int("d3d_driver_index", &idx
);
1364 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
= idx
);
1367 //////////////////////////////////////////////////////
1369 static BOOL
BindFilter (char *control
, char *cmd
, void *data
)
1371 //we'll reserve ESC for breaking from a bind query
1372 if (!strcmp (control
, "esc"))
1375 //don't bind joystick movement
1376 if (!strcmp (control
, "joy_move"))
1379 //scroll lock doesnt have up/down events like a normal key
1380 if (!strcmp (control
, "scroll_lock"))
1383 // don't bind the F keys since the game needs them for psi powers
1385 for (i
=1; i
<= 12; i
++)
1388 sprintf(fkey
,"F%d",i
);
1389 if (!stricmp(control
, fkey
))
1393 // otherwise, it's legal
1397 //////////////////////////////////////////////////////
1399 static void PostBindFunc (BOOL bound
)
1401 for (long i
= 0; i
< gpOptions
->mNumBindable
; i
++)
1402 gpOptions
->mBindButtsFilled
[i
] = FALSE
;
1403 gpOptions
->FillBindStrs ();
1404 gpOptions
->FillBlack (FILL_SUBPANEL
);
1405 gpOptions
->RedrawDisplay ();
1407 g_pInputBinder
->SetContext (gpOptions
->m_old_context
,TRUE
);
1410 //////////////////////////////////////////////////////
1412 static void QuickConfigPostBindFunc (BOOL bound
)
1414 int bind_num
= gpOptions
->mTopBind
+ LGadRadioButtonSelection (&gpOptions
->mBindButtons
) + 1;
1415 if (bind_num
< QUICKCONFIG_BINDNUM
&& bound
) {
1416 if (bind_num
> NUM_BIND_SLOTS
- 1) {
1417 gpOptions
->mTopBind
++;
1419 LGadRadioButtonSelect (&gpOptions
->mBindButtons
, bind_num
- gpOptions
->mTopBind
);
1421 sprintf (buf
, "bindname_%d", bind_num
);
1422 gpOptions
->mBindButtonStrs
[bind_num
] = FetchUIString (gpOptions
->panel_name
, buf
, gpOptions
->mResPath
);
1423 gpOptions
->mBindButtonStrs
[bind_num
] += " = ?";
1425 g_pInputBinder
->TrapBind ((char *)(const char *)gpOptions
->mBindCmd
[bind_num
],
1426 gpOptions
->BindFilter
, gpOptions
->QuickConfigPostBindFunc
, NULL
);
1430 g_pInputBinder
->SetContext (gpOptions
->m_old_context
,TRUE
);
1432 for (long i
= 0; i
< gpOptions
->mNumBindable
; i
++)
1433 gpOptions
->mBindButtsFilled
[i
] = ((i
!= bind_num
|| !bound
) || (bind_num
== QUICKCONFIG_BINDNUM
)) ? FALSE
: TRUE
;
1435 gpOptions
->FillBindStrs ();
1436 gpOptions
->FillBlack (FILL_SUBPANEL
);
1437 gpOptions
->RedrawDisplay ();
1441 //////////////////////////////////////////////////////
1443 void InitButtonList (LGadButtonListDesc
*desc
, Rect
*rect_array
, DrawElement
*draw_elem
,
1444 ButtListCB cb
, cStr
*strs
, const char *prefix
, int num
, int flags
)
1446 // set up drawlelems
1447 for (int i
= 0; i
< num
; i
++) {
1448 DrawElement
*elem
= &draw_elem
[i
];
1452 sprintf(buf
, "%s%d", prefix
, i
);
1453 strs
[i
] = FetchUIString (panel_name
, buf
, mResPath
);
1454 elem
->draw_type
= DRAWTYPE_TEXT
;
1455 elem
->draw_data
= (void*)(const char*)strs
[i
];
1459 LGadButtonListDesc tmp_desc
= {
1468 memcpy (desc
, &tmp_desc
, sizeof (LGadButtonListDesc
));
1472 //////////////////////////////////////////////////////
1474 void DrawButtonList (LGadButtonListDesc
*blist
)
1476 Rect rect
= {{0, 0}, {640, 480}};
1477 uiHideMouse (&rect
);
1479 int num
= blist
->num_buttons
;
1480 for (int i
= 0; i
< num
; i
++) {
1481 ElementDraw (&blist
->button_elems
[i
], dsNORMAL
, blist
->button_rects
[i
].ul
.x
, blist
->button_rects
[i
].ul
.y
,
1482 blist
->button_rects
[i
].lr
.x
- blist
->button_rects
[i
].ul
.x
, blist
->button_rects
[i
].lr
.y
- blist
->button_rects
[i
].ul
.y
);
1485 uiShowMouse (&rect
);
1488 //////////////////////////////////////////////////////
1490 void DrawSlider (int num
, int rect_num
, BOOL draw_slide
= TRUE
)
1492 Rect rect
= {{0, 0}, {640, 480}};
1493 uiHideMouse (&rect
);
1495 Rect
*slide_rect
= (Rect
*)&mSubPanelRects
[rect_num
];
1496 ElementDraw (&mSliderBaseBmp
, dsNORMAL
, slide_rect
->ul
.x
, slide_rect
->ul
.y
,
1497 slide_rect
->lr
.x
- slide_rect
->ul
.x
, slide_rect
->lr
.y
- slide_rect
->ul
.y
);
1499 uiShowMouse (&rect
);
1501 LGadDrawBox ((LGadBox
*)&mSliders
[num
], NULL
);
1504 //////////////////////////////////////////////////////
1506 void LoadButtBmp (IRes
*butt_res
[4], DrawElement
*draw_elem
, char *prefix
)
1508 char *sffx
[] = {"norm", "down", "hlit", "hlit"}, str
[128];
1509 AutoAppIPtr (ResMan
);
1510 for (int i
= 0; i
< 4; i
++) {
1511 butt_res
[i
] = pResMan
->Bind (strcat (strcpy (str
, prefix
), sffx
[i
]), RESTYPE_IMAGE
, NULL
, mResPath
);
1513 AssertMsg (0, "Error loading button bitmap");
1516 InitDrawElem(draw_elem
);
1517 draw_elem
->draw_data
= (void *)butt_res
;
1518 draw_elem
->draw_type
= DRAWTYPE_RESOFFSET
;
1521 //////////////////////////////////////////////////////
1523 void SetUIString (cStr
&str
, DrawElement
&draw_elem
, char *name
, char *suffix
)
1525 str
= FetchUIString (panel_name
, name
, mResPath
);
1528 draw_elem
.draw_data
= (void*)(const char*)str
;
1531 //////////////////////////////////////////////////////
1533 void AppendRects (char *rect_file
, cRectArray
&old_rects
)
1535 long old_sz
, tmp_sz
;
1536 cRectArray tmp_rects
;
1537 FetchUIRects(rect_file
, tmp_rects
, mResPath
);
1538 old_rects
.SetSize ((old_sz
= old_rects
.Size ()) + (tmp_sz
= tmp_rects
.Size ()));
1540 for (long i
= 0, j
= old_sz
; i
< tmp_sz
; i
++, j
++)
1541 old_rects
[j
] = tmp_rects
[i
];
1544 //////////////////////////////////////////////////////
1546 void CreateSlider (int slider_num
, int rect_num
, int *val_ptr
, int num_notches
, int inc
)
1548 LGadSlider
*slider
= &mSliders
[slider_num
];
1549 Rect
*rect
= (Rect
*)&mSubPanelRects
[rect_num
];
1550 memset (slider
, 0, sizeof (LGadSlider
));
1551 slider
->gadg
.draw
= mButtDrawElem
[SLIDER_BMPRES
];
1553 //this is absolutely a hack.
1554 //make the slider's range of motion smaller since the slider's base art
1555 //presents the slide as having a more confined range. 12 pixels will do the trick.
1557 x
= rect
->ul
.x
+ 12;
1558 w
= rect
->lr
.x
- rect
->ul
.x
- 24;
1560 LGadCreateSliderArgs (slider
, LGadCurrentRoot (), x
, rect
->ul
.y
+ ((rect
->lr
.y
- rect
->ul
.y
)>>1), 0, 0, NULL
,
1561 val_ptr
, num_notches
, inc
, w
, LGSLIDER_HORIZONTAL
, 0);
1563 mSlidersOn
[slider_num
] = TRUE
;
1565 LGadDrawBox ((LGadBox
*)slider
, NULL
);
1568 //////////////////////////////////////////////////////
1570 void DestroySlider (int slider_num
)
1572 if (mSlidersOn
[slider_num
]) {
1573 LGadDestroySlider (&mSliders
[slider_num
], FALSE
);
1574 mSlidersOn
[slider_num
] = FALSE
;
1578 //////////////////////////////////////////////////////
1580 void DestroyAllSliders ()
1582 for (int i
= 0; i
< (int)kNumSubPanelSlides
; i
++)
1586 //////////////////////////////////////////////////////
1588 void DrawString (char *strname
, int rect_num
)
1590 cStr str
= FetchUIString (panel_name
, strname
, mResPath
);//copy the string
1591 char *s
= (char*)(const char*)str
;//get a mutable pointer
1593 Rect
&r
= mSubPanelRects
[rect_num
];
1596 InitDrawElem(&draw
);
1597 draw
.draw_type
= DRAWTYPE_TEXT
;
1599 ElementSetStyle(&mTextStyle
);
1600 ElementDraw (&draw
, dsNORMAL
, r
.ul
.x
, r
.ul
.y
, r
.lr
.x
- r
.ul
.x
, r
.lr
.y
- r
.ul
.y
);
1603 //////////////////////////////////////////////////////
1605 void RedrawDisplay ()
1608 region_expose (LGadBoxRegion (&mTabButtons
), LGadBoxRect (&mTabButtons
));
1609 DrawButtonList (&mSubPanelDesc
[mCurSub
]);
1611 //any sub-specific stuff
1614 DrawSlider ((int)kMouseSensSlider
, (int)kMouseSensSliderRect
);
1615 DrawString ("mouse_sens", kMouseSensTextRect
);
1618 case kSubBasicVideo
:
1619 DrawSlider ((int)kGammaSlider
, (int)kGammaSliderRect
);
1620 DrawString ("gamma", kGammaSliderText
);
1625 for (int i
= 0; i
< kNumVolumeSliders
; i
++)
1627 DrawSlider (i
, gVolSliderRects
[i
]);
1629 sprintf(name
,"volume_%d",i
);
1630 DrawString (name
,gVolSliderRects
[i
] + 1); // plus one to get from rect to text rect
1636 region_expose (LGadBoxRegion (&mSubPanelButtons
[kSubGame
]), LGadBoxRect (&mSubPanelButtons
[kSubGame
]));
1637 DrawString ("diff", kDiffTextRect
);
1641 DrawButtonList (&mBindScrollerDesc
);
1642 region_expose (LGadBoxRegion (&mBindButtons
), LGadBoxRect (&mBindButtons
));
1646 region_expose (LGadBoxRegion (&mListButtons
), LGadBoxRect (&mListButtons
));
1647 // DrawButtonList (&mBindScrollerDesc);
1652 //////////////////////////////////////////////////////
1654 void FillBlack (int rect_num
)
1657 if (rect_num
== FILL_SUBPANEL
)
1658 rect
= (Rect
*)&mRects
[(int)kSubFillRect
];
1660 rect
= (Rect
*)&mSubPanelRects
[rect_num
];
1665 //////////////////////////////////////////////////////
1667 void SwapSubPanel (int new_sub
)
1669 if (mCurSub
!= -1) {
1670 LGadDestroyButtonList (&mSubPanelButtons
[mCurSub
]);
1674 if (new_sub
!=kSubAudio
)
1675 metaSndEnterPanel(kMetaSndPanelOptions
);
1677 metaSndExitPanel(TRUE
);
1679 LGadCreateButtonListDesc (&mSubPanelButtons
[new_sub
], LGadCurrentRoot (), &mSubPanelDesc
[new_sub
]);
1680 SetBoxData(VB(&mSubPanelButtons
[new_sub
]));
1686 DrawSlider ((int)kMouseSensSlider
, (int)kMouseSensSliderRect
, FALSE
);
1687 CreateSlider ((int)kMouseSensSlider
, (int)kMouseSensSliderRect
, &m_sens
, 20, 1);
1691 case kSubBasicVideo
:
1693 DrawSlider ((int)kGammaSlider
, (int)kGammaSliderRect
, FALSE
);
1694 CreateSlider ((int)kGammaSlider
, (int)kGammaSliderRect
, &m_gamma
, 20, 1);
1700 for (int i
= 0; i
< kNumVolumeSliders
; i
++)
1702 DrawSlider(i
,gVolSliderRects
[i
],FALSE
);
1703 CreateSlider(i
,gVolSliderRects
[i
],&m_volume
[i
],kVolumeSliderNotches
- 1, 1);
1706 if (! CanChangeSoundDeviceNow ()) {
1707 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioChannels
- kFirstAudioButt
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1708 mSubPanelDesc
[kSubAudio
].button_elems
[kA3DToggle
- kFirstAudioButt
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1711 if (!CanChangeEAX())
1712 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioEAXToggle
- kSpeakerTest
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1718 g_diff_active
= CanChangeDifficultyNow();
1721 AutoAppIPtr(QuestData
);
1722 if (pQuestData
->Exists(DIFF_QVAR
))
1723 g_diff
= pQuestData
->Get(DIFF_QVAR
);
1727 LGadBoxSetStyle (&mSubPanelButtons
[kSubGame
], &mGreyStyle
);
1729 //set the current difficulty setting
1730 LGadRadioButtonSelect (&mSubPanelButtons
[kSubGame
], DIFF2BUTT(g_diff
));
1736 LGadCreateButtonListDesc (&mBindButtons
, LGadCurrentRoot (), &mBindButtonDesc
);
1737 SetBoxData(VB(&mBindButtons
));
1738 LGadRadioButtonSelect (&mBindButtons
,0);
1739 LGadBoxSetStyle (&mBindButtons
, &mBindStyle
);
1741 LGadCreateButtonListDesc (&mBindScrollers
, LGadCurrentRoot (), &mBindScrollerDesc
);
1742 SetBoxData(VB(&mBindScrollers
));
1748 LGadCreateButtonListDesc (&mListButtons
, LGadCurrentRoot (), &mListButtonDesc
);
1749 SetBoxData(VB(&mListButtons
));
1750 LGadBoxSetStyle (&mListButtons
, &mBindStyle
);
1752 // LGadCreateButtonListDesc (&mBindScrollers, LGadCurrentRoot (), &mBindScrollerDesc);
1753 // SetBoxData(VB(&mBindScrollers));
1755 if (mListSub
== kSubAdvancedVideo
)
1757 else if (mListSub
== kSubBasicVideo
)
1764 FillBlack (FILL_SUBPANEL
);
1770 //////////////////////////////////////////////////////
1772 static void PlayRightTest (int, void *)
1775 memset (&parm
, 0, sizeof (sfx_parm
));
1776 parm
.pan
= SFX_StereoReversed() ? -10000 : 10000;
1777 cStr snd_name
= FetchUIString (gpOptions
->panel_name
, "rightsound", gpOptions
->mResPath
);
1779 if (SFX_GetSoundDevice () == SFXDEVICE_A3D
) {
1780 //@TODO: make the a3d speaker test sound crisper, clearer, more refreshed
1781 mxs_vector pos
= {0.0, SFX_StereoReversed() ? 10.0 : -10.0, 0.0};
1782 SFX_Play_Vec (SFX_3D
, &parm
, (char *)(const char *)snd_name
, &pos
);
1785 SFX_Play_Raw (SFX_STATIC
, &parm
, (char *)(const char *)snd_name
);
1788 //////////////////////////////////////////////////////
1790 static bool OnTabButton (ushort action
, int button
, void *data
, LGadBox
*)
1792 cOptions
*panel
= (cOptions
*)data
;
1794 panel
->OnTabButtonList (action
, button
);
1798 //////////////////////////////////////////////////////
1800 void OnTabButtonList (ushort action
, int button
)
1802 if (!(action
& BUTTONGADG_LCLICK
))
1810 if (mCurSub
!= kSubControls
) {
1811 mSwap
= kSubControls
;
1812 DestroyAllSliders ();
1820 if (mCurSub
!= kSubBasicVideo
&& mCurSub
!= kSubAdvancedVideo
) {
1821 DestroyAllSliders ();
1822 mSwap
= kSubBasicVideo
;
1830 if (mCurSub
!= kSubAudio
) {
1831 DestroyAllSliders ();
1840 if (mCurSub
!= kSubGame
) {
1841 DestroyAllSliders ();
1850 //////////////////////////////////////////////////////
1852 static bool OnSubPanelButton (ushort action
, int button
, void *data
, LGadBox
*)
1854 cOptions
*panel
= (cOptions
*)data
;
1856 panel
->OnSubPanelButtonList (action
, button
);
1860 //////////////////////////////////////////////////////
1862 void OnSubPanelButtonList (ushort action
, int button
)
1864 if (!(action
& BUTTONGADG_LCLICK
))
1867 int idx
= button
+ gFirstSubRect
[mCurSub
];
1875 mListSub
= kSubBasicVideo
;
1881 #ifdef ADVANDED_VID_PANEL
1882 case kAdvancedVidOptions
:
1883 DestroyAllSliders ();
1884 mSwap
= kSubAdvancedVideo
;
1888 case kHardwareDriver
:
1890 mListSub
= kSubAdvancedVideo
;
1894 case kZBufferToggle
:
1896 const sScrnMode
*old_mode
= GetGameScreenMode ();
1897 if (mNumVidDevices
> 0 && old_mode
->flags
& kScrnMode3dDriver
) {
1898 if (!g_zbuffer_toggle
) {
1899 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
1900 (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
1901 g_zbuffer_toggle
= TRUE
;
1904 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
1905 (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
1906 g_zbuffer_toggle
= FALSE
;
1908 FillBlack ((int)kZBufferToggle
);
1914 case kBasicVidOptions
:
1915 DestroyAllSliders ();
1916 mSwap
= kSubBasicVideo
;
1923 memset (&parm
, 0, sizeof (sfx_parm
));
1924 parm
.pan
= SFX_StereoReversed() ? 10000 : -10000;
1925 parm
.end_callback
= PlayRightTest
;
1926 cStr snd_name
= FetchUIString (panel_name
, "leftsound", mResPath
);
1928 if (SFX_GetSoundDevice () == SFXDEVICE_A3D
) {
1929 mxs_vector pos
= {0.0, SFX_StereoReversed() ? -10.0 : 10.0, 0.0};
1930 //@TODO: make the a3d speaker test sound crisper, clearer, more refreshed
1931 SFX_Play_Vec (SFX_3D
, &parm
, (char *)(const char *)snd_name
, &pos
);
1934 SFX_Play_Raw (SFX_STATIC
, &parm
, (char *)(const char *)snd_name
);
1939 SFX_SetReverseStereo (!SFX_StereoReversed ());
1940 SetUIString (mSubPanelStrs
[(int)kStereoToggle
], mSubPanelElems
[(int)kStereoToggle
], "audio_1",
1941 (char *)(const char *)mMiscStrs
[(SFX_StereoReversed ()) ? kMiscStrOn
: kMiscStrOff
]);
1942 FillBlack (kStereoToggle
);
1947 if (CanChangeSoundDeviceNow()) {
1948 if (SFX_GetSoundDevice () != SFXDEVICE_A3D
)
1950 // Try to use 3D sound hardware
1951 if (! SFX_SetSoundDevice (SFXDEVICE_A3D
, TRUE
))
1953 // If no 3D sound hardware, turn back on software.
1954 SFX_SetSoundDevice (SFXDEVICE_Software
, TRUE
);
1958 SFX_SetSoundDevice (SFXDEVICE_Software
, TRUE
);
1960 SetUIString (mSubPanelStrs
[(int)kA3DToggle
], mSubPanelElems
[(int)kA3DToggle
], "audio_2",
1961 (char *)(const char *)mMiscStrs
[(SFX_GetSoundDevice () == SFXDEVICE_A3D
) ? kMiscStrOn
: kMiscStrOff
]);
1962 FillBlack (kA3DToggle
);
1963 // RedrawDisplay ();
1965 // EAX settings may have changed.
1966 BOOL newEAXState
= SFX_Is_EAX_Enabled();
1967 SetUIString (mSubPanelStrs
[(int)kAudioEAXToggle
], mSubPanelElems
[(int)kAudioEAXToggle
], "audio_4",
1968 (char *)(const char *)mMiscStrs
[newEAXState
? kMiscStrOn
: kMiscStrOff
]);
1970 // Set EAX button color as appropriate.
1971 if ( CanChangeEAX() )
1972 // Hack: This takes the "green" color from the "speaker test" button..... there must be a better way...
1973 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioEAXToggle
- kSpeakerTest
].fcolor
= mSubPanelDesc
[kSubAudio
].button_elems
[0].fcolor
;
1975 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioEAXToggle
- kSpeakerTest
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1976 FillBlack (kAudioEAXToggle
);
1982 case kAudioChannels
:
1983 if (CanChangeSoundDeviceNow())
1985 // List of valid selections
1986 static int selections
[] = { 4, 8, 12, 16, 0 };
1987 int chan
= sfx_use_channels
;
1988 for (int* sel
= selections
; *sel
!= 0 && *sel
<= chan
; sel
++)
1991 chan
= selections
[0];
1996 sfx_use_channels
= chan
;
1997 config_set_int("sfx_channels", chan
);
2001 sprintf (buf
, "%d", chan
);
2002 mSubPanelStrs
[(int)kAudioChannels
] += buf
;
2003 SetUIString (mSubPanelStrs
[(int)kAudioChannels
], mSubPanelElems
[(int)kAudioChannels
], "audio_3", buf
);
2007 case kAudioEAXToggle
:
2010 // Toggle EAX state.
2011 BOOL newEAXState
= !SFX_Is_EAX_Enabled();
2017 // Double-check to make sure state actually toggled.
2018 newEAXState
= SFX_Is_EAX_Enabled();
2019 config_set_int ("sfx_eax", (int) newEAXState
);
2020 SetUIString (mSubPanelStrs
[(int)kAudioEAXToggle
], mSubPanelElems
[(int)kAudioEAXToggle
], "audio_4",
2021 (char *)(const char *)mMiscStrs
[newEAXState
? kMiscStrOn
: kMiscStrOff
]);
2026 DestroyAllSliders ();
2031 // I may weep openly
2039 // Set the difficulty
2040 g_diff
= BUTT2DIFF(button
);
2043 AutoAppIPtr(QuestData
);
2044 if (pQuestData
->Exists(DIFF_QVAR
))
2045 pQuestData
->Set(DIFF_QVAR
,g_diff
);
2048 //not active, don't let them change buttons
2050 LGadRadioButtonSelect (&mSubPanelButtons
[kSubGame
], DIFF2BUTT(g_diff
));
2056 SwitchToDPCLoadBndMode (TRUE
);
2061 SwitchToDPCSaveBndMode (TRUE
);
2065 DestroyAllSliders ();
2066 mSwap
= kSubControls
;
2070 case kQuickConfigure
:
2071 LGadRadioButtonSelect (&mBindButtons
, mTopBind
= 0);
2072 mBindButtonStrs
[0] = FetchUIString (panel_name
, "bindname_0", mResPath
);
2073 mBindButtonStrs
[0] += " = ?";
2075 //change to game context
2076 g_pInputBinder
->GetContext (&m_old_context
);
2077 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
2078 g_pInputBinder
->TrapBind ((char *)(const char *)mBindCmd
[0], BindFilter
, QuickConfigPostBindFunc
, NULL
);
2081 FillBlack (FILL_SUBPANEL
);
2088 int bind_num
= mTopBind
+ LGadRadioButtonSelection (&mBindButtons
);
2090 sprintf (buf
, "bindname_%d", bind_num
);
2091 mBindButtonStrs
[bind_num
] = FetchUIString (panel_name
, buf
, mResPath
);
2092 mBindButtonStrs
[bind_num
] += " = ?";
2094 //change to game context
2095 g_pInputBinder
->GetContext (&m_old_context
);
2096 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
2097 g_pInputBinder
->TrapBind ((char *)(const char *)mBindCmd
[bind_num
], BindFilter
, PostBindFunc
, NULL
);
2100 FillBlack (FILL_SUBPANEL
);
2108 //change to game context
2109 g_pInputBinder
->GetContext (&m_old_context
);
2110 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
2112 char str
[128], control_buf
[64];
2113 int bind_num
= mTopBind
+ LGadRadioButtonSelection (&mBindButtons
);
2115 g_pInputBinder
->GetControlFromCmdStart ((char *)(const char *)mBindCmd
[bind_num
], control_buf
);
2116 while (*control_buf
!= '\0') {
2117 strcpy (str
, "unbind ");
2118 strcat (str
, control_buf
);
2119 g_pInputBinder
->ProcessCmd (str
);
2120 g_pInputBinder
->GetControlFromCmdStart ((char *)(const char *)mBindCmd
[bind_num
], control_buf
);
2123 g_pInputBinder
->SetContext (m_old_context
,TRUE
);
2125 for (int i
= 0; i
< mNumBindable
; i
++)
2126 mBindButtsFilled
[i
] = FALSE
;
2128 FillBlack (FILL_SUBPANEL
);
2135 char *inverted
= g_pInputBinder
->ProcessCmd ("echo $lookspring"), buf
[16];
2136 sprintf (buf
, "control_%d", button
);
2137 if (atof (inverted
) == 0.0) {
2138 g_pInputBinder
->ProcessCmd ("lookspring 1");
2139 SetUIString (mSubPanelStrs
[(int)kLookspring
], mSubPanelElems
[(int)kLookspring
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
2141 //when lookspring is turned on, turn off freelook if it is on
2142 if (atof (g_pInputBinder
->ProcessCmd ("echo $freelook")) != 0.0)
2143 OnSubPanelButtonList (action
, kFreelook
- kCustomize
);
2146 g_pInputBinder
->ProcessCmd ("lookspring 0");
2147 SetUIString (mSubPanelStrs
[(int)kLookspring
], mSubPanelElems
[(int)kLookspring
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
2149 FillBlack ((int)kLookspring
);
2156 if (g_joystickActive
)
2158 char *rotate
= g_pInputBinder
->ProcessCmd ("echo $joy_rotate"), buf
[16];
2159 sprintf (buf
, "control_%d", button
);
2160 if (atof (rotate
) == 0.0) {
2161 g_pInputBinder
->ProcessCmd ("joy_rotate 1");
2162 SetUIString (mSubPanelStrs
[(int)kJoyRotate
], mSubPanelElems
[(int)kJoyRotate
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrLeftRight
]);
2165 g_pInputBinder
->ProcessCmd ("joy_rotate 0");
2166 SetUIString (mSubPanelStrs
[(int)kJoyRotate
], mSubPanelElems
[(int)kJoyRotate
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrForwardBackward
]);
2168 FillBlack ((int)kJoyRotate
);
2176 char *inverted
= g_pInputBinder
->ProcessCmd ("echo $mouse_invert"), buf
[16];
2177 sprintf (buf
, "control_%d", button
);
2178 if (atof (inverted
) == 0.0) {
2179 g_pInputBinder
->ProcessCmd ("mouse_invert 1");
2180 SetUIString (mSubPanelStrs
[(int)kMouseInvert
], mSubPanelElems
[(int)kMouseInvert
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
2183 g_pInputBinder
->ProcessCmd ("mouse_invert 0");
2184 SetUIString (mSubPanelStrs
[(int)kMouseInvert
], mSubPanelElems
[(int)kMouseInvert
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
2186 FillBlack ((int)kMouseInvert
);
2194 char *inverted
= g_pInputBinder
->ProcessCmd ("echo $freelook"), buf
[16];
2195 sprintf (buf
, "control_%d", button
);
2196 if (atof (inverted
) == 0.0) {
2197 g_pInputBinder
->ProcessCmd ("freelook 1");
2198 SetUIString (mSubPanelStrs
[(int)kFreelook
], mSubPanelElems
[(int)kFreelook
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
2200 //when freelook is turned on, turn off lookspring if it is on
2201 if (atof (g_pInputBinder
->ProcessCmd ("echo $lookspring")) != 0.0)
2202 OnSubPanelButtonList (action
, kLookspring
- kCustomize
);
2205 g_pInputBinder
->ProcessCmd ("freelook 0");
2206 SetUIString (mSubPanelStrs
[(int)kFreelook
], mSubPanelElems
[(int)kFreelook
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
2208 FillBlack ((int)kFreelook
);
2216 DestroyAllSliders ();
2218 if (mListSub
== kSubAdvancedVideo
) {
2219 config_set_int ("d3d_driver_index", m3dDriver
= LGadRadioButtonSelection (&mListButtons
));
2220 // Go back to basic video instead of advanced
2221 mSwap
= kSubBasicVideo
;
2225 else if (mListSub
== kSubBasicVideo
) {
2233 //////////////////////////////////////////////////////
2235 static bool OnScrollButton (ushort action
, int button
, void *data
, LGadBox
*)
2237 cOptions
*panel
= (cOptions
*)data
;
2239 panel
->OnScrollList (action
, button
);
2243 //////////////////////////////////////////////////////
2245 void OnScrollList (ushort action
, int button
)
2247 if (!(action
& BUTTONGADG_LCLICK
))
2266 //scrolling through resolutions
2283 if (mTopBind
<= mNumBindable
- NUM_BIND_SLOTS
) {
2287 if (mTopBind
== mNumBindable
- (NUM_BIND_SLOTS
- 1) && LGadRadioButtonSelection (&mBindButtons
) == (NUM_BIND_SLOTS
- 1))
2288 LGadRadioButtonSelect (&mBindButtons
, 8);
2296 if (mNumListTotal
>= NUM_LIST
- 1) {
2309 FillBlack (FILL_SUBPANEL
);
2315 //////////////////////////////////////////////////////
2317 static bool OnBindButton (ushort action
, int button
, void *data
, LGadBox
*)
2319 cOptions
*panel
= (cOptions
*)data
;
2321 panel
->OnBind (action
, button
);
2325 //////////////////////////////////////////////////////
2327 void OnBind (ushort action
, int button
)
2329 if (!(action
& BUTTONGADG_LCLICK
))
2332 static int prev_pick
;
2333 if (!strcmp ((const char *)mBindButtonElems
[button
].draw_data
, "")) {
2334 LGadRadioButtonSelect (&mBindButtons
, prev_pick
);
2340 //////////////////////////////////////////////////////
2342 static bool OnListButton (ushort action
, int button
, void *data
, LGadBox
*)
2344 cOptions
*panel
= (cOptions
*)data
;
2346 panel
->OnList (action
, button
);
2350 //////////////////////////////////////////////////////
2352 void OnList (ushort action
, int button
)
2354 if (!(action
& BUTTONGADG_LCLICK
))
2357 BOOL valid_butt
= TRUE
;
2359 //display device choice
2360 if (mListSub
== kSubAdvancedVideo
) {
2361 //the button clicked was not filled
2362 if (button
>= mNumVidDevices
) {
2363 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
);
2367 //there was something there
2369 config_set_int ("d3d_driver_index", button
);
2375 else if (mListSub
== kSubBasicVideo
) {
2376 //the button clicked was not filled
2377 if (button
>= mNumListTotal
) {
2378 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
);
2382 mSelectedRes
= mTopList
+ button
;
2388 mListPrevPick
= button
;
2391 //////////////////////////////////////////////////////
2393 void OnButtonList(ushort action
, int button
)
2395 if (!(action
& BUTTONGADG_LCLICK
))
2402 if (mCurSub
== kSubList
)
2403 OnSubPanelButtonList (action
, 0);
2405 cAutoIPtr
<IPanelMode
> mode
= GetPanelMode();
2415 int cDPCOptions::gFirstSubRect
[] =
2417 cDPCOptions::kFirstControlButt
,
2418 cDPCOptions::kFirstBasicVideoButt
,
2419 cDPCOptions::kFirstAdvancedVideoButt
,
2420 cDPCOptions::kFirstAudioButt
,
2421 cDPCOptions::kFirstGameButt
,
2422 cDPCOptions::kFirstBindButt
,
2423 cDPCOptions::kFirstListButt
,
2426 int cDPCOptions::gVolSliderRects
[] =
2428 cDPCOptions::kVolumeSliderRect
,
2429 cDPCOptions::k3dVolumeSliderRect
,
2430 cDPCOptions::kMusicSliderRect
,
2435 // Options Menu descriptor
2438 static const char* options_button_names
[] =
2443 sDarkPanelDesc
cOptions::gDesc
=
2446 cOptions::kNumButts
,
2447 cOptions::kNumRects
,
2448 cOptions::kNumButts
,
2449 options_button_names
,
2452 kMetaSndPanelOptions
2457 EXTERN
void SwitchToDPCOptionsMode(BOOL push
)
2461 cAutoIPtr
<IPanelMode
> panel
= gpOptions
->GetPanelMode();
2462 panel
->Switch((push
) ? kLoopModePush
: kLoopModeSwitch
);
2467 const sLoopInstantiator
* DescribeDPCOptionsMode(void)
2471 cAutoIPtr
<IPanelMode
> panel
= gpOptions
->GetPanelMode();
2472 return panel
->Instantiator();
2478 //Wrapper so that others can use this easier..
2479 //Will stuff retrieve_num many controls bound to cmd into the dest
2480 //string array, and will return how many actually got stuff
2482 int GetCmdBinds (const char *cmd
, cStr
*dest
, int retrieve_num
)
2484 return gpOptions
->GetCmdBinds (cmd
, dest
, retrieve_num
);
2491 // Init and term stuff
2494 void DPCOptionsMenuInit ()
2496 gpOptions
= new cOptions
;
2497 gpOptions
->SetInitialSub ();
2498 DPCInitBindSaveLoad();
2501 void DPCOptionsMenuTerm ()
2504 DPCTermBindSaveLoad();