1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010-2020 EDuke32 developers and contributors
4 Copyright (C) 2020 sirlemonhead, Nuke.YKT
5 This file is part of EWitchaven.
6 EWitchaven is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License version 2
8 as published by the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 See the GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
16 */
17 //-------------------------------------------------------------------------
18 
19 #include "compat.h"
20 #include "renderlayer.h"
21 #include "_control.h"
22 #include "build.h"
23 #include "cache1d.h"
24 #include "keyboard.h"
25 #include "control.h"
26 #include "witchaven.h"
27 #include "scriplib.h"
28 
29 #include "config.h"
30 
31 #include <string>
32 //#include <io.h>
33 #include <stdio.h>
34 #include <time.h>
35 
36 const char gamefunctions[kMaxGameFunctions][kMaxGameFuncLen] =
37 {
38   "Move_Forward",
39   "Move_Backward",
40   "Turn_Left",
41   "Turn_Right",
42   "Strafe",
43   "Strafe_Left",
44   "Strafe_Right",
45   "Run",
46   "Jump",
47   "Crouch",
48   "Fire",
49   "Open",
50   "Fly_Up",
51   "Fly_Down",
52   "Look_Up",
53   "Look_Down",
54   "Look_Straight",
55   "Aim_Up",
56   "Aim_Down",
57   "SendMessage",
58   "Weapon_0",
59   "Weapon_1",
60   "Weapon_2",
61   "Weapon_3",
62   "Weapon_4",
63   "Weapon_5",
64   "Weapon_6",
65   "Weapon_7",
66   "Weapon_8",
67   "Weapon_9",
68   "Spell_Left",
69   "Spell_Right",
70   "Cast_Spell",
71   "Potion_Left",
72   "Potion_Right",
73   "Use_Potion",
74   "Pause",
75   "Map",
76   "Zoom_In",
77   "Zoom_Out",
78   "Gamma_Correction",
79   "Escape",
80   "Shrink_Screen",
81   "Enlarge_Screen",
82   "Mouse_Sensitivity_Up",
83   "Mouse_Sensitivity_Down",
84   "Show_Console",
85   "Mouse_Aiming",
86   "Toggle_Crosshair"
87 };
88 
89 const char keydefaults[kMaxGameFunctions * 2][kMaxGameFuncLen] =
90 {
91    "W", "Kpad8",
92    "S", "Kpad2",
93    "Left", "Kpad4",
94    "Right", "KPad6",
95    "LAlt", "RAlt",
96    "A", "",
97    "D", "",
98    "LShift", "RShift",
99    "Space", "",
100    "LCtrl", "",
101    "RCtrl", "",
102    "E", "",
103    "Insert", "",
104    "Delete", "",
105    "PgUp", "",
106    "PgDn", "",
107    "Home", "",
108    "", "", // aim up
109    "", "", // aim down
110    "T", "",
111    "0", "",
112    "1", "",
113    "2", "",
114    "3", "",
115    "4", "",
116    "5", "",
117    "6", "",
118    "7", "",
119    "8", "",
120    "9", "",
121    "", "", // spell left
122    "", "", // spell right
123    "'", "", // cast spell
124    "[", "", // potion left
125    "]", "", // potion right
126    "Enter", "",  // use potion
127    "Pause", "",
128    "Tab", "",
129    "=", "",
130    "-", "",
131    "F11", "",
132    "Escape", "",
133    "Kpad-", "",
134    "Kpad+", "",
135    "", "", // sensitivity up
136    "", "", // sensitivity down
137    "`", "",
138    "U", "",
139    "I", "",
140 };
141 
142 const char oldkeydefaults[kMaxGameFunctions * 2][kMaxGameFuncLen] =
143 {
144    "Up", "Kpad8",
145    "Down", "Kpad2",
146    "Left", "Kpad4",
147    "Right", "KPad6",
148    "LAlt", "RAlt",
149    ",", "",
150    ".", "",
151    "LShift", "RShift",
152    "A", "",
153    "Z", "",
154    "LCtrl", "RCtrl",
155    "Space", "",
156    "PgUp", "",
157    "PgDn", "",
158    "Home", "",
159    "Insert", "",
160    "Delete", "",
161    "T", "",
162    "1", "",
163    "2", "",
164    "3", "",
165    "4", "",
166    "5", "",
167    "6", "",
168    "7", "",
169    "Pause", "",
170    "Tab", "",
171    "=", "",
172    "-", "",
173    "F11", "",
174    "Escape", "",
175    "Kpad-", "",
176    "Kpad+", "",
177    "Enter", "",
178    "[", "",
179    "]", "",
180    "F7", "",
181    "F8", "",
182    "`", "",
183    "U", "",
184    "I", "",
185 };
186 
187 static const char *mousedefaults[MAXMOUSEBUTTONS] =
188 {
189    "Fire",
190    "Strafe",
191    "Move_Forward"
192    "",
193    "",
194    "",
195 };
196 
197 static const char *mouseclickeddefaults[MAXMOUSEBUTTONS] =
198 {
199 };
200 
201 static const char* mouseanalogdefaults[MAXMOUSEAXES] =
202 {
203 "analog_strafing",
204 "analog_moving",
205 };
206 
207 
208 static const char* mousedigitaldefaults[MAXMOUSEDIGITAL] =
209 {
210 };
211 
212 ud_setup_t gSetup;
213 
214 char setupfilename[BMAX_PATH] = {kSetupFilename};
215 
216 int lMouseSens = 32;
217 
218 int32_t FXVolume;
219 int32_t MusicVolume;
220 int32_t MixRate;
221 int32_t MidiPort;
222 int32_t NumVoices;
223 int32_t NumChannels;
224 int32_t NumBits;
225 int32_t ReverseStereo;
226 int32_t MusicDevice;
227 int32_t FXDevice;
228 int32_t ControllerType;
229 
230 int32_t scripthandle;
231 int32_t setupread;
232 // TODO: implement precaching toggle
233 int32_t useprecache;
234 int32_t MouseDeadZone, MouseBias;
235 
236 // JBF 20031211: Store the input settings because
237 // (currently) mact can't regurgitate them
238 int32_t MouseFunctions[MAXMOUSEBUTTONS][2];
239 int32_t MouseDigitalFunctions[MAXMOUSEAXES][2];
240 int32_t MouseAnalogueAxes[MAXMOUSEAXES];
241 int32_t MouseAnalogueScale[MAXMOUSEAXES];
242 int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2];
243 int32_t JoystickDigitalFunctions[MAXJOYAXES][2];
244 int32_t JoystickAnalogueAxes[MAXJOYAXES];
245 int32_t JoystickAnalogueScale[MAXJOYAXES];
246 int32_t JoystickAnalogueInvert[MAXJOYAXES];
247 int32_t JoystickAnalogueDead[MAXJOYAXES];
248 int32_t JoystickAnalogueSaturate[MAXJOYAXES];
249 uint8_t KeyboardKeys[kMaxGameFunctions][2];
250 
251 int32_t MAXCACHE1DSIZE = (96*1024*1024);
252 
253 
SetupGameButtons()254 void SetupGameButtons()
255 {
256     CONTROL_DefineFlag(gamefunc_Move_Forward,           FALSE);
257     CONTROL_DefineFlag(gamefunc_Move_Backward,          FALSE);
258     CONTROL_DefineFlag(gamefunc_Turn_Left,              FALSE);
259     CONTROL_DefineFlag(gamefunc_Turn_Right,             FALSE);
260     CONTROL_DefineFlag(gamefunc_Strafe,                 FALSE);
261     CONTROL_DefineFlag(gamefunc_Strafe_Left,            FALSE);
262     CONTROL_DefineFlag(gamefunc_Strafe_Right,           FALSE);
263     CONTROL_DefineFlag(gamefunc_Run,                    FALSE);
264     CONTROL_DefineFlag(gamefunc_Jump,                   FALSE);
265     CONTROL_DefineFlag(gamefunc_Crouch,                 FALSE);
266     CONTROL_DefineFlag(gamefunc_Fire,                   FALSE);
267     CONTROL_DefineFlag(gamefunc_Open,                   FALSE);
268     CONTROL_DefineFlag(gamefunc_Fly_Up,                 FALSE);
269     CONTROL_DefineFlag(gamefunc_Fly_Down,               FALSE);
270     CONTROL_DefineFlag(gamefunc_Look_Up,                FALSE);
271     CONTROL_DefineFlag(gamefunc_Look_Down,              FALSE);
272     CONTROL_DefineFlag(gamefunc_Look_Straight,          FALSE);
273     CONTROL_DefineFlag(gamefunc_Aim_Up,                 FALSE);
274     CONTROL_DefineFlag(gamefunc_Aim_Down,               FALSE);
275     CONTROL_DefineFlag(gamefunc_SendMessage,            FALSE);
276     CONTROL_DefineFlag(gamefunc_Weapon_1,               FALSE);
277     CONTROL_DefineFlag(gamefunc_Weapon_2,               FALSE);
278     CONTROL_DefineFlag(gamefunc_Weapon_3,               FALSE);
279     CONTROL_DefineFlag(gamefunc_Weapon_4,               FALSE);
280     CONTROL_DefineFlag(gamefunc_Weapon_5,               FALSE);
281     CONTROL_DefineFlag(gamefunc_Weapon_6,               FALSE);
282     CONTROL_DefineFlag(gamefunc_Weapon_7,               FALSE);
283     CONTROL_DefineFlag(gamefunc_Weapon_8,               FALSE);
284     CONTROL_DefineFlag(gamefunc_Weapon_9,               FALSE);
285     CONTROL_DefineFlag(gamefunc_Spell_Left,             FALSE);
286     CONTROL_DefineFlag(gamefunc_Spell_Right,            FALSE);
287     CONTROL_DefineFlag(gamefunc_Cast_Spell,             FALSE);
288     CONTROL_DefineFlag(gamefunc_Potion_Left,            FALSE);
289     CONTROL_DefineFlag(gamefunc_Potion_Right,           FALSE);
290     CONTROL_DefineFlag(gamefunc_Use_Potion,             FALSE);
291     CONTROL_DefineFlag(gamefunc_Pause,                  FALSE);
292     CONTROL_DefineFlag(gamefunc_Map,                    FALSE);
293     CONTROL_DefineFlag(gamefunc_Zoom_In,                FALSE);
294     CONTROL_DefineFlag(gamefunc_Zoom_Out,               FALSE);
295     CONTROL_DefineFlag(gamefunc_Gamma_Correction,       FALSE);
296     CONTROL_DefineFlag(gamefunc_Escape,                 FALSE);
297     CONTROL_DefineFlag(gamefunc_Shrink_Screen,          FALSE);
298     CONTROL_DefineFlag(gamefunc_Enlarge_Screen,         FALSE);
299     CONTROL_DefineFlag(gamefunc_Mouse_Sensitivity_Up,   FALSE);
300     CONTROL_DefineFlag(gamefunc_Mouse_Sensitivity_Down, FALSE);
301     CONTROL_DefineFlag(gamefunc_Mouse_Aiming,           FALSE);
302     CONTROL_DefineFlag(gamefunc_Toggle_Crosshair,       FALSE);
303 }
304 
305 hashtable_t h_gamefuncs    = { kMaxGameFunctions<<1, NULL };
306 
CONFIG_FunctionNameToNum(const char * func)307 int32_t CONFIG_FunctionNameToNum(const char *func)
308 {
309     if (!func)
310         return -1;
311 
312     return hash_findcase(&h_gamefuncs, func);
313 }
314 
315 
CONFIG_FunctionNumToName(int32_t func)316 static char const * CONFIG_FunctionNumToName(int32_t func)
317 {
318     if ((unsigned)func >= (unsigned)kMaxGameFunctions)
319         return "";
320     return gamefunctions[func];
321 }
322 
323 
CONFIG_AnalogNameToNum(const char * func)324 int32_t CONFIG_AnalogNameToNum(const char *func)
325 {
326     if (!func)
327         return -1;
328     else if (!Bstrcasecmp(func, "analog_turning"))
329         return analog_turning;
330     else if (!Bstrcasecmp(func, "analog_strafing"))
331         return analog_strafing;
332     else if (!Bstrcasecmp(func, "analog_moving"))
333         return analog_moving;
334     else if (!Bstrcasecmp(func, "analog_lookingupanddown"))
335         return analog_lookingupanddown;
336     else
337         return -1;
338 }
339 
340 
CONFIG_AnalogNumToName(int32_t func)341 static char const * CONFIG_AnalogNumToName(int32_t func)
342 {
343     switch (func)
344     {
345     case analog_turning:
346         return "analog_turning";
347     case analog_strafing:
348         return "analog_strafing";
349     case analog_moving:
350         return "analog_moving";
351     case analog_lookingupanddown:
352         return "analog_lookingupanddown";
353     }
354 
355     return "";
356 }
357 
358 
CONFIG_SetJoystickButtonFunction(int i,int j,int function)359 static void CONFIG_SetJoystickButtonFunction(int i, int j, int function)
360 {
361     JoystickFunctions[i][j] = function;
362     CONTROL_MapButton(function, i, j, controldevice_joystick);
363 }
CONFIG_SetJoystickAnalogAxisScale(int i,int scale)364 static void CONFIG_SetJoystickAnalogAxisScale(int i, int scale)
365 {
366     JoystickAnalogueScale[i] = scale;
367     CONTROL_SetAnalogAxisScale(i, scale, controldevice_joystick);
368 }
CONFIG_SetJoystickAnalogAxisInvert(int i,int invert)369 static void CONFIG_SetJoystickAnalogAxisInvert(int i, int invert)
370 {
371     JoystickAnalogueInvert[i] = invert;
372     CONTROL_SetAnalogAxisInvert(i, invert, controldevice_joystick);
373 }
CONFIG_SetJoystickAnalogAxisDeadSaturate(int i,int dead,int saturate)374 static void CONFIG_SetJoystickAnalogAxisDeadSaturate(int i, int dead, int saturate)
375 {
376     JoystickAnalogueDead[i] = dead;
377     JoystickAnalogueSaturate[i] = saturate;
378     joySetDeadZone(i, dead, saturate);
379 }
CONFIG_SetJoystickDigitalAxisFunction(int i,int j,int function)380 static void CONFIG_SetJoystickDigitalAxisFunction(int i, int j, int function)
381 {
382     JoystickDigitalFunctions[i][j] = function;
383     CONTROL_MapDigitalAxis(i, function, j, controldevice_joystick);
384 }
CONFIG_SetJoystickAnalogAxisFunction(int i,int function)385 static void CONFIG_SetJoystickAnalogAxisFunction(int i, int function)
386 {
387     JoystickAnalogueAxes[i] = function;
388     CONTROL_MapAnalogAxis(i, function, controldevice_joystick);
389 }
390 
391 
CONFIG_SetDefaultKeys(const char (* keyptr)[kMaxGameFuncLen],bool lazy)392 void CONFIG_SetDefaultKeys(const char (*keyptr)[kMaxGameFuncLen], bool lazy/*=false*/)
393 {
394     static char const s_gamefunc_[] = "gamefunc_";
395     int constexpr strlen_gamefunc_  = ARRAY_SIZE(s_gamefunc_) - 1;
396 
397     if (!lazy)
398     {
399         Bmemset(KeyboardKeys, 0xff, sizeof(KeyboardKeys));
400         CONTROL_ClearAllBinds();
401     }
402 
403     for (int i=0; i < ARRAY_SSIZE(gamefunctions); ++i)
404     {
405         if (gamefunctions[i][0] == '\0')
406             continue;
407 
408         auto &key = KeyboardKeys[i];
409 
410         int const default0 = KB_StringToScanCode(keyptr[i<<1]);
411         int const default1 = KB_StringToScanCode(keyptr[(i<<1)+1]);
412 
413         // skip the function if the default key is already used
414         // or the function is assigned to another key
415         if (lazy && (key[0] != 0xff || (CONTROL_KeyIsBound(default0) && Bstrlen(CONTROL_KeyBinds[default0].cmdstr) > strlen_gamefunc_
416                         && CONFIG_FunctionNameToNum(CONTROL_KeyBinds[default0].cmdstr + strlen_gamefunc_) >= 0)))
417         {
418 #if 0 // defined(DEBUGGINGAIDS)
419             if (key[0] != 0xff)
420                 initprintf("Skipping %s bound to %s\n", keyptr[i<<1], CONTROL_KeyBinds[default0].cmdstr);
421 #endif
422             continue;
423         }
424 
425         key[0] = default0;
426         key[1] = default1;
427 
428         if (key[0])
429             CONTROL_FreeKeyBind(key[0]);
430 
431         if (key[1])
432             CONTROL_FreeKeyBind(key[1]);
433 
434         if (i == gamefunc_Show_Console)
435             OSD_CaptureKey(key[0]);
436         else
437             CONFIG_MapKey(i, key[0], 0, key[1], 0);
438     }
439 }
440 
CONFIG_SetDefaults()441 void CONFIG_SetDefaults()
442 {
443     scripthandle = -1;
444 # if defined RENDERTYPESDL && SDL_MAJOR_VERSION > 1
445     uint32_t inited = SDL_WasInit(SDL_INIT_VIDEO);
446     if (inited == 0)
447         SDL_Init(SDL_INIT_VIDEO);
448     else if (!(inited & SDL_INIT_VIDEO))
449         SDL_InitSubSystem(SDL_INIT_VIDEO);
450 
451     SDL_DisplayMode dm;
452     if (SDL_GetDesktopDisplayMode(0, &dm) == 0)
453     {
454         gSetup.xdim = dm.w;
455         gSetup.ydim = dm.h;
456     }
457     else
458 # endif
459     {
460         gSetup.xdim = 1024;
461         gSetup.ydim = 768;
462     }
463 
464 #ifdef USE_OPENGL
465     gSetup.bpp = 32;
466 #else
467     gSetup.bpp = 8;
468 #endif
469 
470     // currently settings.cfg is only read after the startup window launches the game,
471     // and rereading binds might be fickle so just enable this
472     gSetup.usejoystick = 1;
473 
474     gSetup.forcesetup = 1;
475     gSetup.noautoload = 1;
476     gSetup.fullscreen = 1;
477     gSetup.usemouse = 1;
478 
479     MixRate = 44100;
480     FXVolume = 255;
481     MusicVolume = 255;
482     NumChannels = 2;
483     NumBits = 16;
484     NumVoices = 32;
485 /* // TODO
486     mouseaiming = 0;
487     aimmode = 1;
488     mouseflip = 1;
489     runkey_mode = 0;
490     auto_run = 1;
491 
492     gFov = 90;
493 */
494     CONFIG_SetDefaultKeys(keydefaults);
495 
496     memset(MouseFunctions, -1, sizeof(MouseFunctions));
497     memset(MouseDigitalFunctions, -1, sizeof(MouseDigitalFunctions));
498     memset(JoystickFunctions, -1, sizeof(JoystickFunctions));
499     memset(JoystickDigitalFunctions, -1, sizeof(JoystickDigitalFunctions));
500 
501     CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY;
502 
503     for (int i=0; i<MAXMOUSEBUTTONS; i++)
504     {
505         MouseFunctions[i][0] = CONFIG_FunctionNameToNum(mousedefaults[i]);
506         CONTROL_MapButton(MouseFunctions[i][0], i, 0, controldevice_mouse);
507         if (i>=4) continue;
508         MouseFunctions[i][1] = CONFIG_FunctionNameToNum(mouseclickeddefaults[i]);
509         CONTROL_MapButton(MouseFunctions[i][1], i, 1, controldevice_mouse);
510     }
511 
512     for (int i=0; i<MAXMOUSEAXES; i++)
513     {
514         MouseAnalogueScale[i] = DEFAULTMOUSEANALOGUESCALE;
515         CONTROL_SetAnalogAxisScale(i, MouseAnalogueScale[i], controldevice_mouse);
516 
517         MouseDigitalFunctions[i][0] = CONFIG_FunctionNameToNum(mousedigitaldefaults[i*2]);
518         MouseDigitalFunctions[i][1] = CONFIG_FunctionNameToNum(mousedigitaldefaults[i*2+1]);
519         CONTROL_MapDigitalAxis(i, MouseDigitalFunctions[i][0], 0, controldevice_mouse);
520         CONTROL_MapDigitalAxis(i, MouseDigitalFunctions[i][1], 1, controldevice_mouse);
521 
522         MouseAnalogueAxes[i] = CONFIG_AnalogNameToNum(mouseanalogdefaults[i]);
523         CONTROL_MapAnalogAxis(i, MouseAnalogueAxes[i], controldevice_mouse);
524     }
525 
526     // TODO:
527     //CONFIG_SetGameControllerDefaultsStandard();
528 
529 #if 0
530     FXVolume       = 128;
531     MusicVolume    = 128;
532     ReverseStereo  = 0;
533     ControllerType = controltype_keyboardandmouse;
534     lMouseSens     = 8;
535 #endif
536 }
537 
CONFIG_ReadSetup()538 int CONFIG_ReadSetup()
539 {
540     //char tempbuf[1024];
541 
542     CONTROL_ClearAssignments();
543     CONFIG_SetDefaults();
544 
545     setupread = 1;
546     pathsearchmode = 1;
547 
548     if (scripthandle < 0)
549     {
550         if (buildvfs_exists(setupfilename))  // JBF 20031211
551             scripthandle = SCRIPT_Load(setupfilename);
552         else if (buildvfs_exists(kSetupFilename))
553         {
554             int const i = wm_ynbox("Import Configuration Settings",
555                 "The configuration file \"%s\" was not found. "
556                 "Import configuration data from \"%s\"?",
557                 setupfilename, kSetupFilename);
558             if (i)
559                 scripthandle = SCRIPT_Load(kSetupFilename);
560         }
561     }
562 
563     pathsearchmode = 0;
564 
565     if (scripthandle < 0)
566         return -1;
567 
568     SCRIPT_GetNumber(scripthandle, "Options", "GoreOn", &goreon);
569     SCRIPT_GetNumber(scripthandle, "Options", "Difficulty", &difficulty);
570     SCRIPT_GetNumber(scripthandle, "Options", "Brightness", &gbrightness);
571 
572     SCRIPT_GetNumber(scripthandle, "Setup", "ForceSetup", &gSetup.forcesetup);
573     SCRIPT_GetNumber(scripthandle, "Setup", "NoAutoLoad", &gSetup.noautoload);
574 
575     int32_t cachesize;
576     SCRIPT_GetNumber(scripthandle, "Setup", "CacheSize", &cachesize);
577 
578     if (cachesize > MAXCACHE1DSIZE)
579         MAXCACHE1DSIZE = cachesize;
580 
581 
582     if (g_noSetup == 0 && g_modDir[0] == '/')
583     {
584         SCRIPT_GetString(scripthandle, "Setup","ModDir",&g_modDir[0]);
585 
586         if (!buildvfs_isdir(g_modDir))
587         {
588             initprintf("Invalid mod dir in cfg!\n");
589             Bsprintf(g_modDir,"/");
590         }
591     }
592 
593     windowx = -1;
594     windowy = -1;
595 
596     SCRIPT_GetNumber(scripthandle, "Screen Setup", "MaxRefreshFreq", (int32_t *)&maxrefreshfreq);
597     SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenBPP", &gSetup.bpp);
598     SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenHeight", &gSetup.ydim);
599     SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenMode", &gSetup.fullscreen);
600     SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenWidth", &gSetup.xdim);
601     SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosX", (int32_t *)&windowx);
602     SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosY", (int32_t *)&windowy);
603     SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPositioning", (int32_t *)&windowpos);
604 
605     if (gSetup.bpp < 8) gSetup.bpp = 32;
606 
607     setupread = 1;
608     return 0;
609 }
610 
611 // wrapper for CONTROL_MapKey(), generates key bindings to reflect changes to keyboard setup
CONFIG_MapKey(int which,kb_scancode key1,kb_scancode oldkey1,kb_scancode key2,kb_scancode oldkey2)612 void CONFIG_MapKey(int which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2)
613 {
614     char tempbuf[256];
615     int const keys[] = { key1, key2, oldkey1, oldkey2 };
616     char buf[2*kMaxGameFuncLen];
617 
618     if (which == gamefunc_Show_Console)
619         OSD_CaptureKey(key1);
620 
621     for (int k = 0; (unsigned)k < ARRAY_SIZE(keys); k++)
622     {
623         if (keys[k] == 0xff || !keys[k])
624             continue;
625 
626         int match = 0;
627 
628         for (; match < ARRAY_SSIZE(sctokeylut); ++match)
629         {
630             if (keys[k] == sctokeylut[match].sc)
631                 break;
632         }
633 
634         tempbuf[0] = 0;
635 
636         for (int i=kMaxGameFunctions-1; i>=0; i--)
637         {
638             if (KeyboardKeys[i][0] == keys[k] || KeyboardKeys[i][1] == keys[k])
639             {
640                 Bsprintf(buf, "gamefunc_%s; ", CONFIG_FunctionNumToName(i));
641                 Bstrcat(tempbuf,buf);
642             }
643         }
644 
645         int const len = Bstrlen(tempbuf);
646 
647         if (len >= 2)
648         {
649             tempbuf[len-2] = 0;  // cut off the trailing "; "
650             CONTROL_BindKey(keys[k], tempbuf, 1, sctokeylut[match].key ? sctokeylut[match].key : "<?>");
651         }
652         else
653         {
654             CONTROL_FreeKeyBind(keys[k]);
655         }
656     }
657 }
658 
659 
CONFIG_SetupMouse(void)660 void CONFIG_SetupMouse(void)
661 {
662     if (scripthandle < 0)
663         return;
664 
665     char str[80];
666     char temp[80];
667 
668     for (int i=0; i<MAXMOUSEBUTTONS; i++)
669     {
670         Bsprintf(str,"MouseButton%d",i);
671         temp[0] = 0;
672         if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
673             MouseFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
674 
675         Bsprintf(str,"MouseButtonClicked%d",i);
676         temp[0] = 0;
677         if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
678             MouseFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
679     }
680 
681     // map over the axes
682     for (int i=0; i<MAXMOUSEAXES; i++)
683     {
684         Bsprintf(str,"MouseAnalogAxes%d",i);
685         temp[0] = 0;
686         if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
687             MouseAnalogueAxes[i] = CONFIG_AnalogNameToNum(temp);
688 
689         Bsprintf(str,"MouseDigitalAxes%d_0",i);
690         temp[0] = 0;
691         if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
692             MouseDigitalFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
693 
694         Bsprintf(str,"MouseDigitalAxes%d_1",i);
695         temp[0] = 0;
696         if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
697             MouseDigitalFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
698 
699         Bsprintf(str,"MouseAnalogScale%d",i);
700         int32_t scale = MouseAnalogueScale[i];
701         SCRIPT_GetNumber(scripthandle, "Controls", str, &scale);
702         MouseAnalogueScale[i] = scale;
703     }
704 
705     for (int i=0; i<MAXMOUSEBUTTONS; i++)
706     {
707         CONTROL_MapButton(MouseFunctions[i][0], i, 0, controldevice_mouse);
708         CONTROL_MapButton(MouseFunctions[i][1], i, 1,  controldevice_mouse);
709     }
710     for (int i=0; i<MAXMOUSEAXES; i++)
711     {
712         CONTROL_MapAnalogAxis(i, MouseAnalogueAxes[i], controldevice_mouse);
713         CONTROL_MapDigitalAxis(i, MouseDigitalFunctions[i][0], 0,controldevice_mouse);
714         CONTROL_MapDigitalAxis(i, MouseDigitalFunctions[i][1], 1,controldevice_mouse);
715         CONTROL_SetAnalogAxisScale(i, MouseAnalogueScale[i], controldevice_mouse);
716     }
717 }
718 
719 
CONFIG_SetupJoystick(void)720 void CONFIG_SetupJoystick(void)
721 {
722     int32_t i;
723     char str[80];
724     char temp[80];
725     int32_t scale;
726 
727     if (scripthandle < 0) return;
728 
729     for (i=0; i<MAXJOYBUTTONSANDHATS; i++)
730     {
731         Bsprintf(str,"ControllerButton%d",i);
732         temp[0] = 0;
733         if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
734             JoystickFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
735 
736         Bsprintf(str,"ControllerButtonClicked%d",i);
737         temp[0] = 0;
738         if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
739             JoystickFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
740     }
741 
742     // map over the axes
743     for (i=0; i<MAXJOYAXES; i++)
744     {
745         Bsprintf(str,"ControllerAnalogAxes%d",i);
746         temp[0] = 0;
747         if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
748             JoystickAnalogueAxes[i] = CONFIG_AnalogNameToNum(temp);
749 
750         Bsprintf(str,"ControllerDigitalAxes%d_0",i);
751         temp[0] = 0;
752         if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
753             JoystickDigitalFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
754 
755         Bsprintf(str,"ControllerDigitalAxes%d_1",i);
756         temp[0] = 0;
757         if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
758             JoystickDigitalFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
759 
760         Bsprintf(str,"ControllerAnalogScale%d",i);
761         scale = JoystickAnalogueScale[i];
762         SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
763         JoystickAnalogueScale[i] = scale;
764 
765         Bsprintf(str,"ControllerAnalogInvert%d",i);
766         scale = JoystickAnalogueInvert[i];
767         SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
768         JoystickAnalogueInvert[i] = scale;
769 
770         Bsprintf(str,"ControllerAnalogDead%d",i);
771         scale = JoystickAnalogueDead[i];
772         SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
773         JoystickAnalogueDead[i] = scale;
774 
775         Bsprintf(str,"ControllerAnalogSaturate%d",i);
776         scale = JoystickAnalogueSaturate[i];
777         SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
778         JoystickAnalogueSaturate[i] = scale;
779     }
780 
781     for (i=0; i<MAXJOYBUTTONSANDHATS; i++)
782     {
783         CONTROL_MapButton(JoystickFunctions[i][0], i, 0, controldevice_joystick);
784         CONTROL_MapButton(JoystickFunctions[i][1], i, 1,  controldevice_joystick);
785     }
786     for (i=0; i<MAXJOYAXES; i++)
787     {
788         CONTROL_MapAnalogAxis(i, JoystickAnalogueAxes[i], controldevice_joystick);
789         CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][0], 0, controldevice_joystick);
790         CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][1], 1, controldevice_joystick);
791         CONTROL_SetAnalogAxisScale(i, JoystickAnalogueScale[i], controldevice_joystick);
792         CONTROL_SetAnalogAxisInvert(i, JoystickAnalogueInvert[i], controldevice_joystick);
793     }
794 }
795 
SetupInput()796 void SetupInput()
797 {
798     if (CONTROL_Startup(controltype_keyboardandmouse, &BGetTime, kTimerTicks))
799     {
800         ERRprintf("There was an error initializing the CONTROL system.\n");
801         engineUnInit();
802         Bexit(5);
803     }
804     SetupGameButtons();
805     CONFIG_SetupMouse();
806     CONFIG_SetupJoystick();
807 
808     CONTROL_JoystickEnabled = (gSetup.usejoystick && CONTROL_JoyPresent);
809     CONTROL_MouseEnabled    = (gSetup.usemouse && CONTROL_MousePresent);
810 
811     // JBF 20040215: evil and nasty place to do this, but joysticks are evil and nasty too
812     for (int i=0; i<joystick.numAxes; i++)
813         joySetDeadZone(i,JoystickAnalogueDead[i],JoystickAnalogueSaturate[i]);
814 }
815 
CONFIG_WriteSettings(void)816 void CONFIG_WriteSettings(void) // save binds and aliases to <cfgname>_settings.cfg
817 {
818     char filename[BMAX_PATH];
819 /*
820     if (!Bstrcmp(setupfilename, kSetupFilename))
821         Bsprintf(filename, "settings.cfg");
822     else
823         Bsprintf(filename, "%s_settings.cfg", strtok(setupfilename, "."));
824 */
825     Bsprintf(filename, "ewitchaven_cvars.cfg");
826 
827     buildvfs_FILE fp = buildvfs_fopen_write(filename);
828 
829     if (fp)
830     {
831         buildvfs_fputstr(fp, "// this file is automatically generated by ");
832         buildvfs_fputstrptr(fp, AppProperName);
833         buildvfs_fputstr(fp,"\nunbindall\n");
834 
835         for (int i=0; i<MAXBOUNDKEYS+MAXMOUSEBUTTONS; i++)
836         {
837             if (CONTROL_KeyIsBound(i))
838             {
839                 buildvfs_fputstr(fp, "bind \"");
840                 buildvfs_fputstrptr(fp, CONTROL_KeyBinds[i].key);
841                 if (CONTROL_KeyBinds[i].repeat)
842                     buildvfs_fputstr(fp, "\" \"");
843                 else
844                     buildvfs_fputstr(fp, "\" norepeat \"");
845                 buildvfs_fputstrptr(fp, CONTROL_KeyBinds[i].cmdstr);
846                 buildvfs_fputstr(fp, "\"\n");
847             }
848         }
849 
850         for (int i=0; i<kMaxGameFunctions; ++i)
851         {
852             char const * name = CONFIG_FunctionNumToName(i);
853             if (name && name[0] != '\0' && (KeyboardKeys[i][0] == 0xff || !KeyboardKeys[i][0]))
854             {
855                 buildvfs_fputstr(fp, "unbound ");
856                 buildvfs_fputstrptr(fp, name);
857                 buildvfs_fputstr(fp, "\n");
858             }
859         }
860 
861         OSD_WriteAliases(fp);
862 
863         //if (g_crosshairSum != -1 && g_crosshairSum != DefaultCrosshairColors.r+(DefaultCrosshairColors.g<<8)+(DefaultCrosshairColors.b<<16))
864         //{
865         //    buildvfs_fputstr(fp, "crosshaircolor ");
866         //    char buf[64];
867         //    snprintf(buf, sizeof(buf), "%d %d %d\n", CrosshairColors.r, CrosshairColors.g, CrosshairColors.b);
868         //    buildvfs_fputstrptr(fp, buf);
869         //}
870 
871         OSD_WriteCvars(fp);
872 
873         buildvfs_fclose(fp);
874 
875         OSD_Printf("Wrote %s\n", filename);
876 
877         return;
878     }
879 
880     OSD_Printf("Error writing %s: %s\n", filename, strerror(errno));
881 }
882 
CONFIG_WriteSetup(uint32_t flags)883 void CONFIG_WriteSetup(uint32_t flags)
884 {
885     char buf[256];
886     if (!setupread) return;
887 
888     if (scripthandle < 0)
889         scripthandle = SCRIPT_Init(setupfilename);
890 
891     SCRIPT_PutNumber(scripthandle, "Options", "GoreOn", goreon, FALSE, TRUE);
892     SCRIPT_PutNumber(scripthandle, "Options", "Difficulty", difficulty, FALSE, 2);
893     SCRIPT_PutNumber(scripthandle, "Options", "Brightness", gbrightness, FALSE, 0);
894 
895     SCRIPT_PutNumber(scripthandle, "Setup", "CacheSize", MAXCACHE1DSIZE, FALSE, FALSE);
896     //SCRIPT_PutNumber(scripthandle, "Setup", "ConfigVersion", BYTEVERSION_EDUKE32, FALSE, FALSE);
897     SCRIPT_PutNumber(scripthandle, "Setup", "ForceSetup", gSetup.forcesetup, FALSE, FALSE);
898     SCRIPT_PutNumber(scripthandle, "Setup", "NoAutoLoad", gSetup.noautoload, FALSE, FALSE);
899 
900 //#ifdef POLYMER
901 //    SCRIPT_PutNumber(ud.config.scripthandle, "Screen Setup", "Polymer", glrendmode == REND_POLYMER, FALSE, FALSE);
902 //#endif
903 
904     SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenBPP", gSetup.bpp, FALSE, FALSE);
905     SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenHeight", gSetup.ydim, FALSE, FALSE);
906     SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenMode", gSetup.fullscreen, FALSE, FALSE);
907     SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenWidth", gSetup.xdim, FALSE, FALSE);
908 
909     //if (g_grpNamePtr && !g_addonNum)
910     //    SCRIPT_PutString(ud.config.scripthandle, "Setup", "SelectedGRP", g_grpNamePtr);
911 
912 #ifdef STARTUP_SETUP_WINDOW
913     if (g_noSetup == 0)
914         SCRIPT_PutString(scripthandle, "Setup", "ModDir", &g_modDir[0]);
915 #endif
916     // exit early after only updating the values that can be changed from the startup window
917     if (flags & 1)
918     {
919         SCRIPT_Save(scripthandle, setupfilename);
920         SCRIPT_Free(scripthandle);
921         return;
922     }
923 
924     SCRIPT_PutNumber(scripthandle, "Screen Setup", "MaxRefreshFreq", maxrefreshfreq, FALSE, FALSE);
925     SCRIPT_PutNumber(scripthandle, "Screen Setup", "WindowPosX", windowx, FALSE, FALSE);
926     SCRIPT_PutNumber(scripthandle, "Screen Setup", "WindowPosY", windowy, FALSE, FALSE);
927     SCRIPT_PutNumber(scripthandle, "Screen Setup", "WindowPositioning", windowpos, FALSE, FALSE);
928 
929     //if (!NAM_WW2GI)
930     //{
931     //    SCRIPT_PutNumber(ud.config.scripthandle, "Screen Setup", "Out",ud.lockout,FALSE,FALSE);
932     //    SCRIPT_PutString(ud.config.scripthandle, "Screen Setup", "Password",ud.pwlockout);
933     //}
934 
935 //#ifdef _WIN32
936 //    SCRIPT_PutNumber(ud.config.scripthandle, "Updates", "CheckForUpdates", ud.config.CheckForUpdates, FALSE, FALSE);
937 //    SCRIPT_PutNumber(ud.config.scripthandle, "Updates", "LastUpdateCheck", ud.config.LastUpdateCheck, FALSE, FALSE);
938 //#endif
939 
940     if (gSetup.usemouse)
941     {
942         for (int i=0; i<MAXMOUSEBUTTONS; i++)
943         {
944             if (CONFIG_FunctionNumToName(MouseFunctions[i][0]))
945             {
946                 Bsprintf(buf, "MouseButton%d", i);
947                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(MouseFunctions[i][0]));
948             }
949 
950             if (i >= (MAXMOUSEBUTTONS-2)) continue;
951 
952             if (CONFIG_FunctionNumToName(MouseFunctions[i][1]))
953             {
954                 Bsprintf(buf, "MouseButtonClicked%d", i);
955                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(MouseFunctions[i][1]));
956             }
957         }
958 
959         for (int i=0; i<MAXMOUSEAXES; i++)
960         {
961             if (CONFIG_AnalogNumToName(MouseAnalogueAxes[i]))
962             {
963                 Bsprintf(buf, "MouseAnalogAxes%d", i);
964                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_AnalogNumToName(MouseAnalogueAxes[i]));
965             }
966 
967             if (CONFIG_FunctionNumToName(MouseDigitalFunctions[i][0]))
968             {
969                 Bsprintf(buf, "MouseDigitalAxes%d_0", i);
970                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(MouseDigitalFunctions[i][0]));
971             }
972 
973             if (CONFIG_FunctionNumToName(MouseDigitalFunctions[i][1]))
974             {
975                 Bsprintf(buf, "MouseDigitalAxes%d_1", i);
976                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(MouseDigitalFunctions[i][1]));
977             }
978 
979             Bsprintf(buf, "MouseAnalogScale%d", i);
980             SCRIPT_PutNumber(scripthandle, "Controls", buf, MouseAnalogueScale[i], FALSE, FALSE);
981         }
982     }
983 
984     if (gSetup.usejoystick)
985     {
986         for (int dummy=0; dummy<MAXJOYBUTTONSANDHATS; dummy++)
987         {
988             if (CONFIG_FunctionNumToName(JoystickFunctions[dummy][0]))
989             {
990                 Bsprintf(buf, "ControllerButton%d", dummy);
991                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickFunctions[dummy][0]));
992             }
993 
994             if (CONFIG_FunctionNumToName(JoystickFunctions[dummy][1]))
995             {
996                 Bsprintf(buf, "ControllerButtonClicked%d", dummy);
997                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickFunctions[dummy][1]));
998             }
999         }
1000         for (int dummy=0; dummy<MAXJOYAXES; dummy++)
1001         {
1002             if (CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy]))
1003             {
1004                 Bsprintf(buf, "ControllerAnalogAxes%d", dummy);
1005                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy]));
1006             }
1007 
1008             if (CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][0]))
1009             {
1010                 Bsprintf(buf, "ControllerDigitalAxes%d_0", dummy);
1011                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][0]));
1012             }
1013 
1014             if (CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][1]))
1015             {
1016                 Bsprintf(buf, "ControllerDigitalAxes%d_1", dummy);
1017                 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][1]));
1018             }
1019 
1020             Bsprintf(buf, "ControllerAnalogScale%d", dummy);
1021             SCRIPT_PutNumber(scripthandle, "Controls", buf, JoystickAnalogueScale[dummy], FALSE, FALSE);
1022 
1023             Bsprintf(buf, "ControllerAnalogInvert%d", dummy);
1024             SCRIPT_PutNumber(scripthandle, "Controls", buf, JoystickAnalogueInvert[dummy], FALSE, FALSE);
1025 
1026             Bsprintf(buf, "ControllerAnalogDead%d", dummy);
1027             SCRIPT_PutNumber(scripthandle, "Controls", buf, JoystickAnalogueDead[dummy], FALSE, FALSE);
1028 
1029             Bsprintf(buf, "ControllerAnalogSaturate%d", dummy);
1030             SCRIPT_PutNumber(scripthandle, "Controls", buf, JoystickAnalogueSaturate[dummy], FALSE, FALSE);
1031         }
1032     }
1033 
1034     //SCRIPT_PutString(ud.config.scripthandle, "Comm Setup","PlayerName",&szPlayerName[0]);
1035 
1036     //SCRIPT_PutString(ud.config.scripthandle, "Comm Setup","RTSName",&ud.rtsname[0]);
1037 
1038  //   char commmacro[] = "CommbatMacro# ";
1039 
1040     //for (int dummy = 0; dummy < MAXRIDECULE; dummy++)
1041     //{
1042     //    commmacro[13] = dummy+'0';
1043     //    SCRIPT_PutString(ud.config.scripthandle, "Comm Setup",commmacro,&ud.ridecule[dummy][0]);
1044     //}
1045 
1046     SCRIPT_Save(scripthandle, setupfilename);
1047 
1048     if ((flags & 2) == 0)
1049         SCRIPT_Free(scripthandle);
1050 
1051     OSD_Printf("Wrote %s\n",setupfilename);
1052     CONFIG_WriteSettings();
1053     Bfflush(NULL);
1054 }
1055