2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
6 // $Header: r:/t2repos/thief2/src/shock/shkoptmn.cpp,v 1.20 1999/08/27 13:04:56 mahk Exp $
59 #define kVolumeSliderNotches 25
60 #define kOneOverVolumeSliderNotches ((1.0)/(float)kVolumeSliderNotches)
62 static void TouchGamma (float gamma
)
69 //is the difficulty setting greyed out or not?
70 static BOOL g_diff_active
= TRUE
;
77 inline int DIFF2BUTT(int x
)
80 if (x
< kShockFirstDiff
)
82 if (x
>= kShockLimDiff
)
88 #define BUTT2DIFF(x) ((x) + 1)
91 EXTERN BOOL g_zbuffer_toggle
;
92 extern int sfx_use_channels
;
97 #define MAX_NUM_BINDABLE 64
98 #define QUICKCONFIG_BINDNUM 15 /*number of quick configurable commands*/
99 #define NUM_BIND_SLOTS 13
100 //max cmds we will display per a given cmd
101 #define MAX_BINDS_PER_CMD 3
105 #define SLIDER_BMPRES 0
106 #define BINDUP_BMPRES 1
107 #define BINDDN_BMPRES 2
110 #define FILL_SUBPANEL 666
112 #define LRMOD(x) (!strcmp (x, "lalt") || !strcmp (x, "ralt") || \
113 !strcmp (x, "lctrl") || !strcmp (x, "rctrl") || \
114 !strcmp (x, "lshift") || !strcmp (x, "rshift"))
118 #define MIN_RES_X 640
119 #define MIN_RES_Y 480
120 #define MAX_RES_Y 768
122 //all 8-bit for software
123 static short soft_modes
[] = {
132 //#define CanChangeEAX() (SFX_Is_EAX_Available())
133 #define CanChangeEAX() (SFX_Is_EAX_Available() && (SFX_GetSoundDevice () == SFXDEVICE_A3D))
137 AutoAppIPtr(SimManager
);
138 return (pSimManager
->LastMsg() & (kSimInit
| kSimResume
)) != 0;
141 #define CanChangeSoundDeviceNow() (!InSim())
144 BOOL
CanChangeDifficultyNow()
146 AutoAppIPtr(NetManager
);
147 return !pNetManager
->IsNetworkGame();
151 static const DrawElement def_draw_elem
=
153 0, 0, 0, // type, data, data2
154 0, 0, // fcolor bcolor
155 INTERNAL(DRAWFLAG_INT_TRANSP
), // flags
158 static void InitDrawElem(DrawElement
* elem
)
160 *elem
= def_draw_elem
;
164 //------------------------------------------------------------
168 typedef class cShockOptions cOptions
;
170 static cOptions
*gpOptions
= NULL
;
173 class cShockOptions
: public cDarkPanel
175 static sDarkPanelDesc gDesc
;
178 cOptions() : cDarkPanel(&gDesc
)
180 memset(&mTabButtons
,0,sizeof(mTabButtons
));
181 memset(mSubPanelButtons
,0,sizeof(mSubPanelButtons
));
182 memset(&mListButtons
,0,sizeof(mListButtons
));
183 memset(&mBindButtons
,0,sizeof(mBindButtons
));
184 memset(&mBindScrollers
,0,sizeof(mBindScrollers
));
185 memset(mSliders
,0,sizeof(mSliders
));
189 void SetInitialSub ()
191 mCurSub
= kSubControls
;
194 //Will stuff retrieve_num many controls bound to cmd into the dest
195 //string array, and will return how many actually got stuff
196 int GetCmdBinds (const char *cmd
, cStr
*dest
, int retrieve_num
, cStr
* raw_dest
= NULL
)
198 char control_buf
[64];
199 char controls
[4][32];
200 long num_controls
, i
, cur_control
;
202 g_pInputBinder
->GetControlFromCmdStart ((char *)cmd
, control_buf
);
205 for (cur_control
= 0; *control_buf
!= '\0' && cur_control
< retrieve_num
;) {
206 g_pInputBinder
->DecomposeControl (control_buf
, controls
, &num_controls
);
207 //we don't want to throw in the l/r mods
208 for (i
= 0; i
< num_controls
&& !LRMOD (controls
[i
]); i
++);
210 //no l/r's, this control is cool. fetch names
211 if (i
== num_controls
)
213 cStr
& cur_dest
= dest
[cur_control
];
215 cStr temp_raw
; // We might not have a raw_dest
216 cStr
& cur_raw
= (raw_dest
) ? raw_dest
[cur_control
] : temp_raw
;
220 for (i
= 0; i
< num_controls
; i
++)
228 cStr str
= FetchUIString ("controls", controls
[i
], mResPath
);
230 //does this key have a translated string?
231 cur_dest
+= (*str
) ? str
: controls
[i
];
232 cur_raw
+= controls
[i
];
238 g_pInputBinder
->GetControlFromCmdNext (control_buf
);
248 kSubFillRect
= kNumButts
,
264 kCustomize
= kFirstControlButt
,
271 kMouseSensSliderRect
= kFirstControlRect
,
274 kNumControlButts
= kFirstControlRect
- kFirstControlButt
,
275 kNumControlRects
= kLimControlRect
- kFirstControlButt
,
278 kFirstBasicVideoButt
= kLimControlRect
,
279 kScreenRes
= kFirstBasicVideoButt
,
282 kFirstBasicVideoRect
,
283 kGammaSliderRect
= kFirstBasicVideoRect
,
286 kNumBasicVideoButts
= kFirstBasicVideoRect
- kFirstBasicVideoButt
,
287 kNumBasicVideoRects
= kLimBasicVideoRect
- kFirstBasicVideoRect
,
289 kFirstAdvancedVideoButt
= kLimBasicVideoRect
,
290 kHardwareDriverOld
= kFirstAdvancedVideoButt
,
293 kLimAdvancedVideoRect
,
294 kNumAdvancedVideoRects
= kLimAdvancedVideoRect
- kFirstAdvancedVideoButt
,
296 //audio buttons/rects
297 kFirstAudioButt
= kLimAdvancedVideoRect
,
298 kSpeakerTest
= kFirstAudioButt
,
305 kVolumeSliderRect
= kFirstAudioRect
,
313 kNumAudioButts
= kFirstAudioRect
- kFirstAudioButt
,
314 kNumAudioRects
= kLimAudioRect
- kFirstAudioButt
,
316 //game buttons (Note irregularity)
317 kFirstGameRect
= kLimAudioRect
,
318 kDiffTextRect
= kFirstGameRect
,
320 kDiff0
= kFirstGameButt
,
325 kNumGameButts
= kLimGameRect
- kFirstGameButt
,
326 kNumGameRects
= kLimGameRect
- kFirstGameRect
,
329 kFirstBindButt
= kLimGameRect
,
330 kBindLoad
= kFirstBindButt
,
336 kBindButt0
,//0 to NUM_BIND_SLOTS - 1
338 kBindScrollUp
= kBindButt0
+ NUM_BIND_SLOTS
,
341 kNumBindButts
= kBindButt0
- kFirstBindButt
,
342 kNumBindRects
= kLimBindRects
- kFirstBindButt
,
344 kFirstListButt
= kLimBindRects
,
345 kListBack
= kFirstListButt
,
346 kList0
,//13 of these, just add what is needed.
347 kNumListButts
= kList0
- kFirstListButt
,
348 kNumListRects
= NUM_LIST
+ kNumListButts
,
351 kNumSubPanelRects
= kNumControlRects
+ kNumBasicVideoRects
+ kNumAdvancedVideoRects
352 + kNumAudioRects
+ kNumGameRects
+ kNumBindRects
+ kNumListRects
,
360 kMouseSensSlider
= kNumVolumeSliders
,
384 kMiscStrForwardBackward
,
390 static int gFirstSubRect
[];
397 cStr mMiscStrs
[kNumMiscStrs
];
399 IRes
*mButtBmpRes
[3][4];//4 button draw states
400 DrawElement mButtDrawElem
[3];
403 LGadButtonList mTabButtons
;
404 LGadButtonListDesc mTabDesc
;
405 cRectArray mTabRects
;
406 DrawElement mTabElems
[kNumTabs
];
407 cStr mTabStrs
[kNumTabs
];
411 LGadButtonList mSubPanelButtons
[kNumSubs
];
412 LGadButtonListDesc mSubPanelDesc
[kNumSubs
];
413 cRectArray mSubPanelRects
;
414 DrawElement mSubPanelElems
[kNumSubPanelRects
];
415 cStr mSubPanelStrs
[kNumSubPanelRects
];
422 LGadButtonList mListButtons
;
423 LGadButtonListDesc mListButtonDesc
;
424 DrawElement mListButtonElems
[NUM_LIST
];
425 cStr mListButtonStrs
[NUM_LIST
];
432 //binding-related data
437 LGadButtonList mBindButtons
;
438 LGadButtonListDesc mBindButtonDesc
;
439 DrawElement mBindButtonElems
[NUM_BIND_SLOTS
];
440 cStr mBindButtonStrs
[MAX_NUM_BINDABLE
];
441 cStr mBindCmd
[MAX_NUM_BINDABLE
];
442 bool mBindButtsFilled
[MAX_NUM_BINDABLE
];
444 LGadButtonList mBindScrollers
;
445 LGadButtonListDesc mBindScrollerDesc
;
451 LGadSlider mSliders
[kNumSubPanelSlides
];
452 bool mSlidersOn
[kNumSubPanelSlides
];
453 DrawElement mSliderBaseBmp
;
459 int m_volume
[kNumVolumeSliders
];
463 typedef bool (*ButtListCB
)(ushort
, int, void *, LGadBox
*);
466 //////////////////////////////////////////////////////
468 void SetBoxData(LGadBox
* box
)
470 LGadBoxSetUserData (box
, this);
472 int flags
= LGadBoxFlags(box
);
473 LGadBoxSetFlags(box
, flags
| BOXFLAG_CLEAR
);
476 typedef int (*vol_get_func
)(void);
478 uint
MillibelToSlider(int vol
)
480 uint retval
= (uint
) ( VolMillibelToLinear((float)vol
) * kVolumeSliderNotches
);
481 if (retval
>= kVolumeSliderNotches
)
482 retval
= kVolumeSliderNotches
- 1;
487 // get slider volume, in slider notches
488 uint
GetVolume(uint which
)
490 static vol_get_func funcs
[] =
497 if (which
== k3dVolumeSlider
)
499 uint vol3d
= MillibelToSlider(SFX_Get3dVolume());
500 uint vol2d
= MillibelToSlider(SFX_Get2dVolume());
503 vol2d
= kVolumeSliderNotches
- vol2d
;
504 return (kVolumeSliderNotches
+ vol2d
)/2;
510 int vol
= funcs
[which
]();
511 return MillibelToSlider(vol
);
515 typedef void (*vol_set_func
)(int);
517 // set volume, in slider notches
518 void SetVolume(int which
, int vol
)
520 static vol_set_func funcs
[] =
527 vol_set_func func
= funcs
[which
];
528 // the 3d volume slider is really a "mix" between 2d and 3d
529 if (which
== k3dVolumeSlider
)
531 int half
= (kVolumeSliderNotches
+ 1)/2;
535 func
= SFX_Set3dVolume
;
541 func
= SFX_Set2dVolume
;
542 vol
= (kVolumeSliderNotches
- vol
)*2;
546 Assert_(which
< kNumVolumeSliders
);
548 float fvol
= VolLinearToMillibel((float)vol
* kOneOverVolumeSliderNotches
);
554 static int gVolSliderRects
[];
559 cDarkPanel::InitUI();
561 //load in the tab and subpanel rectangles
562 AppendRects ("optiontr", mTabRects
);//tabs
563 AppendRects ("optioncr", mSubPanelRects
);//controls
564 AppendRects ("optnbvr", mSubPanelRects
);//basic video
565 AppendRects ("optnavr", mSubPanelRects
);//advanced video
566 AppendRects ("optionar", mSubPanelRects
);//audio
567 AppendRects ("optiongr", mSubPanelRects
);//game
568 AppendRects ("optionbr", mSubPanelRects
);//bindings
569 AppendRects ("optionlr", mSubPanelRects
);//list
571 //load miscellaneous strings
573 for (long i
= 0; i
< kNumMiscStrs
; i
++) {
574 sprintf (buf
, "misc_%d", i
);
575 mMiscStrs
[i
] = FetchUIString (panel_name
, buf
, mResPath
);
578 //create our "tabs" at the top of the menu for the different major categories
579 InitButtonList (&mTabDesc
, &mTabRects
[0], mTabElems
, OnTabButton
, mTabStrs
, "tab_", kNumTabs
, BUTTONLIST_RADIO_FLAG
);
580 LGadCreateButtonListDesc (&mTabButtons
, LGadCurrentRoot(), &mTabDesc
);
581 SetBoxData(VB(&mTabButtons
));
583 int sub_tabs
[] = {0, 1, 1, 2, 3, 0, 1};
584 LGadRadioButtonSelect (&mTabButtons
, sub_tabs
[mCurSub
]);
586 // default to current style colors
587 AssertMsg (GetCurrentStyle (), "No current style for diff defaults");
588 memset (&mTextStyle
, 0, sizeof (guiStyle
));
589 memcpy (mTextStyle
.colors
, GetCurrentStyle ()->colors
, sizeof(mTextStyle
.colors
));
590 uiGameLoadStyle ("opttext_", &mTextStyle
, mResPath
);
592 // style for greyed area
593 AssertMsg (GetCurrentStyle (), "No current style for diff defaults");
594 memcpy (&mGreyStyle
, GetCurrentStyle (), sizeof(guiStyle
));
595 uiGameLoadStyle ("grey_", &mGreyStyle
, mResPath
);
597 //get our slider button bitmap
598 AutoAppIPtr (ResMan
);
599 for (i
= 0; i
< 4; i
++) {
600 mButtBmpRes
[SLIDER_BMPRES
][i
] = pResMan
->Bind ("slidbutt", RESTYPE_IMAGE
, NULL
, mResPath
);
601 if (!mButtBmpRes
[SLIDER_BMPRES
][i
])
602 AssertMsg (0, "Error loading button bitmap");
604 InitDrawElem(&mButtDrawElem
[SLIDER_BMPRES
]);
605 mButtDrawElem
[SLIDER_BMPRES
].draw_data
= (void *)mButtBmpRes
[SLIDER_BMPRES
];
606 mButtDrawElem
[SLIDER_BMPRES
].draw_type
= DRAWTYPE_RESOFFSET
;
608 InitDrawElem(&mSliderBaseBmp
);
609 mSliderBaseBmp
.draw_type
= DRAWTYPE_RES
;
610 mSliderBaseBmp
.draw_data
= (void *)pResMan
->Bind ("slidbase", RESTYPE_IMAGE
, NULL
, mResPath
);
612 for (i
= 0; i
< kNumSubPanelSlides
; i
++)
613 mSlidersOn
[i
] = FALSE
;
615 //set sliders initial vals
616 m_sens
= int((atof (g_pInputBinder
->ProcessCmd ("echo $mouse_sensitivity")) - 0.5) * 2.0);
618 for (int v
= 0; v
< kNumVolumeSliders
; v
++)
619 m_volume
[v
] = GetVolume(v
);
620 m_gamma
= 20-(20.0 / (MAX_GAMMA
- MIN_GAMMA
)) * (g_gamma
- MIN_GAMMA
);
623 if (config_is_defined("d3d_driver_index"))
624 config_get_int("d3d_driver_index", &m3dDriver
);
626 //initialize our subpanels
629 InitControlOptions ();
636 //our handler for handling keyboard arrows and enter in the binding menu
638 uiGetCurrentSlab (&slab
);
640 uiInstallRegionHandler (slab
->creg
, UI_EVENT_KBD_COOKED
, StaticBindKeyHandler
, NULL
, &m_cookie
);
643 //////////////////////////////////////////////////////
647 LGadDestroyButtonList(&mTabButtons
);
649 memset(&mTabElems
,0,sizeof(mTabElems
));
650 for (int i
= 0, j
; i
< kNumTabs
; i
++)
654 uiGameUnloadStyle (&mBindStyle
);
655 uiGameUnloadStyle (&mTextStyle
);
657 for (i
= 0; i
< 3; i
++)
658 for (j
= 0; j
< 4; j
++)
659 mButtBmpRes
[i
][j
]->Release ();
661 ((IRes
*)(mSliderBaseBmp
.draw_data
))->Release ();
663 //save the current bindings upon exit of the options menu
664 //change to game context
666 g_pInputBinder
->GetContext (&old_context
);
667 g_pInputBinder
->SetContext (HK_GAME_MODE
,FALSE
);
668 cStr header
= FetchUIString (panel_name
, "bnd_header", mResPath
);
669 g_pInputBinder
->SaveBndFile ("user.bnd", (char *)(const char *)header
);
670 //plop in input variable control settings
671 BndAppendControls ();
673 g_pInputBinder
->SetContext (HK_GAME2_MODE
,FALSE
);
674 g_pInputBinder
->SaveBndFile ("user2.bnd", (char *)(const char *)header
);
675 g_pInputBinder
->SetContext (old_context
,FALSE
);
677 //remove the binding keyboard handler
679 uiGetCurrentSlab (&slab
);
680 uiRemoveRegionHandler (LGadBoxRegion (slab
->creg
), m_cookie
);
682 cDarkPanel::TermUI();
686 //////////////////////////////////////////////////////
690 LGadDestroyButtonList (&mSubPanelButtons
[mCurSub
]);
692 if (mCurSub
== kSubBind
) {
693 LGadDestroyButtonList (&mBindButtons
);
694 LGadDestroyButtonList (&mBindScrollers
);
697 memset (mSubPanelElems
, 0, kNumSubPanelRects
* sizeof(DrawElement
));
698 for (int i
= 0; i
< kNumSubPanelRects
; i
++)
699 mSubPanelStrs
[i
] = "";
701 //if there are any sliders, kill them
702 DestroyAllSliders ();
704 mTabRects
.SetSize (0);
705 mSubPanelRects
.SetSize (0);
708 //////////////////////////////////////////////////////
712 if (mCurSub
== kSubBind
) {
713 LGadDestroyButtonList (&mBindButtons
);
714 LGadDestroyButtonList (&mBindScrollers
);
717 else if (mCurSub
== kSubList
) {
718 if (mListSub
== kSubBasicVideo
) {
722 LGadDestroyButtonList (&mListButtons
);
726 //////////////////////////////////////////////////////
728 void OnLoopMsg (eLoopMessage msg
, tLoopMessageData msg_data
)
730 if (SFX_GetSoundDevice () == SFXDEVICE_A3D
) {
731 mxs_vector origin
= {0.0, 0.0, 0.0};
732 SFX_Frame (&origin
, (mxs_angvec
*)&origin
);
735 SFX_Frame (NULL
, NULL
);
738 SwapSubPanel (mSwap
);
749 for (int i
= 0; i
< kNumVolumeSliders
; i
++)
750 SetVolume(i
,m_volume
[i
]);
757 sprintf (buf
, "mouse_sensitivity %8.8f", ((double)m_sens
/ 2.0) + 0.5);//slide goes from 0.5 (slow) to 10.5 (fast)
758 g_pInputBinder
->ProcessCmd (buf
);
766 static int prev_gamma
;
767 if (prev_gamma
!= m_gamma
) {
768 TouchGamma ((((MAX_GAMMA
- MIN_GAMMA
) / 20.0) * (float)(20-m_gamma
)) + MIN_GAMMA
);
769 prev_gamma
= m_gamma
;
777 //////////////////////////////////////////////////////
779 void InitControlOptions ()
781 InitButtonList(&mSubPanelDesc
[kSubControls
], &mSubPanelRects
[(int)kCustomize
], &mSubPanelElems
[(int)kCustomize
], OnSubPanelButton
,
782 &mSubPanelStrs
[(int)kCustomize
], "control_", kNumControlButts
, 0);
784 //set starting button strings
786 // watch me factor code like the dickens.
787 static const char* cmds
[] =
791 "echo $mouse_invert",
796 for (int i
= kLookspring
; i
< kFirstControlRect
; i
++)
798 int idx
= i
- kFirstControlButt
;
800 char *str
= g_pInputBinder
->ProcessCmd((char*)cmds
[idx
]); // command value
801 cStr
& substr
= mSubPanelStrs
[i
]; // button string
802 DrawElement
& elem
= mSubPanelElems
[i
]; // button elem
804 sprintf(res_str
,"control_%d",i
);
806 BOOL state
= atof(str
) != 0.0;
807 const char* state_str
;
809 if (i
== kJoyRotate
) // exception
811 if (g_joystickActive
)
812 state_str
= mMiscStrs
[(state
) ? kMiscStrLeftRight
: kMiscStrForwardBackward
];
820 state_str
= mMiscStrs
[(state
) ? kMiscStrOn
: kMiscStrOff
];
822 SetUIString(substr
,elem
,res_str
,(char*)state_str
);
828 //////////////////////////////////////////////////////
830 void BndAppendControls ()
832 FILE *fp
= fopen ("user.bnd", "at");
837 char *controls
[] = {"lookspring", "mouse_invert", "freelook", "mouse_sensitivity", "\0"};
839 char **p_control
= controls
;
841 while (**p_control
) {
842 sprintf (str
, "echo $%s", *p_control
);
843 fprintf (fp
, "%s %s\r\n", *p_control
, g_pInputBinder
->ProcessCmd (str
));
851 //////////////////////////////////////////////////////
853 void InitVideoOptions ()
855 InitButtonList (&mSubPanelDesc
[kSubBasicVideo
], &mSubPanelRects
[(int)kFirstBasicVideoButt
], &mSubPanelElems
[(int)kFirstBasicVideoButt
],
856 OnSubPanelButton
, &mSubPanelStrs
[(int)kFirstBasicVideoButt
], "videob_", kNumBasicVideoButts
, 0);
858 int first
= kFirstAdvancedVideoButt
;
859 InitButtonList (&mSubPanelDesc
[kSubAdvancedVideo
], &mSubPanelRects
[first
], &mSubPanelElems
[first
],
860 OnSubPanelButton
, &mSubPanelStrs
[(int)first
], "videoa_", kNumAdvancedVideoRects
, 0);
865 //let's get some info about the video card
866 mNumVidDevices
= lgd3d_enumerate_devices ();
868 sScrnMode mode
= *GetGameScreenMode();
870 if (mNumVidDevices
> 0 && (mode
.flags
& kScrnMode3dDriver
)) {
871 g_zbuffer_toggle
= TRUE
;
872 mode
.flags
|= kScrnMode3dDriver
;
873 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
874 (char *)(const char *)mMiscStrs
[(g_zbuffer_toggle
&& (mode
.flags
& kScrnMode3dDriver
) != 0) ? kMiscStrOn
: kMiscStrOff
]);
878 g_zbuffer_toggle
= FALSE
;
879 mode
.flags
&= ~kScrnMode3dDriver
;
880 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
881 (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
884 SetGameScreenMode (&mode
);
888 //////////////////////////////////////////////////////
890 void InitAudioOptions ()
892 InitButtonList (&mSubPanelDesc
[kSubAudio
], &mSubPanelRects
[(int)kSpeakerTest
], &mSubPanelElems
[(int)kSpeakerTest
], OnSubPanelButton
,
893 &mSubPanelStrs
[(int)kSpeakerTest
], "audio_", kNumAudioButts
, 0);
895 SetUIString (mSubPanelStrs
[(int)kStereoToggle
], mSubPanelElems
[(int)kStereoToggle
], "audio_1",
896 (char *)(const char *)mMiscStrs
[(SFX_StereoReversed ()) ? kMiscStrOn
: kMiscStrOff
]);
898 SetUIString (mSubPanelStrs
[(int)kA3DToggle
], mSubPanelElems
[(int)kA3DToggle
], "audio_2",
899 (char *)(const char *)mMiscStrs
[(SFX_GetSoundDevice () == SFXDEVICE_A3D
) ? kMiscStrOn
: kMiscStrOff
]);
902 sprintf (buf
, "%d", sfx_use_channels
);
903 mSubPanelStrs
[(int)kAudioChannels
] += buf
;
904 SetUIString (mSubPanelStrs
[(int)kAudioChannels
], mSubPanelElems
[(int)kAudioChannels
], "audio_3", buf
);
906 BOOL isEAXOn
= SFX_Is_EAX_Enabled();
907 SetUIString (mSubPanelStrs
[(int)kAudioEAXToggle
], mSubPanelElems
[(int)kAudioEAXToggle
], "audio_4",
908 (char *)(const char *)mMiscStrs
[isEAXOn
? kMiscStrOn
: kMiscStrOff
]);
911 //////////////////////////////////////////////////////
913 void InitGameOptions ()
915 int first
= kFirstGameButt
;
916 InitButtonList (&mSubPanelDesc
[kSubGame
], &mSubPanelRects
[first
], &mSubPanelElems
[first
], OnSubPanelButton
,
917 &mSubPanelStrs
[first
], "game_", kNumGameButts
, BUTTONLIST_RADIO_FLAG
);
920 //////////////////////////////////////////////////////
922 void InitBindOptions ()
924 InitButtonList (&mSubPanelDesc
[kSubBind
], &mSubPanelRects
[(int)kBindLoad
], &mSubPanelElems
[(int)kBindLoad
], OnSubPanelButton
,
925 &mSubPanelStrs
[(int)kBindLoad
], "bind_", kNumBindButts
, 0);
927 //set up description for binding buttons. joy.
928 //rearrange a few rects
930 cRectArray tmp_rects
;
931 tmp_rects
.SetSize (NUM_BIND_SLOTS
);
932 for (long i
= 0; i
< (NUM_BIND_SLOTS
- 2); i
++)
933 tmp_rects
[i
] = mSubPanelRects
[(int)kBindButt0
+ 2 + i
];
934 tmp_rects
[NUM_BIND_SLOTS
- 2] = mSubPanelRects
[(int)kBindScrollUp
];
935 tmp_rects
[NUM_BIND_SLOTS
- 1] = mSubPanelRects
[(int)kBindButt0
+ 1];
936 for (i
= 0; i
< NUM_BIND_SLOTS
; i
++)
938 mSubPanelRects
[(int)kBindButt0
+ 1 + i
] = tmp_rects
[i
];
939 InitDrawElem(&mBindButtonElems
[i
]);
940 mBindButtonElems
[i
].draw_type
= DRAWTYPE_TEXT
;
942 //description of binding radio buttons
944 LGadButtonListDesc tmp_desc
= {NUM_BIND_SLOTS
, (Rect
*)&mSubPanelRects
[(int)kBindButt0
],
945 mBindButtonElems
, OnBindButton
, 0, BUTTONLIST_RADIO_FLAG
};
946 memcpy (&mBindButtonDesc
, &tmp_desc
, sizeof (LGadButtonListDesc
));
949 // default to current style colors
950 AssertMsg (GetCurrentStyle (), "No current style for diff defaults");
951 memset (&mBindStyle
, 0, sizeof (mBindStyle
));
952 memcpy (mBindStyle
.colors
, GetCurrentStyle()->colors
, sizeof (mBindStyle
.colors
));
953 uiGameLoadStyle("bind_", &mBindStyle
, mResPath
);
960 sprintf (buf
, "bindcmd_%d", mNumBindable
);
961 bind_cmd
= FetchUIString ("bindcmds", buf
, mResPath
);
963 if (bind_cmd
== "" || mNumBindable
>= MAX_NUM_BINDABLE
)
966 mBindCmd
[mNumBindable
] = bind_cmd
;
967 mBindButtsFilled
[mNumBindable
] = FALSE
;
974 //load bitmaps for up/down scroll arrows
975 LoadButtBmp (mButtBmpRes
[BINDUP_BMPRES
], &mButtDrawElem
[BINDUP_BMPRES
], "bup_");
976 LoadButtBmp (mButtBmpRes
[BINDDN_BMPRES
], &mButtDrawElem
[BINDDN_BMPRES
], "bdn_");
978 //description of binding scroll buttons
980 LGadButtonListDesc tmp_desc
= {2, (Rect
*)&mSubPanelRects
[(int)kBindScrollUp
],
981 &mButtDrawElem
[BINDUP_BMPRES
], OnScrollButton
, 0, 0};
982 memcpy (&mBindScrollerDesc
, &tmp_desc
, sizeof (LGadButtonListDesc
));
987 //////////////////////////////////////////////////////
989 void InitListOptions ()
991 //description of back button
993 LGadButtonListDesc tmp_desc
= {kNumListButts
, (Rect
*)&mSubPanelRects
[(int)kListBack
],
994 &mSubPanelElems
[(int)kListBack
], OnSubPanelButton
, 0, 0};
995 mSubPanelDesc
[kSubList
] = tmp_desc
;
998 mSubPanelStrs
[(int)kListBack
] = FetchUIString (panel_name
, "bind_1", mResPath
);
1000 DrawElement
& backelem
= mSubPanelElems
[(int)kListBack
];
1001 InitDrawElem(&backelem
);
1002 backelem
.draw_data
= (void *)(const char *)mSubPanelStrs
[(int)kListBack
];
1003 backelem
.draw_type
= DRAWTYPE_TEXT
;
1005 //description of list buttons
1007 LGadButtonListDesc tmp_desc
= {NUM_LIST
, (Rect
*)&mSubPanelRects
[(int)kList0
],
1008 mListButtonElems
, OnListButton
, 0, BUTTONLIST_RADIO_FLAG
};
1009 mListButtonDesc
= tmp_desc
;
1017 //////////////////////////////////////////////////////
1019 void FillBindStr (long bind_num
, long butt_num
)
1021 if (bind_num
>= mNumBindable
) {
1022 static char *dummy
= "";
1023 mBindButtonElems
[butt_num
].draw_data
= dummy
;
1027 if (mBindButtsFilled
[bind_num
]) {
1028 mBindButtonElems
[butt_num
].draw_data
= (void*)(const char*)mBindButtonStrs
[bind_num
];
1031 mBindButtsFilled
[bind_num
] = TRUE
;
1034 g_pInputBinder
->GetContext (&old_context
);
1035 if (old_context
!= HK_GAME_MODE
)
1036 g_pInputBinder
->SetContext (HK_GAME_MODE
,FALSE
);
1040 sprintf (buf
, "bindname_%d", bind_num
);
1042 mBindButtonStrs
[bind_num
] = FetchUIString (panel_name
, buf
, mResPath
);
1043 mBindButtonStrs
[bind_num
] += " = ";
1045 cStr controls
[MAX_BINDS_PER_CMD
];
1046 cStr raw_controls
[MAX_BINDS_PER_CMD
];
1047 int num
= GetCmdBinds (mBindCmd
[bind_num
], controls
, MAX_BINDS_PER_CMD
, raw_controls
);
1049 for (long i
= 0; i
< num
; i
++) {
1051 mBindButtonStrs
[bind_num
] += ", ";
1052 mBindButtonStrs
[bind_num
] += controls
[i
];
1055 //there were no controls
1057 mBindButtonStrs
[bind_num
] += mMiscStrs
[kMiscStrEmpty
];
1060 // Copy the controls over to game2
1061 g_pInputBinder
->SetContext(HK_GAME2_MODE
,FALSE
);
1062 for (int i
= 0; i
< num
; i
++)
1064 const char* cmd
= mBindCmd
[bind_num
];
1065 const char* ctrl
= raw_controls
[i
];
1067 // if cmd has a space, we have to quote it, because the binder is stupid
1069 if (strchr(cmd
,' ') != NULL
)
1077 // Check the config to make sure we can bind this stuff in game2
1078 BOOL can_bind
= TRUE
;
1080 sprintf(varbuf
,"%s_bind_game2",ctrl
);
1081 config_get_int(varbuf
,&can_bind
);
1084 g_pInputBinder
->Bind((char*)ctrl
,(char*)cmd
);
1088 if (old_context
!= HK_GAME2_MODE
)
1089 g_pInputBinder
->SetContext (old_context
,FALSE
);
1091 mBindButtonElems
[butt_num
].draw_data
= (void*)(const char*)mBindButtonStrs
[bind_num
];
1094 //////////////////////////////////////////////////////
1096 void FillBindStrs ()
1098 AutoAppIPtr(ResMan
);
1099 IRes
* ctrls
= pResMan
->Bind("controls",RESTYPE_STRING
,NULL
,mResPath
);
1102 IRes
* panel
= pResMan
->Bind(panel_name
,RESTYPE_STRING
,NULL
,mResPath
);
1106 g_pInputBinder
->GetContext (&old_context
);
1107 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
1110 for (long i
= 0, j
= mTopBind
; i
< NUM_BIND_SLOTS
; i
++, j
++) {
1120 //change back to previous mode
1121 g_pInputBinder
->SetContext (old_context
,TRUE
);
1125 //////////////////////////////////////////////////////
1127 static bool StaticBindKeyHandler (uiEvent
*p_event
, Region
*p_reg
, void *state
)
1130 if (gpOptions
->mCurSub
== gpOptions
->kSubBind
&& p_event
->type
== UI_EVENT_KBD_COOKED
)
1131 ret
= gpOptions
->BindKeyHandler ((uiCookedKeyEvent
*)p_event
);
1135 bool BindKeyHandler (uiCookedKeyEvent
*event
)
1137 //only use up actions
1138 if (event
->code
& KB_FLAG_DOWN
)
1143 int cur_selected
= LGadRadioButtonSelection (&mBindButtons
);
1145 switch (event
->code
) {
1148 if (cur_selected
> 0)
1149 LGadRadioButtonSelect (&mBindButtons
, cur_selected
- 1);
1150 else if (mTopBind
> 0) {
1162 if (cur_selected
< (NUM_BIND_SLOTS
- 1))
1163 LGadRadioButtonSelect (&mBindButtons
, cur_selected
+ 1);
1164 else if (mTopBind
< mNumBindable
- NUM_BIND_SLOTS
) {
1175 mTopBind
-= NUM_BIND_SLOTS
;
1178 LGadRadioButtonSelect (&mBindButtons
, 0);
1187 mTopBind
+= NUM_BIND_SLOTS
;
1188 if (mTopBind
>= (mNumBindable
- NUM_BIND_SLOTS
)) {
1189 mTopBind
= mNumBindable
- NUM_BIND_SLOTS
;
1190 LGadRadioButtonSelect (&mBindButtons
, NUM_BIND_SLOTS
- 1);
1200 LGadRadioButtonSelect (&mBindButtons
, 0);
1201 if (mTopBind
!= 0) {
1210 LGadRadioButtonSelect (&mBindButtons
, NUM_BIND_SLOTS
- 1);
1211 if (mTopBind
!= (mNumBindable
- NUM_BIND_SLOTS
)) {
1212 mTopBind
= mNumBindable
- NUM_BIND_SLOTS
;
1219 case KEY_GREY_ENTER
:
1220 OnSubPanelButtonList (BUTTONGADG_LCLICK
, kBind
- kBindLoad
);
1229 FillBlack (FILL_SUBPANEL
);
1237 //////////////////////////////////////////////////////
1242 if (mSelectedRes
== -1)
1245 sScrnMode mode
= *GetGameScreenMode();
1247 char *mode_desc
= (char *)(const char *)mListButtonStrs
[mSelectedRes
];
1248 sscanf (mode_desc
, "%dx%dx%d", &mode
.w
, &mode
.h
, &mode
.bitdepth
);
1250 SetGameScreenMode (&mode
);
1255 // Set the resolution string
1258 int residx
= kScreenRes
;
1259 cStr
& resstr
= mSubPanelStrs
[residx
];
1260 DrawElement
& elem
= mSubPanelElems
[residx
];
1263 const sScrnMode
& mode
= *GetGameScreenMode();
1264 sprintf(buf
,"%dx%dx%d",mode
.w
,mode
.h
,mode
.bitdepth
);
1266 SetUIString(resstr
,elem
,"videob_0",buf
);
1270 //////////////////////////////////////////////////////
1272 void FillVidResStrs ()
1275 const sScrnMode
*mode
= GetGameScreenMode ();
1276 lgd3ds_device_info
*info
;
1278 int idx
= mNumVidDevices
- 1;
1279 if (config_is_defined("d3d_driver_index"))
1280 config_get_int("d3d_driver_index", &idx
);
1281 info
= lgd3d_get_device_info (idx
);
1285 char buf
[32], mode_str
[32];
1287 if (mNumVidDevices
> 0 && (mode
->flags
& kScrnMode3dDriver
)) {
1288 cur_mode
= &info
->supported_modes
[mTopList
];
1292 cur_mode
= &soft_modes
[mTopList
];
1296 //get current mode string so we know what to select
1297 sprintf (mode_str
, "%dx%dx%d", mode
->w
, mode
->h
, mode
->bitdepth
);
1298 //dunny button will be default selection if we dont have a matching res for some reason
1299 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
= NUM_LIST
- 1);
1302 for (long i
= 0, inc
= 0; i
< NUM_LIST
; i
+= inc
) {
1304 if (*cur_mode
!= -1 && i
< NUM_LIST
- 1)
1306 grs_mode_info
& info
= grd_mode_info
[*cur_mode
];
1308 if (info
.bitDepth
== bpp
1309 && info
.w
>= MIN_RES_X
1310 && info
.h
>= MIN_RES_Y
1311 && info
.h
<= MAX_RES_Y
)
1315 sprintf (buf
, "%dx%dx%d", grd_mode_info
[*cur_mode
].w
,
1316 grd_mode_info
[*cur_mode
].h
, grd_mode_info
[*cur_mode
].bitDepth
);
1318 mListButtonStrs
[i
] = buf
;
1320 if (!strcmp (buf
, mode_str
))
1321 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
= i
);
1329 mListButtonStrs
[i
] = "";
1333 DrawElement
& elem
= mListButtonElems
[i
];
1334 InitDrawElem(&elem
);
1335 elem
.draw_data
= (void *)(const char *)mListButtonStrs
[i
];
1336 elem
.draw_type
= DRAWTYPE_TEXT
;
1342 //////////////////////////////////////////////////////
1344 void FillVidDevStrs ()
1346 lgd3ds_device_info
*info
;
1348 for (long i
= 0; i
< NUM_LIST
; i
++) {
1349 if (i
< mNumVidDevices
) {
1350 info
= lgd3d_get_device_info (i
);
1351 mListButtonStrs
[i
] = info
->p_ddraw_desc
;
1354 mListButtonStrs
[i
] = "";
1356 DrawElement
& elem
= mListButtonElems
[i
];
1357 InitDrawElem(&elem
);
1358 elem
.draw_data
= (void *)(const char *)mListButtonStrs
[i
];
1359 elem
.draw_type
= DRAWTYPE_TEXT
;
1362 int idx
= mNumVidDevices
- 1;
1363 if (config_is_defined("d3d_driver_index"))
1364 config_get_int("d3d_driver_index", &idx
);
1365 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
= idx
);
1368 //////////////////////////////////////////////////////
1370 static BOOL
BindFilter (char *control
, char *cmd
, void *data
)
1372 //we'll reserve ESC for breaking from a bind query
1373 if (!strcmp (control
, "esc"))
1376 //don't bind joystick movement
1377 if (!strcmp (control
, "joy_move"))
1380 //scroll lock doesnt have up/down events like a normal key
1381 if (!strcmp (control
, "scroll_lock"))
1384 // don't bind the F keys since the game needs them for psi powers
1386 for (i
=1; i
<= 12; i
++)
1389 sprintf(fkey
,"F%d",i
);
1390 if (!stricmp(control
, fkey
))
1394 // otherwise, it's legal
1398 //////////////////////////////////////////////////////
1400 static void PostBindFunc (BOOL bound
)
1402 for (long i
= 0; i
< gpOptions
->mNumBindable
; i
++)
1403 gpOptions
->mBindButtsFilled
[i
] = FALSE
;
1404 gpOptions
->FillBindStrs ();
1405 gpOptions
->FillBlack (FILL_SUBPANEL
);
1406 gpOptions
->RedrawDisplay ();
1408 g_pInputBinder
->SetContext (gpOptions
->m_old_context
,TRUE
);
1411 //////////////////////////////////////////////////////
1413 static void QuickConfigPostBindFunc (BOOL bound
)
1415 int bind_num
= gpOptions
->mTopBind
+ LGadRadioButtonSelection (&gpOptions
->mBindButtons
) + 1;
1416 if (bind_num
< QUICKCONFIG_BINDNUM
&& bound
) {
1417 if (bind_num
> NUM_BIND_SLOTS
- 1) {
1418 gpOptions
->mTopBind
++;
1420 LGadRadioButtonSelect (&gpOptions
->mBindButtons
, bind_num
- gpOptions
->mTopBind
);
1422 sprintf (buf
, "bindname_%d", bind_num
);
1423 gpOptions
->mBindButtonStrs
[bind_num
] = FetchUIString (gpOptions
->panel_name
, buf
, gpOptions
->mResPath
);
1424 gpOptions
->mBindButtonStrs
[bind_num
] += " = ?";
1426 g_pInputBinder
->TrapBind ((char *)(const char *)gpOptions
->mBindCmd
[bind_num
],
1427 gpOptions
->BindFilter
, gpOptions
->QuickConfigPostBindFunc
, NULL
);
1431 g_pInputBinder
->SetContext (gpOptions
->m_old_context
,TRUE
);
1433 for (long i
= 0; i
< gpOptions
->mNumBindable
; i
++)
1434 gpOptions
->mBindButtsFilled
[i
] = ((i
!= bind_num
|| !bound
) || (bind_num
== QUICKCONFIG_BINDNUM
)) ? FALSE
: TRUE
;
1436 gpOptions
->FillBindStrs ();
1437 gpOptions
->FillBlack (FILL_SUBPANEL
);
1438 gpOptions
->RedrawDisplay ();
1442 //////////////////////////////////////////////////////
1444 void InitButtonList (LGadButtonListDesc
*desc
, Rect
*rect_array
, DrawElement
*draw_elem
,
1445 ButtListCB cb
, cStr
*strs
, const char *prefix
, int num
, int flags
)
1447 // set up drawlelems
1448 for (int i
= 0; i
< num
; i
++) {
1449 DrawElement
*elem
= &draw_elem
[i
];
1453 sprintf(buf
, "%s%d", prefix
, i
);
1454 strs
[i
] = FetchUIString (panel_name
, buf
, mResPath
);
1455 elem
->draw_type
= DRAWTYPE_TEXT
;
1456 elem
->draw_data
= (void*)(const char*)strs
[i
];
1460 LGadButtonListDesc tmp_desc
= {
1469 memcpy (desc
, &tmp_desc
, sizeof (LGadButtonListDesc
));
1473 //////////////////////////////////////////////////////
1475 void DrawButtonList (LGadButtonListDesc
*blist
)
1477 Rect rect
= {{0, 0}, {640, 480}};
1478 uiHideMouse (&rect
);
1480 int num
= blist
->num_buttons
;
1481 for (int i
= 0; i
< num
; i
++) {
1482 ElementDraw (&blist
->button_elems
[i
], dsNORMAL
, blist
->button_rects
[i
].ul
.x
, blist
->button_rects
[i
].ul
.y
,
1483 blist
->button_rects
[i
].lr
.x
- blist
->button_rects
[i
].ul
.x
, blist
->button_rects
[i
].lr
.y
- blist
->button_rects
[i
].ul
.y
);
1486 uiShowMouse (&rect
);
1489 //////////////////////////////////////////////////////
1491 void DrawSlider (int num
, int rect_num
, BOOL draw_slide
= TRUE
)
1493 Rect rect
= {{0, 0}, {640, 480}};
1494 uiHideMouse (&rect
);
1496 Rect
*slide_rect
= (Rect
*)&mSubPanelRects
[rect_num
];
1497 ElementDraw (&mSliderBaseBmp
, dsNORMAL
, slide_rect
->ul
.x
, slide_rect
->ul
.y
,
1498 slide_rect
->lr
.x
- slide_rect
->ul
.x
, slide_rect
->lr
.y
- slide_rect
->ul
.y
);
1500 uiShowMouse (&rect
);
1502 LGadDrawBox ((LGadBox
*)&mSliders
[num
], NULL
);
1505 //////////////////////////////////////////////////////
1507 void LoadButtBmp (IRes
*butt_res
[4], DrawElement
*draw_elem
, char *prefix
)
1509 char *sffx
[] = {"norm", "down", "hlit", "hlit"}, str
[128];
1510 AutoAppIPtr (ResMan
);
1511 for (int i
= 0; i
< 4; i
++) {
1512 butt_res
[i
] = pResMan
->Bind (strcat (strcpy (str
, prefix
), sffx
[i
]), RESTYPE_IMAGE
, NULL
, mResPath
);
1514 AssertMsg (0, "Error loading button bitmap");
1517 InitDrawElem(draw_elem
);
1518 draw_elem
->draw_data
= (void *)butt_res
;
1519 draw_elem
->draw_type
= DRAWTYPE_RESOFFSET
;
1522 //////////////////////////////////////////////////////
1524 void SetUIString (cStr
&str
, DrawElement
&draw_elem
, char *name
, char *suffix
)
1526 str
= FetchUIString (panel_name
, name
, mResPath
);
1529 draw_elem
.draw_data
= (void*)(const char*)str
;
1532 //////////////////////////////////////////////////////
1534 void AppendRects (char *rect_file
, cRectArray
&old_rects
)
1536 long old_sz
, tmp_sz
;
1537 cRectArray tmp_rects
;
1538 FetchUIRects(rect_file
, tmp_rects
, mResPath
);
1539 old_rects
.SetSize ((old_sz
= old_rects
.Size ()) + (tmp_sz
= tmp_rects
.Size ()));
1541 for (long i
= 0, j
= old_sz
; i
< tmp_sz
; i
++, j
++)
1542 old_rects
[j
] = tmp_rects
[i
];
1545 //////////////////////////////////////////////////////
1547 void CreateSlider (int slider_num
, int rect_num
, int *val_ptr
, int num_notches
, int inc
)
1549 LGadSlider
*slider
= &mSliders
[slider_num
];
1550 Rect
*rect
= (Rect
*)&mSubPanelRects
[rect_num
];
1551 memset (slider
, 0, sizeof (LGadSlider
));
1552 slider
->gadg
.draw
= mButtDrawElem
[SLIDER_BMPRES
];
1554 //this is absolutely a hack.
1555 //make the slider's range of motion smaller since the slider's base art
1556 //presents the slide as having a more confined range. 12 pixels will do the trick.
1558 x
= rect
->ul
.x
+ 12;
1559 w
= rect
->lr
.x
- rect
->ul
.x
- 24;
1561 LGadCreateSliderArgs (slider
, LGadCurrentRoot (), x
, rect
->ul
.y
+ ((rect
->lr
.y
- rect
->ul
.y
)>>1), 0, 0, NULL
,
1562 val_ptr
, num_notches
, inc
, w
, LGSLIDER_HORIZONTAL
, 0);
1564 mSlidersOn
[slider_num
] = TRUE
;
1566 LGadDrawBox ((LGadBox
*)slider
, NULL
);
1569 //////////////////////////////////////////////////////
1571 void DestroySlider (int slider_num
)
1573 if (mSlidersOn
[slider_num
]) {
1574 LGadDestroySlider (&mSliders
[slider_num
], FALSE
);
1575 mSlidersOn
[slider_num
] = FALSE
;
1579 //////////////////////////////////////////////////////
1581 void DestroyAllSliders ()
1583 for (int i
= 0; i
< (int)kNumSubPanelSlides
; i
++)
1587 //////////////////////////////////////////////////////
1589 void DrawString (char *strname
, int rect_num
)
1591 cStr str
= FetchUIString (panel_name
, strname
, mResPath
);//copy the string
1592 char *s
= (char*)(const char*)str
;//get a mutable pointer
1594 Rect
&r
= mSubPanelRects
[rect_num
];
1597 InitDrawElem(&draw
);
1598 draw
.draw_type
= DRAWTYPE_TEXT
;
1600 ElementSetStyle(&mTextStyle
);
1601 ElementDraw (&draw
, dsNORMAL
, r
.ul
.x
, r
.ul
.y
, r
.lr
.x
- r
.ul
.x
, r
.lr
.y
- r
.ul
.y
);
1604 //////////////////////////////////////////////////////
1606 void RedrawDisplay ()
1609 region_expose (LGadBoxRegion (&mTabButtons
), LGadBoxRect (&mTabButtons
));
1610 DrawButtonList (&mSubPanelDesc
[mCurSub
]);
1612 //any sub-specific stuff
1615 DrawSlider ((int)kMouseSensSlider
, (int)kMouseSensSliderRect
);
1616 DrawString ("mouse_sens", kMouseSensTextRect
);
1619 case kSubBasicVideo
:
1620 DrawSlider ((int)kGammaSlider
, (int)kGammaSliderRect
);
1621 DrawString ("gamma", kGammaSliderText
);
1626 for (int i
= 0; i
< kNumVolumeSliders
; i
++)
1628 DrawSlider (i
, gVolSliderRects
[i
]);
1630 sprintf(name
,"volume_%d",i
);
1631 DrawString (name
,gVolSliderRects
[i
] + 1); // plus one to get from rect to text rect
1637 region_expose (LGadBoxRegion (&mSubPanelButtons
[kSubGame
]), LGadBoxRect (&mSubPanelButtons
[kSubGame
]));
1638 DrawString ("diff", kDiffTextRect
);
1642 DrawButtonList (&mBindScrollerDesc
);
1643 region_expose (LGadBoxRegion (&mBindButtons
), LGadBoxRect (&mBindButtons
));
1647 region_expose (LGadBoxRegion (&mListButtons
), LGadBoxRect (&mListButtons
));
1648 // DrawButtonList (&mBindScrollerDesc);
1653 //////////////////////////////////////////////////////
1655 void FillBlack (int rect_num
)
1658 if (rect_num
== FILL_SUBPANEL
)
1659 rect
= (Rect
*)&mRects
[(int)kSubFillRect
];
1661 rect
= (Rect
*)&mSubPanelRects
[rect_num
];
1666 //////////////////////////////////////////////////////
1668 void SwapSubPanel (int new_sub
)
1670 if (mCurSub
!= -1) {
1671 LGadDestroyButtonList (&mSubPanelButtons
[mCurSub
]);
1675 if (new_sub
!=kSubAudio
)
1676 metaSndEnterPanel(kMetaSndPanelOptions
);
1678 metaSndExitPanel(TRUE
);
1680 LGadCreateButtonListDesc (&mSubPanelButtons
[new_sub
], LGadCurrentRoot (), &mSubPanelDesc
[new_sub
]);
1681 SetBoxData(VB(&mSubPanelButtons
[new_sub
]));
1687 DrawSlider ((int)kMouseSensSlider
, (int)kMouseSensSliderRect
, FALSE
);
1688 CreateSlider ((int)kMouseSensSlider
, (int)kMouseSensSliderRect
, &m_sens
, 20, 1);
1692 case kSubBasicVideo
:
1694 DrawSlider ((int)kGammaSlider
, (int)kGammaSliderRect
, FALSE
);
1695 CreateSlider ((int)kGammaSlider
, (int)kGammaSliderRect
, &m_gamma
, 20, 1);
1701 for (int i
= 0; i
< kNumVolumeSliders
; i
++)
1703 DrawSlider(i
,gVolSliderRects
[i
],FALSE
);
1704 CreateSlider(i
,gVolSliderRects
[i
],&m_volume
[i
],kVolumeSliderNotches
- 1, 1);
1707 if (! CanChangeSoundDeviceNow ()) {
1708 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioChannels
- kFirstAudioButt
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1709 mSubPanelDesc
[kSubAudio
].button_elems
[kA3DToggle
- kFirstAudioButt
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1712 if (!CanChangeEAX())
1713 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioEAXToggle
- kSpeakerTest
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1719 g_diff_active
= CanChangeDifficultyNow();
1722 AutoAppIPtr(QuestData
);
1723 if (pQuestData
->Exists(DIFF_QVAR
))
1724 g_diff
= pQuestData
->Get(DIFF_QVAR
);
1728 LGadBoxSetStyle (&mSubPanelButtons
[kSubGame
], &mGreyStyle
);
1730 //set the current difficulty setting
1731 LGadRadioButtonSelect (&mSubPanelButtons
[kSubGame
], DIFF2BUTT(g_diff
));
1737 LGadCreateButtonListDesc (&mBindButtons
, LGadCurrentRoot (), &mBindButtonDesc
);
1738 SetBoxData(VB(&mBindButtons
));
1739 LGadRadioButtonSelect (&mBindButtons
,0);
1740 LGadBoxSetStyle (&mBindButtons
, &mBindStyle
);
1742 LGadCreateButtonListDesc (&mBindScrollers
, LGadCurrentRoot (), &mBindScrollerDesc
);
1743 SetBoxData(VB(&mBindScrollers
));
1749 LGadCreateButtonListDesc (&mListButtons
, LGadCurrentRoot (), &mListButtonDesc
);
1750 SetBoxData(VB(&mListButtons
));
1751 LGadBoxSetStyle (&mListButtons
, &mBindStyle
);
1753 // LGadCreateButtonListDesc (&mBindScrollers, LGadCurrentRoot (), &mBindScrollerDesc);
1754 // SetBoxData(VB(&mBindScrollers));
1756 if (mListSub
== kSubAdvancedVideo
)
1758 else if (mListSub
== kSubBasicVideo
)
1765 FillBlack (FILL_SUBPANEL
);
1771 //////////////////////////////////////////////////////
1773 static void PlayRightTest (int, void *)
1776 memset (&parm
, 0, sizeof (sfx_parm
));
1777 parm
.pan
= SFX_StereoReversed() ? -10000 : 10000;
1778 cStr snd_name
= FetchUIString (gpOptions
->panel_name
, "rightsound", gpOptions
->mResPath
);
1780 if (SFX_GetSoundDevice () == SFXDEVICE_A3D
) {
1781 //@TODO: make the a3d speaker test sound crisper, clearer, more refreshed
1782 mxs_vector pos
= {0.0, SFX_StereoReversed() ? 10.0 : -10.0, 0.0};
1783 SFX_Play_Vec (SFX_3D
, &parm
, (char *)(const char *)snd_name
, &pos
);
1786 SFX_Play_Raw (SFX_STATIC
, &parm
, (char *)(const char *)snd_name
);
1789 //////////////////////////////////////////////////////
1791 static bool OnTabButton (ushort action
, int button
, void *data
, LGadBox
*)
1793 cOptions
*panel
= (cOptions
*)data
;
1795 panel
->OnTabButtonList (action
, button
);
1799 //////////////////////////////////////////////////////
1801 void OnTabButtonList (ushort action
, int button
)
1803 if (!(action
& BUTTONGADG_LCLICK
))
1811 if (mCurSub
!= kSubControls
) {
1812 mSwap
= kSubControls
;
1813 DestroyAllSliders ();
1821 if (mCurSub
!= kSubBasicVideo
&& mCurSub
!= kSubAdvancedVideo
) {
1822 DestroyAllSliders ();
1823 mSwap
= kSubBasicVideo
;
1831 if (mCurSub
!= kSubAudio
) {
1832 DestroyAllSliders ();
1841 if (mCurSub
!= kSubGame
) {
1842 DestroyAllSliders ();
1851 //////////////////////////////////////////////////////
1853 static bool OnSubPanelButton (ushort action
, int button
, void *data
, LGadBox
*)
1855 cOptions
*panel
= (cOptions
*)data
;
1857 panel
->OnSubPanelButtonList (action
, button
);
1861 //////////////////////////////////////////////////////
1863 void OnSubPanelButtonList (ushort action
, int button
)
1865 if (!(action
& BUTTONGADG_LCLICK
))
1868 int idx
= button
+ gFirstSubRect
[mCurSub
];
1876 mListSub
= kSubBasicVideo
;
1882 #ifdef ADVANDED_VID_PANEL
1883 case kAdvancedVidOptions
:
1884 DestroyAllSliders ();
1885 mSwap
= kSubAdvancedVideo
;
1889 case kHardwareDriver
:
1891 mListSub
= kSubAdvancedVideo
;
1895 case kZBufferToggle
:
1897 const sScrnMode
*old_mode
= GetGameScreenMode ();
1898 if (mNumVidDevices
> 0 && old_mode
->flags
& kScrnMode3dDriver
) {
1899 if (!g_zbuffer_toggle
) {
1900 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
1901 (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
1902 g_zbuffer_toggle
= TRUE
;
1905 SetUIString (mSubPanelStrs
[(int)kZBufferToggle
], mSubPanelElems
[(int)kZBufferToggle
], "videoa_1",
1906 (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
1907 g_zbuffer_toggle
= FALSE
;
1909 FillBlack ((int)kZBufferToggle
);
1915 case kBasicVidOptions
:
1916 DestroyAllSliders ();
1917 mSwap
= kSubBasicVideo
;
1924 memset (&parm
, 0, sizeof (sfx_parm
));
1925 parm
.pan
= SFX_StereoReversed() ? 10000 : -10000;
1926 parm
.end_callback
= PlayRightTest
;
1927 cStr snd_name
= FetchUIString (panel_name
, "leftsound", mResPath
);
1929 if (SFX_GetSoundDevice () == SFXDEVICE_A3D
) {
1930 mxs_vector pos
= {0.0, SFX_StereoReversed() ? -10.0 : 10.0, 0.0};
1931 //@TODO: make the a3d speaker test sound crisper, clearer, more refreshed
1932 SFX_Play_Vec (SFX_3D
, &parm
, (char *)(const char *)snd_name
, &pos
);
1935 SFX_Play_Raw (SFX_STATIC
, &parm
, (char *)(const char *)snd_name
);
1940 SFX_SetReverseStereo (!SFX_StereoReversed ());
1941 SetUIString (mSubPanelStrs
[(int)kStereoToggle
], mSubPanelElems
[(int)kStereoToggle
], "audio_1",
1942 (char *)(const char *)mMiscStrs
[(SFX_StereoReversed ()) ? kMiscStrOn
: kMiscStrOff
]);
1943 FillBlack (kStereoToggle
);
1948 if (CanChangeSoundDeviceNow()) {
1949 if (SFX_GetSoundDevice () != SFXDEVICE_A3D
)
1951 // Try to use 3D sound hardware
1952 if (! SFX_SetSoundDevice (SFXDEVICE_A3D
, TRUE
))
1954 // If no 3D sound hardware, turn back on software.
1955 SFX_SetSoundDevice (SFXDEVICE_Software
, TRUE
);
1959 SFX_SetSoundDevice (SFXDEVICE_Software
, TRUE
);
1961 SetUIString (mSubPanelStrs
[(int)kA3DToggle
], mSubPanelElems
[(int)kA3DToggle
], "audio_2",
1962 (char *)(const char *)mMiscStrs
[(SFX_GetSoundDevice () == SFXDEVICE_A3D
) ? kMiscStrOn
: kMiscStrOff
]);
1963 FillBlack (kA3DToggle
);
1964 // RedrawDisplay ();
1966 // EAX settings may have changed.
1967 BOOL newEAXState
= SFX_Is_EAX_Enabled();
1968 SetUIString (mSubPanelStrs
[(int)kAudioEAXToggle
], mSubPanelElems
[(int)kAudioEAXToggle
], "audio_4",
1969 (char *)(const char *)mMiscStrs
[newEAXState
? kMiscStrOn
: kMiscStrOff
]);
1971 // Set EAX button color as appropriate.
1972 if ( CanChangeEAX() )
1973 // Hack: This takes the "green" color from the "speaker test" button..... there must be a better way...
1974 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioEAXToggle
- kSpeakerTest
].fcolor
= mSubPanelDesc
[kSubAudio
].button_elems
[0].fcolor
;
1976 mSubPanelDesc
[kSubAudio
].button_elems
[kAudioEAXToggle
- kSpeakerTest
].fcolor
= guiStyleGetColor(&mGreyStyle
,StyleColorText
);
1977 FillBlack (kAudioEAXToggle
);
1983 case kAudioChannels
:
1984 if (CanChangeSoundDeviceNow())
1986 // List of valid selections
1987 static int selections
[] = { 4, 8, 12, 16, 0 };
1988 int chan
= sfx_use_channels
;
1989 for (int* sel
= selections
; *sel
!= 0 && *sel
<= chan
; sel
++)
1992 chan
= selections
[0];
1997 sfx_use_channels
= chan
;
1998 config_set_int("sfx_channels", chan
);
2002 sprintf (buf
, "%d", chan
);
2003 mSubPanelStrs
[(int)kAudioChannels
] += buf
;
2004 SetUIString (mSubPanelStrs
[(int)kAudioChannels
], mSubPanelElems
[(int)kAudioChannels
], "audio_3", buf
);
2008 case kAudioEAXToggle
:
2011 // Toggle EAX state.
2012 BOOL newEAXState
= !SFX_Is_EAX_Enabled();
2018 // Double-check to make sure state actually toggled.
2019 newEAXState
= SFX_Is_EAX_Enabled();
2020 config_set_int ("sfx_eax", (int) newEAXState
);
2021 SetUIString (mSubPanelStrs
[(int)kAudioEAXToggle
], mSubPanelElems
[(int)kAudioEAXToggle
], "audio_4",
2022 (char *)(const char *)mMiscStrs
[newEAXState
? kMiscStrOn
: kMiscStrOff
]);
2027 DestroyAllSliders ();
2032 // I may weep openly
2040 // Set the difficulty
2041 g_diff
= BUTT2DIFF(button
);
2044 AutoAppIPtr(QuestData
);
2045 if (pQuestData
->Exists(DIFF_QVAR
))
2046 pQuestData
->Set(DIFF_QVAR
,g_diff
);
2049 //not active, don't let them change buttons
2051 LGadRadioButtonSelect (&mSubPanelButtons
[kSubGame
], DIFF2BUTT(g_diff
));
2057 SwitchToShockLoadBndMode (TRUE
);
2062 SwitchToShockSaveBndMode (TRUE
);
2066 DestroyAllSliders ();
2067 mSwap
= kSubControls
;
2071 case kQuickConfigure
:
2072 LGadRadioButtonSelect (&mBindButtons
, mTopBind
= 0);
2073 mBindButtonStrs
[0] = FetchUIString (panel_name
, "bindname_0", mResPath
);
2074 mBindButtonStrs
[0] += " = ?";
2076 //change to game context
2077 g_pInputBinder
->GetContext (&m_old_context
);
2078 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
2079 g_pInputBinder
->TrapBind ((char *)(const char *)mBindCmd
[0], BindFilter
, QuickConfigPostBindFunc
, NULL
);
2082 FillBlack (FILL_SUBPANEL
);
2089 int bind_num
= mTopBind
+ LGadRadioButtonSelection (&mBindButtons
);
2091 sprintf (buf
, "bindname_%d", bind_num
);
2092 mBindButtonStrs
[bind_num
] = FetchUIString (panel_name
, buf
, mResPath
);
2093 mBindButtonStrs
[bind_num
] += " = ?";
2095 //change to game context
2096 g_pInputBinder
->GetContext (&m_old_context
);
2097 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
2098 g_pInputBinder
->TrapBind ((char *)(const char *)mBindCmd
[bind_num
], BindFilter
, PostBindFunc
, NULL
);
2101 FillBlack (FILL_SUBPANEL
);
2109 //change to game context
2110 g_pInputBinder
->GetContext (&m_old_context
);
2111 g_pInputBinder
->SetContext (HK_GAME_MODE
,TRUE
);
2113 char str
[128], control_buf
[64];
2114 int bind_num
= mTopBind
+ LGadRadioButtonSelection (&mBindButtons
);
2116 g_pInputBinder
->GetControlFromCmdStart ((char *)(const char *)mBindCmd
[bind_num
], control_buf
);
2117 while (*control_buf
!= '\0') {
2118 strcpy (str
, "unbind ");
2119 strcat (str
, control_buf
);
2120 g_pInputBinder
->ProcessCmd (str
);
2121 g_pInputBinder
->GetControlFromCmdStart ((char *)(const char *)mBindCmd
[bind_num
], control_buf
);
2124 g_pInputBinder
->SetContext (m_old_context
,TRUE
);
2126 for (int i
= 0; i
< mNumBindable
; i
++)
2127 mBindButtsFilled
[i
] = FALSE
;
2129 FillBlack (FILL_SUBPANEL
);
2136 char *inverted
= g_pInputBinder
->ProcessCmd ("echo $lookspring"), buf
[16];
2137 sprintf (buf
, "control_%d", button
);
2138 if (atof (inverted
) == 0.0) {
2139 g_pInputBinder
->ProcessCmd ("lookspring 1");
2140 SetUIString (mSubPanelStrs
[(int)kLookspring
], mSubPanelElems
[(int)kLookspring
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
2142 //when lookspring is turned on, turn off freelook if it is on
2143 if (atof (g_pInputBinder
->ProcessCmd ("echo $freelook")) != 0.0)
2144 OnSubPanelButtonList (action
, kFreelook
- kCustomize
);
2147 g_pInputBinder
->ProcessCmd ("lookspring 0");
2148 SetUIString (mSubPanelStrs
[(int)kLookspring
], mSubPanelElems
[(int)kLookspring
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
2150 FillBlack ((int)kLookspring
);
2157 if (g_joystickActive
)
2159 char *rotate
= g_pInputBinder
->ProcessCmd ("echo $joy_rotate"), buf
[16];
2160 sprintf (buf
, "control_%d", button
);
2161 if (atof (rotate
) == 0.0) {
2162 g_pInputBinder
->ProcessCmd ("joy_rotate 1");
2163 SetUIString (mSubPanelStrs
[(int)kJoyRotate
], mSubPanelElems
[(int)kJoyRotate
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrLeftRight
]);
2166 g_pInputBinder
->ProcessCmd ("joy_rotate 0");
2167 SetUIString (mSubPanelStrs
[(int)kJoyRotate
], mSubPanelElems
[(int)kJoyRotate
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrForwardBackward
]);
2169 FillBlack ((int)kJoyRotate
);
2177 char *inverted
= g_pInputBinder
->ProcessCmd ("echo $mouse_invert"), buf
[16];
2178 sprintf (buf
, "control_%d", button
);
2179 if (atof (inverted
) == 0.0) {
2180 g_pInputBinder
->ProcessCmd ("mouse_invert 1");
2181 SetUIString (mSubPanelStrs
[(int)kMouseInvert
], mSubPanelElems
[(int)kMouseInvert
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
2184 g_pInputBinder
->ProcessCmd ("mouse_invert 0");
2185 SetUIString (mSubPanelStrs
[(int)kMouseInvert
], mSubPanelElems
[(int)kMouseInvert
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
2187 FillBlack ((int)kMouseInvert
);
2195 char *inverted
= g_pInputBinder
->ProcessCmd ("echo $freelook"), buf
[16];
2196 sprintf (buf
, "control_%d", button
);
2197 if (atof (inverted
) == 0.0) {
2198 g_pInputBinder
->ProcessCmd ("freelook 1");
2199 SetUIString (mSubPanelStrs
[(int)kFreelook
], mSubPanelElems
[(int)kFreelook
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOn
]);
2201 //when freelook is turned on, turn off lookspring if it is on
2202 if (atof (g_pInputBinder
->ProcessCmd ("echo $lookspring")) != 0.0)
2203 OnSubPanelButtonList (action
, kLookspring
- kCustomize
);
2206 g_pInputBinder
->ProcessCmd ("freelook 0");
2207 SetUIString (mSubPanelStrs
[(int)kFreelook
], mSubPanelElems
[(int)kFreelook
], buf
, (char *)(const char *)mMiscStrs
[kMiscStrOff
]);
2209 FillBlack ((int)kFreelook
);
2217 DestroyAllSliders ();
2219 if (mListSub
== kSubAdvancedVideo
) {
2220 config_set_int ("d3d_driver_index", m3dDriver
= LGadRadioButtonSelection (&mListButtons
));
2221 // Go back to basic video instead of advanced
2222 mSwap
= kSubBasicVideo
;
2226 else if (mListSub
== kSubBasicVideo
) {
2234 //////////////////////////////////////////////////////
2236 static bool OnScrollButton (ushort action
, int button
, void *data
, LGadBox
*)
2238 cOptions
*panel
= (cOptions
*)data
;
2240 panel
->OnScrollList (action
, button
);
2244 //////////////////////////////////////////////////////
2246 void OnScrollList (ushort action
, int button
)
2248 if (!(action
& BUTTONGADG_LCLICK
))
2267 //scrolling through resolutions
2284 if (mTopBind
<= mNumBindable
- NUM_BIND_SLOTS
) {
2288 if (mTopBind
== mNumBindable
- (NUM_BIND_SLOTS
- 1) && LGadRadioButtonSelection (&mBindButtons
) == (NUM_BIND_SLOTS
- 1))
2289 LGadRadioButtonSelect (&mBindButtons
, 8);
2297 if (mNumListTotal
>= NUM_LIST
- 1) {
2310 FillBlack (FILL_SUBPANEL
);
2316 //////////////////////////////////////////////////////
2318 static bool OnBindButton (ushort action
, int button
, void *data
, LGadBox
*)
2320 cOptions
*panel
= (cOptions
*)data
;
2322 panel
->OnBind (action
, button
);
2326 //////////////////////////////////////////////////////
2328 void OnBind (ushort action
, int button
)
2330 if (!(action
& BUTTONGADG_LCLICK
))
2333 static int prev_pick
;
2334 if (!strcmp ((const char *)mBindButtonElems
[button
].draw_data
, "")) {
2335 LGadRadioButtonSelect (&mBindButtons
, prev_pick
);
2341 //////////////////////////////////////////////////////
2343 static bool OnListButton (ushort action
, int button
, void *data
, LGadBox
*)
2345 cOptions
*panel
= (cOptions
*)data
;
2347 panel
->OnList (action
, button
);
2351 //////////////////////////////////////////////////////
2353 void OnList (ushort action
, int button
)
2355 if (!(action
& BUTTONGADG_LCLICK
))
2358 BOOL valid_butt
= TRUE
;
2360 //display device choice
2361 if (mListSub
== kSubAdvancedVideo
) {
2362 //the button clicked was not filled
2363 if (button
>= mNumVidDevices
) {
2364 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
);
2368 //there was something there
2370 config_set_int ("d3d_driver_index", button
);
2376 else if (mListSub
== kSubBasicVideo
) {
2377 //the button clicked was not filled
2378 if (button
>= mNumListTotal
) {
2379 LGadRadioButtonSelect (&mListButtons
, mListPrevPick
);
2383 mSelectedRes
= mTopList
+ button
;
2389 mListPrevPick
= button
;
2392 //////////////////////////////////////////////////////
2394 void OnButtonList(ushort action
, int button
)
2396 if (!(action
& BUTTONGADG_LCLICK
))
2403 if (mCurSub
== kSubList
)
2404 OnSubPanelButtonList (action
, 0);
2406 cAutoIPtr
<IPanelMode
> mode
= GetPanelMode();
2416 int cShockOptions::gFirstSubRect
[] =
2418 cShockOptions::kFirstControlButt
,
2419 cShockOptions::kFirstBasicVideoButt
,
2420 cShockOptions::kFirstAdvancedVideoButt
,
2421 cShockOptions::kFirstAudioButt
,
2422 cShockOptions::kFirstGameButt
,
2423 cShockOptions::kFirstBindButt
,
2424 cShockOptions::kFirstListButt
,
2427 int cShockOptions::gVolSliderRects
[] =
2429 cShockOptions::kVolumeSliderRect
,
2430 cShockOptions::k3dVolumeSliderRect
,
2431 cShockOptions::kMusicSliderRect
,
2436 // Options Menu descriptor
2439 static const char* options_button_names
[] =
2444 sDarkPanelDesc
cOptions::gDesc
=
2447 cOptions::kNumButts
,
2448 cOptions::kNumRects
,
2449 cOptions::kNumButts
,
2450 options_button_names
,
2453 kMetaSndPanelOptions
2458 EXTERN
void SwitchToShockOptionsMode(BOOL push
)
2462 cAutoIPtr
<IPanelMode
> panel
= gpOptions
->GetPanelMode();
2463 panel
->Switch((push
) ? kLoopModePush
: kLoopModeSwitch
);
2468 const sLoopInstantiator
* DescribeShockOptionsMode(void)
2472 cAutoIPtr
<IPanelMode
> panel
= gpOptions
->GetPanelMode();
2473 return panel
->Instantiator();
2479 //Wrapper so that others can use this easier..
2480 //Will stuff retrieve_num many controls bound to cmd into the dest
2481 //string array, and will return how many actually got stuff
2483 int GetCmdBinds (const char *cmd
, cStr
*dest
, int retrieve_num
)
2485 return gpOptions
->GetCmdBinds (cmd
, dest
, retrieve_num
);
2492 // Init and term stuff
2495 void ShockOptionsMenuInit ()
2497 gpOptions
= new cOptions
;
2498 gpOptions
->SetInitialSub ();
2499 ShockInitBindSaveLoad();
2502 void ShockOptionsMenuTerm ()
2505 ShockTermBindSaveLoad();