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