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