1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 2010-2019 EDuke32 developers and contributors
4 Copyright (C) 2019 Nuke.YKT
5
6 This file is part of NBlood.
7
8 NBlood is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License version 2
10 as published by the Free Software Foundation.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22 //-------------------------------------------------------------------------
23
24 #include "baselayer.h"
25 #include "common_game.h"
26 #include "build.h"
27 #include "cache1d.h"
28 #include "sndcards.h"
29 #include "hash.h"
30 #include "scriplib.h"
31 #include "renderlayer.h"
32 #include "function.h"
33 #include "blood.h"
34 #include "config.h"
35 #include "gamedefs.h"
36 #include "globals.h"
37 #include "screen.h"
38 #include "sound.h"
39 #include "tile.h"
40 #include "view.h"
41
42 #ifdef __ANDROID__
43 # include "android.h"
44 #endif
45
46 #if defined RENDERTYPESDL && defined SDL_TARGET && SDL_TARGET > 1
47 # include "sdl_inc.h"
48 #endif
49
50 // we load this in to get default button and key assignments
51 // as well as setting up function mappings
52
53 #define __SETUP__ // JBF 20031211
54 #include "_functio.h"
55
56 hashtable_t h_gamefuncs = { NUMGAMEFUNCTIONS<<1, NULL };
57
58 int32_t MouseDeadZone, MouseBias;
59 int32_t MouseFunctions[MAXMOUSEBUTTONS][2];
60 int32_t MouseAnalogueAxes[MAXMOUSEAXES];
61 int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2];
62 int32_t JoystickDigitalFunctions[MAXJOYAXES][2];
63 int32_t JoystickAnalogueAxes[MAXJOYAXES];
64 int32_t JoystickAnalogueScale[MAXJOYAXES];
65 int32_t JoystickAnalogueDead[MAXJOYAXES];
66 int32_t JoystickAnalogueSaturate[MAXJOYAXES];
67 uint8_t KeyboardKeys[NUMGAMEFUNCTIONS][2];
68 int32_t scripthandle;
69 int32_t setupread;
70 int32_t MusicRestartsOnLoadToggle;
71 int32_t configversion;
72 int32_t CheckForUpdates;
73 int32_t LastUpdateCheck;
74 int32_t useprecache;
75 char CommbatMacro[MAXRIDECULE][MAXRIDECULELENGTH];
76 char szPlayerName[MAXPLAYERNAME];
77 int32_t gTurnSpeed;
78 int32_t gDetail;
79 int32_t gMouseAim;
80 int32_t gAutoAim;
81 int32_t gWeaponSwitch;
82 int32_t gAutoRun;
83 int32_t gViewInterpolate;
84 int32_t gViewHBobbing;
85 int32_t gViewVBobbing;
86 int32_t gFollowMap;
87 int32_t gOverlayMap;
88 int32_t gRotateMap;
89 int32_t gAimReticle;
90 int32_t gSlopeTilting;
91 int32_t gMessageState;
92 int32_t gMessageCount;
93 int32_t gMessageTime;
94 int32_t gMessageFont;
95 int32_t gbAdultContent;
96 char gzAdultPassword[9];
97 int32_t gDoppler;
98 int32_t gShowPlayerNames;
99 int32_t gShowWeapon;
100 int32_t gMouseSensitivity;
101 int32_t gMouseAiming;
102 int32_t gMouseAimingFlipped;
103 int32_t gRunKeyMode;
104 bool gNoClip;
105 bool gInfiniteAmmo;
106 bool gFullMap;
107 int32_t gUpscaleFactor;
108 int32_t gLevelStats;
109 int32_t gPowerupDuration;
110 int32_t gShowMapTitle;
111 int32_t gFov;
112 int32_t gCenterHoriz;
113 int32_t gDeliriumBlur;
114
115 //////////
116 int gWeaponsV10x;
117 /////////
118
CONFIG_FunctionNameToNum(const char * func)119 int32_t CONFIG_FunctionNameToNum(const char *func)
120 {
121 int32_t i;
122
123 if (!func)
124 return -1;
125
126 i = hash_find(&h_gamefuncs,func);
127
128 if (i < 0)
129 {
130 char *str = Bstrtolower(Xstrdup(func));
131 i = hash_find(&h_gamefuncs,str);
132 Bfree(str);
133
134 return i;
135 }
136
137 return i;
138 }
139
140
CONFIG_FunctionNumToName(int32_t func)141 char *CONFIG_FunctionNumToName(int32_t func)
142 {
143 if ((unsigned)func >= (unsigned)NUMGAMEFUNCTIONS)
144 return NULL;
145 return gamefunctions[func];
146 }
147
148
CONFIG_AnalogNameToNum(const char * func)149 int32_t CONFIG_AnalogNameToNum(const char *func)
150 {
151 if (!func)
152 return -1;
153
154 if (!Bstrcasecmp(func,"analog_turning"))
155 {
156 return analog_turning;
157 }
158 if (!Bstrcasecmp(func,"analog_strafing"))
159 {
160 return analog_strafing;
161 }
162 if (!Bstrcasecmp(func,"analog_moving"))
163 {
164 return analog_moving;
165 }
166 if (!Bstrcasecmp(func,"analog_lookingupanddown"))
167 {
168 return analog_lookingupanddown;
169 }
170
171 return -1;
172 }
173
174
CONFIG_AnalogNumToName(int32_t func)175 const char *CONFIG_AnalogNumToName(int32_t func)
176 {
177 switch (func)
178 {
179 case analog_turning:
180 return "analog_turning";
181 case analog_strafing:
182 return "analog_strafing";
183 case analog_moving:
184 return "analog_moving";
185 case analog_lookingupanddown:
186 return "analog_lookingupanddown";
187 }
188
189 return NULL;
190 }
191
192
CONFIG_SetDefaultKeys(const char (* keyptr)[MAXGAMEFUNCLEN],bool lazy)193 void CONFIG_SetDefaultKeys(const char (*keyptr)[MAXGAMEFUNCLEN], bool lazy/*=false*/)
194 {
195 static char const s_gamefunc_[] = "gamefunc_";
196 int constexpr strlen_gamefunc_ = ARRAY_SIZE(s_gamefunc_) - 1;
197
198 if (!lazy)
199 {
200 Bmemset(KeyboardKeys, 0xff, sizeof(KeyboardKeys));
201 CONTROL_ClearAllBinds();
202 }
203
204 for (int i=0; i < ARRAY_SSIZE(gamefunctions); ++i)
205 {
206 if (gamefunctions[i][0] == '\0')
207 continue;
208
209 auto &key = KeyboardKeys[i];
210
211 int const default0 = KB_StringToScanCode(keyptr[i<<1]);
212 int const default1 = KB_StringToScanCode(keyptr[(i<<1)+1]);
213
214 // skip the function if the default key is already used
215 // or the function is assigned to another key
216 if (lazy && (key[0] != 0xff || (CONTROL_KeyIsBound(default0) && Bstrlen(CONTROL_KeyBinds[default0].cmdstr) > strlen_gamefunc_
217 && CONFIG_FunctionNameToNum(CONTROL_KeyBinds[default0].cmdstr + strlen_gamefunc_) >= 0)))
218 {
219 #if 0 // defined(DEBUGGINGAIDS)
220 if (key[0] != 0xff)
221 initprintf("Skipping %s bound to %s\n", keyptr[i<<1], CONTROL_KeyBinds[default0].cmdstr);
222 #endif
223 continue;
224 }
225
226 key[0] = default0;
227 key[1] = default1;
228
229 if (key[0])
230 CONTROL_FreeKeyBind(key[0]);
231
232 if (key[1])
233 CONTROL_FreeKeyBind(key[1]);
234
235 if (i == gamefunc_Show_Console)
236 OSD_CaptureKey(key[0]);
237 else
238 CONFIG_MapKey(i, key[0], 0, key[1], 0);
239 }
240 }
241
242
CONFIG_SetDefaults(void)243 void CONFIG_SetDefaults(void)
244 {
245 scripthandle = -1;
246
247 #ifdef __ANDROID__
248 droidinput.forward_sens = 5.f;
249 droidinput.gameControlsAlpha = 0.5;
250 droidinput.hideStick = 0;
251 droidinput.pitch_sens = 5.f;
252 droidinput.quickSelectWeapon = 1;
253 droidinput.strafe_sens = 5.f;
254 droidinput.toggleCrouch = 1;
255 droidinput.yaw_sens = 5.f;
256
257 gSetup.xdim = droidinfo.screen_width;
258 gSetup.ydim = droidinfo.screen_height;
259 #else
260 # if defined RENDERTYPESDL && SDL_MAJOR_VERSION > 1
261 uint32_t inited = SDL_WasInit(SDL_INIT_VIDEO);
262 if (inited == 0)
263 SDL_Init(SDL_INIT_VIDEO);
264 else if (!(inited & SDL_INIT_VIDEO))
265 SDL_InitSubSystem(SDL_INIT_VIDEO);
266
267 SDL_DisplayMode dm;
268 if (SDL_GetDesktopDisplayMode(0, &dm) == 0)
269 {
270 gSetup.xdim = dm.w;
271 gSetup.ydim = dm.h;
272 }
273 else
274 # endif
275 {
276 gSetup.xdim = 1024;
277 gSetup.ydim = 768;
278 }
279 #endif
280
281 #ifdef USE_OPENGL
282 gSetup.bpp = 32;
283 #else
284 gSetup.bpp = 8;
285 #endif
286
287 #if defined(_WIN32)
288 MixRate = 44100;
289 #elif defined __ANDROID__
290 MixRate = droidinfo.audio_sample_rate;
291 #else
292 MixRate = 48000;
293 #endif
294
295 #if defined GEKKO || defined __OPENDINGUX__
296 NumVoices = 32;
297 #else
298 NumVoices = 64;
299 #endif
300
301 #ifdef GEKKO
302 gSetup.usejoystick = 1;
303 #else
304 gSetup.usejoystick = 0;
305 #endif
306
307 gSetup.forcesetup = 1;
308 gSetup.noautoload = 1;
309 gSetup.fullscreen = 1;
310 gSetup.usemouse = 1;
311
312 //ud.config.AmbienceToggle = 1;
313 //ud.config.AutoAim = 1;
314 CheckForUpdates = 1;
315 FXVolume = 255;
316 MouseBias = 0;
317 MouseDeadZone = 0;
318 MusicToggle = 1;
319 MusicRestartsOnLoadToggle = 0;
320 MusicVolume = 195;
321 NumBits = 16;
322 NumChannels = 2;
323 #ifdef ASS_REVERSESTEREO
324 ReverseStereo = 0;
325 #endif
326 gBrightness = 8;
327 //ud.config.ShowWeapons = 0;
328 SoundToggle = 1;
329 CDAudioToggle = 0;
330 MusicDevice = ASS_AutoDetect;
331 //ud.config.VoiceToggle = 5; // bitfield, 1 = local, 2 = dummy, 4 = other players in DM
332 useprecache = 1;
333 configversion = 0;
334 //ud.crosshair = 1;
335 //ud.crosshairscale = 50;
336 //ud.default_skill = 1;
337 //ud.democams = 1;
338 gUpscaleFactor = 0;
339 //ud.display_bonus_screen = 1;
340 //ud.drawweapon = 1;
341 //ud.hudontop = 0;
342 //ud.idplayers = 1;
343 gLevelStats = 0;
344 gPowerupDuration = 1;
345 gShowMapTitle = 1;
346 //ud.lockout = 0;
347 //ud.m_marker = 1;
348 //ud.maxautosaves = 5;
349 //ud.menu_scrollbartilenum = -1;
350 //ud.menu_scrollbarz = 65536;
351 //ud.menu_scrollcursorz = 65536;
352 //ud.menu_slidebarmargin = 65536;
353 //ud.menu_slidebarz = 65536;
354 //ud.menu_slidecursorz = 65536;
355 //ud.menubackground = 1;
356 //ud.mouseaiming = 0;
357 //ud.mouseflip = 1;
358 //ud.msgdisptime = 120;
359 //ud.obituaries = 1;
360 //ud.pwlockout[0] = '\0';
361 gRunKeyMode = 0;
362 //ud.screen_size = 4;
363 //ud.screen_tilting = 1;
364 //ud.screenfade = 1;
365 //ud.shadow_pal = 4;
366 //ud.shadows = 1;
367 //ud.show_level_text = 1;
368 //ud.slidebar_paldisabled = 1;
369 //ud.statusbarflags = STATUSBAR_NOSHRINK;
370 //ud.statusbarmode = 1;
371 //ud.statusbarscale = 100;
372 //ud.team = 0;
373 //ud.textscale = 200;
374 //ud.viewbob = 1;
375 //ud.weaponscale = 100;
376 //ud.weaponsway = 1;
377 //ud.weaponswitch = 3; // new+empty
378 gFov = 90;
379 gCenterHoriz = 0;
380 gDeliriumBlur = 1;
381 gViewSize = 2;
382 gTurnSpeed = 92;
383 gDetail = 4;
384 gAutoRun = 0;
385 gViewInterpolate = 1;
386 gViewHBobbing = 1;
387 gViewVBobbing = 1;
388 gFollowMap = 1;
389 gOverlayMap = 0;
390 gRotateMap = 0;
391 gAimReticle = 0;
392 gSlopeTilting = 0;
393 gMessageState = 1;
394 gMessageCount = 4;
395 gMessageTime = 5;
396 gMessageFont = 0;
397 gbAdultContent = 0;
398 gDoppler = 1;
399 gShowPlayerNames = 0;
400 gShowWeapon = 0;
401 gzAdultPassword[0] = 0;
402
403 gMouseAimingFlipped = 0;
404 gMouseAim = 1;
405 gAutoAim = 1;
406 gWeaponSwitch = 1;
407
408 Bstrcpy(szPlayerName, "Player");
409
410 Bstrcpy(CommbatMacro[0], "I love the smell of napalm...");
411 Bstrcpy(CommbatMacro[1], "Is that gasoline I smell?");
412 Bstrcpy(CommbatMacro[2], "Ta da!");
413 Bstrcpy(CommbatMacro[3], "Who wants some, huh? Who's next?");
414 Bstrcpy(CommbatMacro[4], "I have something for you.");
415 Bstrcpy(CommbatMacro[5], "You just gonna stand there...");
416 Bstrcpy(CommbatMacro[6], "That'll teach ya!");
417 Bstrcpy(CommbatMacro[7], "Ooh, that wasn't a bit nice.");
418 Bstrcpy(CommbatMacro[8], "Amateurs!");
419 Bstrcpy(CommbatMacro[9], "Fool! You are already dead.");
420
421 CONFIG_SetDefaultKeys(keydefaults);
422
423 memset(MouseFunctions, -1, sizeof(MouseFunctions));
424 memset(JoystickFunctions, -1, sizeof(JoystickFunctions));
425 memset(JoystickDigitalFunctions, -1, sizeof(JoystickDigitalFunctions));
426
427 CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY;
428
429 for (int i=0; i<MAXMOUSEBUTTONS; i++)
430 {
431 MouseFunctions[i][0] = CONFIG_FunctionNameToNum(mousedefaults[i]);
432 CONTROL_MapButton(MouseFunctions[i][0], i, 0, controldevice_mouse);
433 if (i>=4) continue;
434 MouseFunctions[i][1] = CONFIG_FunctionNameToNum(mouseclickeddefaults[i]);
435 CONTROL_MapButton(MouseFunctions[i][1], i, 1, controldevice_mouse);
436 }
437
438 for (int i=0; i<MAXMOUSEAXES; i++)
439 {
440 CONTROL_SetAnalogAxisScale(i, DEFAULTMOUSEANALOGUESCALE, controldevice_mouse);
441
442 MouseAnalogueAxes[i] = CONFIG_AnalogNameToNum(mouseanalogdefaults[i]);
443 CONTROL_MapAnalogAxis(i, MouseAnalogueAxes[i], controldevice_mouse);
444 }
445
446 for (int i=0; i<MAXJOYBUTTONSANDHATS; i++)
447 {
448 JoystickFunctions[i][0] = CONFIG_FunctionNameToNum(joystickdefaults[i]);
449 JoystickFunctions[i][1] = CONFIG_FunctionNameToNum(joystickclickeddefaults[i]);
450 CONTROL_MapButton(JoystickFunctions[i][0], i, 0, controldevice_joystick);
451 CONTROL_MapButton(JoystickFunctions[i][1], i, 1, controldevice_joystick);
452 }
453
454 for (int i=0; i<MAXJOYAXES; i++)
455 {
456 JoystickAnalogueScale[i] = DEFAULTJOYSTICKANALOGUESCALE;
457 JoystickAnalogueDead[i] = DEFAULTJOYSTICKANALOGUEDEAD;
458 JoystickAnalogueSaturate[i] = DEFAULTJOYSTICKANALOGUESATURATE;
459 CONTROL_SetAnalogAxisScale(i, JoystickAnalogueScale[i], controldevice_joystick);
460
461 JoystickDigitalFunctions[i][0] = CONFIG_FunctionNameToNum(joystickdigitaldefaults[i*2]);
462 JoystickDigitalFunctions[i][1] = CONFIG_FunctionNameToNum(joystickdigitaldefaults[i*2+1]);
463 CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][0], 0, controldevice_joystick);
464 CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][1], 1, controldevice_joystick);
465
466 JoystickAnalogueAxes[i] = CONFIG_AnalogNameToNum(joystickanalogdefaults[i]);
467 CONTROL_MapAnalogAxis(i, JoystickAnalogueAxes[i], controldevice_joystick);
468 }
469 }
470
471
472 // 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)473 void CONFIG_MapKey(int which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2)
474 {
475 int const keys[] = { key1, key2, oldkey1, oldkey2 };
476 char buf[2*MAXGAMEFUNCLEN];
477 char tempbuf[128];
478
479 if (which == gamefunc_Show_Console)
480 OSD_CaptureKey(key1);
481
482 for (int k = 0; (unsigned)k < ARRAY_SIZE(keys); k++)
483 {
484 if (keys[k] == 0xff || !keys[k])
485 continue;
486
487 int match = 0;
488
489 for (; sctokeylut[match].key; match++)
490 {
491 if (keys[k] == sctokeylut[match].sc)
492 break;
493 }
494
495 tempbuf[0] = 0;
496
497 for (int i=NUMGAMEFUNCTIONS-1; i>=0; i--)
498 {
499 if (KeyboardKeys[i][0] == keys[k] || KeyboardKeys[i][1] == keys[k])
500 {
501 Bsprintf(buf, "gamefunc_%s; ", CONFIG_FunctionNumToName(i));
502 Bstrcat(tempbuf,buf);
503 }
504 }
505
506 int const len = Bstrlen(tempbuf);
507
508 if (len >= 2)
509 {
510 tempbuf[len-2] = 0; // cut off the trailing "; "
511 CONTROL_BindKey(keys[k], tempbuf, 1, sctokeylut[match].key ? sctokeylut[match].key : "<?>");
512 }
513 else
514 {
515 CONTROL_FreeKeyBind(keys[k]);
516 }
517 }
518 }
519
520
CONFIG_SetupMouse(void)521 void CONFIG_SetupMouse(void)
522 {
523 if (scripthandle < 0)
524 return;
525
526 char str[80];
527 char temp[80];
528
529 for (int i=0; i<MAXMOUSEBUTTONS; i++)
530 {
531 Bsprintf(str,"MouseButton%d",i);
532 temp[0] = 0;
533 if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
534 MouseFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
535
536 Bsprintf(str,"MouseButtonClicked%d",i);
537 temp[0] = 0;
538 if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
539 MouseFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
540 }
541
542 // map over the axes
543 for (int i=0; i<MAXMOUSEAXES; i++)
544 {
545 Bsprintf(str,"MouseAnalogAxes%d",i);
546 temp[0] = 0;
547 if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
548 if (CONFIG_AnalogNameToNum(temp) != -1 || (!temp[0] && CONFIG_FunctionNameToNum(temp) != -1))
549 MouseAnalogueAxes[i] = CONFIG_AnalogNameToNum(temp);
550 }
551
552 for (int i=0; i<MAXMOUSEBUTTONS; i++)
553 {
554 CONTROL_MapButton(MouseFunctions[i][0], i, 0, controldevice_mouse);
555 CONTROL_MapButton(MouseFunctions[i][1], i, 1, controldevice_mouse);
556 }
557 for (int i=0; i<MAXMOUSEAXES; i++)
558 CONTROL_MapAnalogAxis(i, MouseAnalogueAxes[i], controldevice_mouse);
559 }
560
561
CONFIG_SetupJoystick(void)562 void CONFIG_SetupJoystick(void)
563 {
564 int32_t i;
565 char str[80];
566 char temp[80];
567 int32_t scale;
568
569 if (scripthandle < 0) return;
570
571 for (i=0; i<MAXJOYBUTTONSANDHATS; i++)
572 {
573 Bsprintf(str,"JoystickButton%d",i);
574 temp[0] = 0;
575 if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
576 JoystickFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
577
578 Bsprintf(str,"JoystickButtonClicked%d",i);
579 temp[0] = 0;
580 if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
581 JoystickFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
582 }
583
584 // map over the axes
585 for (i=0; i<MAXJOYAXES; i++)
586 {
587 Bsprintf(str,"JoystickAnalogAxes%d",i);
588 temp[0] = 0;
589 if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
590 if (CONFIG_AnalogNameToNum(temp) != -1 || (!temp[0] && CONFIG_FunctionNameToNum(temp) != -1))
591 JoystickAnalogueAxes[i] = CONFIG_AnalogNameToNum(temp);
592
593 Bsprintf(str,"JoystickDigitalAxes%d_0",i);
594 temp[0] = 0;
595 if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
596 if (CONFIG_FunctionNameToNum(temp) != -1 || (!temp[0] && CONFIG_FunctionNameToNum(temp) != -1))
597 JoystickDigitalFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
598
599 Bsprintf(str,"JoystickDigitalAxes%d_1",i);
600 temp[0] = 0;
601 if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
602 if (CONFIG_FunctionNameToNum(temp) != -1 || (!temp[0] && CONFIG_FunctionNameToNum(temp) != -1))
603 JoystickDigitalFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
604
605 Bsprintf(str,"JoystickAnalogScale%d",i);
606 scale = JoystickAnalogueScale[i];
607 SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
608 JoystickAnalogueScale[i] = scale;
609
610 Bsprintf(str,"JoystickAnalogDead%d",i);
611 scale = JoystickAnalogueDead[i];
612 SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
613 JoystickAnalogueDead[i] = scale;
614
615 Bsprintf(str,"JoystickAnalogSaturate%d",i);
616 scale = JoystickAnalogueSaturate[i];
617 SCRIPT_GetNumber(scripthandle, "Controls", str,&scale);
618 JoystickAnalogueSaturate[i] = scale;
619 }
620
621 for (i=0; i<MAXJOYBUTTONSANDHATS; i++)
622 {
623 CONTROL_MapButton(JoystickFunctions[i][0], i, 0, controldevice_joystick);
624 CONTROL_MapButton(JoystickFunctions[i][1], i, 1, controldevice_joystick);
625 }
626 for (i=0; i<MAXJOYAXES; i++)
627 {
628 CONTROL_MapAnalogAxis(i, JoystickAnalogueAxes[i], controldevice_joystick);
629 CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][0], 0, controldevice_joystick);
630 CONTROL_MapDigitalAxis(i, JoystickDigitalFunctions[i][1], 1, controldevice_joystick);
631 CONTROL_SetAnalogAxisScale(i, JoystickAnalogueScale[i], controldevice_joystick);
632 }
633 }
634
635
CONFIG_ReadSetup(void)636 int CONFIG_ReadSetup(void)
637 {
638 char tempbuf[1024];
639
640 CONTROL_ClearAssignments();
641 CONFIG_SetDefaults();
642
643 setupread = 1;
644 pathsearchmode = 1;
645
646 if (scripthandle < 0)
647 {
648 if (buildvfs_exists(SetupFilename)) // JBF 20031211
649 scripthandle = SCRIPT_Load(SetupFilename);
650 #if !defined(EDUKE32_TOUCH_DEVICES) && !defined(EDUKE32_STANDALONE)
651 else if (buildvfs_exists(SETUPFILENAME))
652 {
653 int const i = wm_ynbox("Import Configuration Settings",
654 "The configuration file \"%s\" was not found. "
655 "Import configuration data from \"%s\"?",
656 SetupFilename, SETUPFILENAME);
657 if (i)
658 scripthandle = SCRIPT_Load(SETUPFILENAME);
659 }
660 #endif
661 }
662
663 pathsearchmode = 0;
664
665 if (scripthandle < 0)
666 return -1;
667
668 // Nuke: make cvar
669 ///////
670 SCRIPT_GetNumber(scripthandle, "Game Options", "WeaponsV10x", &gWeaponsV10x);
671 ///////
672
673 char commmacro[] = "CommbatMacro# ";
674
675 for (int i = 0; i < MAXRIDECULE; i++)
676 {
677 commmacro[13] = i+'0';
678 SCRIPT_GetString(scripthandle, "Comm Setup",commmacro,&CommbatMacro[i][0]);
679 }
680
681 Bmemset(tempbuf, 0, sizeof(tempbuf));
682 SCRIPT_GetString(scripthandle, "Comm Setup","PlayerName",&tempbuf[0]);
683
684 char nameBuf[64];
685
686 while (Bstrlen(OSD_StripColors(nameBuf, tempbuf)) > 10)
687 tempbuf[Bstrlen(tempbuf) - 1] = '\0';
688
689 Bstrncpyz(szPlayerName, tempbuf, sizeof(szPlayerName));
690
691 //SCRIPT_GetString(scripthandle, "Comm Setup","RTSName",&ud.rtsname[0]);
692
693 SCRIPT_GetNumber(scripthandle, "Setup", "ConfigVersion", &configversion);
694 SCRIPT_GetNumber(scripthandle, "Setup", "ForceSetup", &gSetup.forcesetup);
695 SCRIPT_GetNumber(scripthandle, "Setup", "NoAutoLoad", &gSetup.noautoload);
696
697 int32_t cachesize;
698 SCRIPT_GetNumber(scripthandle, "Setup", "CacheSize", &cachesize);
699
700 if (cachesize > MAXCACHE1DSIZE)
701 MAXCACHE1DSIZE = cachesize;
702
703 if (gNoSetup == 0 && g_modDir[0] == '/')
704 {
705 struct Bstat st;
706 SCRIPT_GetString(scripthandle, "Setup","ModDir",&g_modDir[0]);
707
708 if (Bstat(g_modDir, &st))
709 {
710 if ((st.st_mode & S_IFDIR) != S_IFDIR)
711 {
712 initprintf("Invalid mod dir in cfg!\n");
713 Bsprintf(g_modDir,"/");
714 }
715 }
716 }
717
718 //if (g_grpNamePtr == NULL && g_addonNum == 0)
719 //{
720 // SCRIPT_GetStringPtr(scripthandle, "Setup", "SelectedGRP", &g_grpNamePtr);
721 // if (g_grpNamePtr && !Bstrlen(g_grpNamePtr))
722 // g_grpNamePtr = dup_filename(G_DefaultGrpFile());
723 //}
724 //
725 //if (!NAM_WW2GI)
726 //{
727 // SCRIPT_GetNumber(scripthandle, "Screen Setup", "Out", &ud.lockout);
728 // SCRIPT_GetString(scripthandle, "Screen Setup", "Password", &ud.pwlockout[0]);
729 //}
730
731 windowx = -1;
732 windowy = -1;
733
734 SCRIPT_GetNumber(scripthandle, "Screen Setup", "MaxRefreshFreq", (int32_t *)&maxrefreshfreq);
735 SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenBPP", &gSetup.bpp);
736 SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenHeight", &gSetup.ydim);
737 SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenMode", &gSetup.fullscreen);
738 SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenWidth", &gSetup.xdim);
739 SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosX", (int32_t *)&windowx);
740 SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosY", (int32_t *)&windowy);
741 SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPositioning", (int32_t *)&windowpos);
742
743 if (gSetup.bpp < 8) gSetup.bpp = 32;
744
745 #ifdef POLYMER
746 int32_t rendmode = 0;
747 SCRIPT_GetNumber(scripthandle, "Screen Setup", "Polymer", &rendmode);
748 glrendmode = (rendmode > 0) ? REND_POLYMER : REND_POLYMOST;
749 #endif
750
751 //SCRIPT_GetNumber(scripthandle, "Misc", "Executions", &ud.executions);
752
753 #ifdef _WIN32
754 SCRIPT_GetNumber(scripthandle, "Updates", "CheckForUpdates", &CheckForUpdates);
755 SCRIPT_GetNumber(scripthandle, "Updates", "LastUpdateCheck", &LastUpdateCheck);
756 #endif
757
758 setupread = 1;
759 return 0;
760 }
761
762
CONFIG_WriteSettings(void)763 void CONFIG_WriteSettings(void) // save binds and aliases to <cfgname>_settings.cfg
764 {
765 char *ptr = Xstrdup(SetupFilename);
766 char filename[BMAX_PATH];
767
768 if (!Bstrcmp(SetupFilename, SETUPFILENAME))
769 Bsprintf(filename, "settings.cfg");
770 else
771 Bsprintf(filename, "%s_settings.cfg", strtok(ptr, "."));
772
773 BFILE *fp = Bfopen(filename, "wt");
774
775 if (fp)
776 {
777 Bfprintf(fp,"// this file is automatically generated by %s\n", AppProperName);
778 Bfprintf(fp,"unbindall\n");
779
780 for (int i=0; i<MAXBOUNDKEYS+MAXMOUSEBUTTONS; i++)
781 {
782 if (CONTROL_KeyIsBound(i))
783 {
784 Bfprintf(fp, "bind \"%s\"%s \"%s\"\n", CONTROL_KeyBinds[i].key,
785 CONTROL_KeyBinds[i].repeat ? "" : " norepeat",
786 CONTROL_KeyBinds[i].cmdstr);
787 }
788 }
789
790 OSD_WriteAliases(fp);
791
792 if (g_isAlterDefaultCrosshair)
793 Bfprintf(fp, "crosshaircolor %d %d %d\n", CrosshairColors.r, CrosshairColors.g, CrosshairColors.b);
794
795 OSD_WriteCvars(fp);
796
797 Bfclose(fp);
798 Bfree(ptr);
799
800 OSD_Printf("Wrote %s\n", filename);
801
802 return;
803 }
804
805 OSD_Printf("Error writing %s: %s\n", filename, strerror(errno));
806
807 Bfree(ptr);
808 }
809
CONFIG_WriteSetup(uint32_t flags)810 void CONFIG_WriteSetup(uint32_t flags)
811 {
812 char buf[128];
813 if (!setupread) return;
814
815 if (scripthandle < 0)
816 scripthandle = SCRIPT_Init(SetupFilename);
817
818 //SCRIPT_PutNumber(scripthandle, "Misc", "Executions", ud.executions, FALSE, FALSE);
819
820 SCRIPT_PutNumber(scripthandle, "Setup", "CacheSize", MAXCACHE1DSIZE, FALSE, FALSE);
821 SCRIPT_PutNumber(scripthandle, "Setup", "ConfigVersion", BYTEVERSION, FALSE, FALSE);
822 SCRIPT_PutNumber(scripthandle, "Setup", "ForceSetup", gSetup.forcesetup, FALSE, FALSE);
823 SCRIPT_PutNumber(scripthandle, "Setup", "NoAutoLoad", gSetup.noautoload, FALSE, FALSE);
824
825 #ifdef POLYMER
826 SCRIPT_PutNumber(scripthandle, "Screen Setup", "Polymer", glrendmode == REND_POLYMER, FALSE, FALSE);
827 #endif
828
829 SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenBPP", gSetup.bpp, FALSE, FALSE);
830 SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenHeight", gSetup.ydim, FALSE, FALSE);
831 SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenMode", gSetup.fullscreen, FALSE, FALSE);
832 SCRIPT_PutNumber(scripthandle, "Screen Setup", "ScreenWidth", gSetup.xdim, FALSE, FALSE);
833
834 //if (g_grpNamePtr && !g_addonNum)
835 // SCRIPT_PutString(scripthandle, "Setup", "SelectedGRP", g_grpNamePtr);
836
837 #ifdef STARTUP_SETUP_WINDOW
838 if (gNoSetup == 0)
839 SCRIPT_PutString(scripthandle, "Setup", "ModDir", &g_modDir[0]);
840 #endif
841 // exit early after only updating the values that can be changed from the startup window
842 if (flags & 1)
843 {
844 SCRIPT_Save(scripthandle, SetupFilename);
845 SCRIPT_Free(scripthandle);
846 return;
847 }
848
849 SCRIPT_PutNumber(scripthandle, "Screen Setup", "MaxRefreshFreq", maxrefreshfreq, FALSE, FALSE);
850 SCRIPT_PutNumber(scripthandle, "Screen Setup", "WindowPosX", windowx, FALSE, FALSE);
851 SCRIPT_PutNumber(scripthandle, "Screen Setup", "WindowPosY", windowy, FALSE, FALSE);
852 SCRIPT_PutNumber(scripthandle, "Screen Setup", "WindowPositioning", windowpos, FALSE, FALSE);
853
854 //if (!NAM_WW2GI)
855 //{
856 // SCRIPT_PutNumber(scripthandle, "Screen Setup", "Out",ud.lockout,FALSE,FALSE);
857 // SCRIPT_PutString(scripthandle, "Screen Setup", "Password",ud.pwlockout);
858 //}
859
860 #ifdef _WIN32
861 SCRIPT_PutNumber(scripthandle, "Updates", "CheckForUpdates", CheckForUpdates, FALSE, FALSE);
862 SCRIPT_PutNumber(scripthandle, "Updates", "LastUpdateCheck", LastUpdateCheck, FALSE, FALSE);
863 #endif
864
865 if (gSetup.usemouse)
866 {
867 for (int i=0; i<MAXMOUSEBUTTONS; i++)
868 {
869 if (CONFIG_FunctionNumToName(MouseFunctions[i][0]))
870 {
871 Bsprintf(buf, "MouseButton%d", i);
872 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(MouseFunctions[i][0]));
873 }
874
875 if (i >= (MAXMOUSEBUTTONS-2)) continue;
876
877 if (CONFIG_FunctionNumToName(MouseFunctions[i][1]))
878 {
879 Bsprintf(buf, "MouseButtonClicked%d", i);
880 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(MouseFunctions[i][1]));
881 }
882 }
883
884 for (int i=0; i<MAXMOUSEAXES; i++)
885 {
886 if (CONFIG_AnalogNumToName(MouseAnalogueAxes[i]))
887 {
888 Bsprintf(buf, "MouseAnalogAxes%d", i);
889 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_AnalogNumToName(MouseAnalogueAxes[i]));
890 }
891 }
892 }
893
894 if (gSetup.usejoystick)
895 {
896 for (int dummy=0; dummy<MAXJOYBUTTONSANDHATS; dummy++)
897 {
898 if (CONFIG_FunctionNumToName(JoystickFunctions[dummy][0]))
899 {
900 Bsprintf(buf, "JoystickButton%d", dummy);
901 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickFunctions[dummy][0]));
902 }
903
904 if (CONFIG_FunctionNumToName(JoystickFunctions[dummy][1]))
905 {
906 Bsprintf(buf, "JoystickButtonClicked%d", dummy);
907 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickFunctions[dummy][1]));
908 }
909 }
910 for (int dummy=0; dummy<MAXJOYAXES; dummy++)
911 {
912 if (CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy]))
913 {
914 Bsprintf(buf, "JoystickAnalogAxes%d", dummy);
915 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_AnalogNumToName(JoystickAnalogueAxes[dummy]));
916 }
917
918 if (CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][0]))
919 {
920 Bsprintf(buf, "JoystickDigitalAxes%d_0", dummy);
921 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][0]));
922 }
923
924 if (CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][1]))
925 {
926 Bsprintf(buf, "JoystickDigitalAxes%d_1", dummy);
927 SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(JoystickDigitalFunctions[dummy][1]));
928 }
929
930 if (JoystickAnalogueScale[dummy] != DEFAULTJOYSTICKANALOGUESCALE)
931 {
932 Bsprintf(buf, "JoystickAnalogScale%d", dummy);
933 SCRIPT_PutNumber(scripthandle, "Controls", buf, JoystickAnalogueScale[dummy], FALSE, FALSE);
934 }
935
936 if (JoystickAnalogueDead[dummy] != DEFAULTJOYSTICKANALOGUEDEAD)
937 {
938 Bsprintf(buf, "JoystickAnalogDead%d", dummy);
939 SCRIPT_PutNumber(scripthandle, "Controls", buf, JoystickAnalogueDead[dummy], FALSE, FALSE);
940 }
941
942 if (JoystickAnalogueSaturate[dummy] != DEFAULTJOYSTICKANALOGUESATURATE)
943 {
944 Bsprintf(buf, "JoystickAnalogSaturate%d", dummy);
945 SCRIPT_PutNumber(scripthandle, "Controls", buf, JoystickAnalogueSaturate[dummy], FALSE, FALSE);
946 }
947 }
948 }
949
950 SCRIPT_PutString(scripthandle, "Comm Setup","PlayerName",&szPlayerName[0]);
951
952 //SCRIPT_PutString(scripthandle, "Comm Setup","RTSName",&ud.rtsname[0]);
953
954 char commmacro[] = "CommbatMacro# ";
955
956 for (int dummy = 0; dummy < MAXRIDECULE; dummy++)
957 {
958 commmacro[13] = dummy+'0';
959 SCRIPT_PutString(scripthandle, "Comm Setup",commmacro,&CommbatMacro[dummy][0]);
960 }
961
962 ///////
963 SCRIPT_PutNumber(scripthandle, "Game Options", "WeaponsV10x", gWeaponsV10x, FALSE, FALSE);
964 ///////
965
966 SCRIPT_Save(scripthandle, SetupFilename);
967
968 if ((flags & 2) == 0)
969 SCRIPT_Free(scripthandle);
970
971 OSD_Printf("Wrote %s\n",SetupFilename);
972 CONFIG_WriteSettings();
973 Bfflush(NULL);
974 }
975
976 #if 0
977 static const char *CONFIG_GetMapEntryName(char m[], char const * const mapname)
978 {
979 strcpy(m, mapname);
980
981 char *p = strrchr(m, '/');
982 if (!p) p = strrchr(m, '\\');
983 if (p) Bmemmove(m, p, Bstrlen(p)+1);
984 for (p=m; *p; p++) *p = tolower(*p);
985
986 // cheap hack because SCRIPT_GetNumber doesn't like the slashes
987 p = m;
988 while (*p == '/') p++;
989
990 return p;
991 }
992
993 static void CONFIG_GetMD4EntryName(char m[], uint8_t const * const md4)
994 {
995 sprintf(m, "MD4_%08x%08x%08x%08x",
996 B_BIG32(B_UNBUF32(&md4[0])), B_BIG32(B_UNBUF32(&md4[4])),
997 B_BIG32(B_UNBUF32(&md4[8])), B_BIG32(B_UNBUF32(&md4[12])));
998 }
999
1000 int32_t CONFIG_GetMapBestTime(char const * const mapname, uint8_t const * const mapmd4)
1001 {
1002 if (!setupread || scripthandle < 0)
1003 return -1;
1004
1005 char m[37];
1006
1007 CONFIG_GetMD4EntryName(m, mapmd4);
1008
1009 int32_t t = -1;
1010 if (SCRIPT_GetNumber(scripthandle, "MapTimes", m, &t))
1011 {
1012 // fall back to map filenames
1013 char m2[BMAX_PATH];
1014 auto p = CONFIG_GetMapEntryName(m2, mapname);
1015
1016 SCRIPT_GetNumber(scripthandle, "MapTimes", p, &t);
1017 }
1018
1019 return t;
1020 }
1021
1022 int CONFIG_SetMapBestTime(uint8_t const * const mapmd4, int32_t tm)
1023 {
1024 if (scripthandle < 0 && (scripthandle = SCRIPT_Init(SetupFilename)) < 0)
1025 return -1;
1026
1027 char m[37];
1028
1029 CONFIG_GetMD4EntryName(m, mapmd4);
1030 SCRIPT_PutNumber(scripthandle, "MapTimes", m, tm, FALSE, FALSE);
1031
1032 return 0;
1033 }
1034
1035 #endif
1036