//------------------------------------------------------------------------- /* Copyright (C) 2016 EDuke32 developers and contributors This file is part of EDuke32. EDuke32 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //------------------------------------------------------------------------- #include "duke3d.h" #include "scriplib.h" #include "osdcmds.h" #include "renderlayer.h" #include "cmdline.h" #include "vfs.h" #ifdef __ANDROID__ # include "android.h" #endif #if defined RENDERTYPESDL && defined SDL_TARGET && SDL_TARGET > 1 # include "sdl_inc.h" #endif // we load this in to get default button and key assignments // as well as setting up function mappings #define __SETUP__ // JBF 20031211 #include "_functio.h" hashtable_t h_gamefuncs = { NUMGAMEFUNCTIONS<<1, NULL }; int32_t CONFIG_FunctionNameToNum(const char *func) { if (!func) return -1; return hash_findcase(&h_gamefuncs, func); } char *CONFIG_FunctionNumToName(int32_t func) { if ((unsigned)func >= (unsigned)NUMGAMEFUNCTIONS) return NULL; return gamefunctions[func]; } int32_t CONFIG_AnalogNameToNum(const char *func) { if (!func) return -1; else if (!Bstrcasecmp(func, "analog_turning")) return analog_turning; else if (!Bstrcasecmp(func, "analog_strafing")) return analog_strafing; else if (!Bstrcasecmp(func, "analog_moving")) return analog_moving; else if (!Bstrcasecmp(func, "analog_lookingupanddown")) return analog_lookingupanddown; else return -1; } const char *CONFIG_AnalogNumToName(int32_t func) { switch (func) { case analog_turning: return "analog_turning"; case analog_strafing: return "analog_strafing"; case analog_moving: return "analog_moving"; case analog_lookingupanddown: return "analog_lookingupanddown"; } return NULL; } void CONFIG_SetDefaultKeys(const char (*keyptr)[MAXGAMEFUNCLEN], bool lazy/*=false*/) { static char const s_gamefunc_[] = "gamefunc_"; int constexpr strlen_gamefunc_ = ARRAY_SIZE(s_gamefunc_) - 1; if (!lazy) { Bmemset(ud.config.KeyboardKeys, 0xff, sizeof(ud.config.KeyboardKeys)); CONTROL_ClearAllBinds(); } for (int i=0; i < ARRAY_SSIZE(gamefunctions); ++i) { if (gamefunctions[i][0] == '\0') continue; auto &key = ud.config.KeyboardKeys[i]; int const default0 = KB_StringToScanCode(keyptr[i<<1]); int const default1 = KB_StringToScanCode(keyptr[(i<<1)+1]); // skip the function if the default key is already used // or the function is assigned to another key if (lazy && (key[0] != 0xff || (CONTROL_KeyIsBound(default0) && Bstrlen(CONTROL_KeyBinds[default0].cmdstr) > strlen_gamefunc_ && CONFIG_FunctionNameToNum(CONTROL_KeyBinds[default0].cmdstr + strlen_gamefunc_) >= 0))) { #if 0 // defined(DEBUGGINGAIDS) if (key[0] != 0xff) initprintf("Skipping %s bound to %s\n", keyptr[i<<1], CONTROL_KeyBinds[default0].cmdstr); #endif continue; } key[0] = default0; key[1] = default1; if (key[0]) CONTROL_FreeKeyBind(key[0]); if (key[1]) CONTROL_FreeKeyBind(key[1]); if (i == gamefunc_Show_Console) OSD_CaptureKey(key[0]); else CONFIG_MapKey(i, key[0], 0, key[1], 0); } } void CONFIG_SetDefaults(void) { ud.config.scripthandle = -1; #ifdef __ANDROID__ droidinput.forward_sens = 5.f; droidinput.gameControlsAlpha = 0.5; droidinput.hideStick = 0; droidinput.pitch_sens = 5.f; droidinput.quickSelectWeapon = 1; droidinput.strafe_sens = 5.f; droidinput.toggleCrouch = 1; droidinput.yaw_sens = 5.f; ud.setup.xdim = droidinfo.screen_width; ud.setup.ydim = droidinfo.screen_height; #else # if defined RENDERTYPESDL && SDL_MAJOR_VERSION > 1 uint32_t inited = SDL_WasInit(SDL_INIT_VIDEO); if (inited == 0) SDL_Init(SDL_INIT_VIDEO); else if (!(inited & SDL_INIT_VIDEO)) SDL_InitSubSystem(SDL_INIT_VIDEO); SDL_DisplayMode dm; if (SDL_GetDesktopDisplayMode(0, &dm) == 0) { ud.setup.xdim = dm.w; ud.setup.ydim = dm.h; } else # endif { ud.setup.xdim = 1024; ud.setup.ydim = 768; } #endif #ifdef USE_OPENGL ud.setup.bpp = 32; #else ud.setup.bpp = 8; #endif #if defined(_WIN32) ud.config.MixRate = 44100; #elif defined __ANDROID__ ud.config.MixRate = droidinfo.audio_sample_rate; #else ud.config.MixRate = 48000; #endif #if defined GEKKO || defined __OPENDINGUX__ ud.config.NumVoices = 32; ud.camera_time = 11; #else ud.config.NumVoices = 64; ud.camera_time = 4; #endif // currently settings.cfg is only read after the startup window launches the game, // and rereading binds might be fickle so just enable this ud.setup.usejoystick = 1; g_myAimMode = 1; g_player[0].ps->aim_mode = 1; ud.setup.forcesetup = 1; ud.setup.noautoload = 1; ud.setup.fullscreen = 1; ud.setup.usemouse = 1; ud.althud = 1; ud.angleinterpolation = 0; ud.auto_run = 1; ud.automsg = 0; ud.autosave = 1; ud.autosavedeletion = 1; ud.autovote = 0; ud.brightness = 8; ud.camerasprite = -1; ud.color = 0; ud.config.AmbienceToggle = 1; ud.config.AutoAim = 1; ud.config.CheckForUpdates = 1; ud.config.FXVolume = 255; ud.config.MouseBias = 0; ud.config.MouseDeadZone = 0; ud.config.MusicToggle = 1; ud.config.MusicVolume = 195; ud.config.NumBits = 16; ud.config.NumChannels = 2; ud.config.ReverseStereo = 0; ud.config.ShowWeapons = 0; ud.config.SmoothInput = 1; ud.config.SoundToggle = 1; ud.config.VoiceToggle = 5; // bitfield, 1 = local, 2 = dummy, 4 = other players in DM ud.config.useprecache = 1; ud.configversion = 0; ud.crosshair = 1; ud.crosshairscale = 50; ud.default_skill = 1; ud.democams = 1; ud.detail = 0; ud.display_bonus_screen = 1; ud.drawweapon = 1; ud.fov = 90; ud.hudontop = 0; ud.idplayers = 1; ud.levelstats = 0; ud.lockout = 0; ud.m_marker = 1; ud.maxautosaves = 5; ud.menu_scrollbartilenum = -1; ud.menu_scrollbarz = 65536; ud.menu_scrollcursorz = 65536; ud.menu_slidebarmargin = 65536; ud.menu_slidebarz = 65536; ud.menu_slidecursorz = 65536; ud.menubackground = 1; ud.mouseaiming = 0; ud.mouseflip = 1; ud.msgdisptime = 120; ud.obituaries = 1; ud.pwlockout[0] = '\0'; ud.runkey_mode = 0; ud.screen_size = 4; ud.screen_tilting = 1; ud.screenfade = 1; ud.shadow_pal = 4; ud.shadows = 1; ud.show_level_text = 1; ud.slidebar_paldisabled = 1; ud.statusbarflags = STATUSBAR_NOSHRINK; ud.statusbarmode = 1; ud.statusbarscale = 100; ud.team = 0; ud.textscale = 200; ud.viewbob = 1; ud.weaponscale = 100; ud.weaponsway = 1; ud.weaponswitch = 3; // new+empty Bstrcpy(ud.rtsname, G_DefaultRtsFile()); Bstrcpy(szPlayerName, "Player"); #ifndef EDUKE32_STANDALONE Bstrcpy(ud.ridecule[0], "An inspiration for birth control."); Bstrcpy(ud.ridecule[1], "You're gonna die for that!"); Bstrcpy(ud.ridecule[2], "It hurts to be you."); Bstrcpy(ud.ridecule[3], "Lucky son of a bitch."); Bstrcpy(ud.ridecule[4], "Hmmm... payback time."); Bstrcpy(ud.ridecule[5], "You bottom dwelling scum sucker."); Bstrcpy(ud.ridecule[6], "Damn, you're ugly."); Bstrcpy(ud.ridecule[7], "Ha ha ha... wasted!"); Bstrcpy(ud.ridecule[8], "You suck!"); Bstrcpy(ud.ridecule[9], "AARRRGHHHHH!!!"); #endif CONFIG_SetDefaultKeys(keydefaults); memset(ud.config.MouseFunctions, -1, sizeof(ud.config.MouseFunctions)); memset(ud.config.MouseDigitalFunctions, -1, sizeof(ud.config.MouseDigitalFunctions)); memset(ud.config.JoystickFunctions, -1, sizeof(ud.config.JoystickFunctions)); memset(ud.config.JoystickDigitalFunctions, -1, sizeof(ud.config.JoystickDigitalFunctions)); CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY; for (int i=0; i=4) continue; ud.config.MouseFunctions[i][1] = CONFIG_FunctionNameToNum(mouseclickeddefaults[i]); CONTROL_MapButton(ud.config.MouseFunctions[i][1], i, 1, controldevice_mouse); } for (int i=0; ii, myconnectindex); } // wrapper for CONTROL_MapKey(), generates key bindings to reflect changes to keyboard setup void CONFIG_MapKey(int which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2) { int const keys[] = { key1, key2, oldkey1, oldkey2 }; char buf[2*MAXGAMEFUNCLEN]; if (which == gamefunc_Show_Console) OSD_CaptureKey(key1); for (int k = 0; (unsigned)k < ARRAY_SIZE(keys); k++) { if (keys[k] == 0xff || !keys[k]) continue; int match = 0; for (; sctokeylut[match].key; match++) { if (keys[k] == sctokeylut[match].sc) break; } tempbuf[0] = 0; for (int i=NUMGAMEFUNCTIONS-1; i>=0; i--) { if (ud.config.KeyboardKeys[i][0] == keys[k] || ud.config.KeyboardKeys[i][1] == keys[k]) { Bsprintf(buf, "gamefunc_%s; ", CONFIG_FunctionNumToName(i)); Bstrcat(tempbuf,buf); } } int const len = Bstrlen(tempbuf); if (len >= 2) { tempbuf[len-2] = 0; // cut off the trailing "; " CONTROL_BindKey(keys[k], tempbuf, 1, sctokeylut[match].key ? sctokeylut[match].key : ""); } else { CONTROL_FreeKeyBind(keys[k]); } } } void CONFIG_SetupMouse(void) { if (ud.config.scripthandle < 0) return; char str[80]; char temp[80]; for (int i=0; i 10) tempbuf[Bstrlen(tempbuf) - 1] = '\0'; Bstrncpyz(szPlayerName, tempbuf, sizeof(szPlayerName)); SCRIPT_GetString(ud.config.scripthandle, "Comm Setup","RTSName",&ud.rtsname[0]); SCRIPT_GetNumber(ud.config.scripthandle, "Setup", "ConfigVersion", &ud.configversion); SCRIPT_GetNumber(ud.config.scripthandle, "Setup", "ForceSetup", &ud.setup.forcesetup); SCRIPT_GetNumber(ud.config.scripthandle, "Setup", "NoAutoLoad", &ud.setup.noautoload); int32_t cachesize; SCRIPT_GetNumber(ud.config.scripthandle, "Setup", "CacheSize", &cachesize); if (cachesize > MAXCACHE1DSIZE) MAXCACHE1DSIZE = cachesize; if (g_noSetup == 0 && g_modDir[0] == '/') { SCRIPT_GetString(ud.config.scripthandle, "Setup","ModDir",&g_modDir[0]); if (!buildvfs_isdir(g_modDir)) { initprintf("Invalid mod dir in cfg!\n"); Bsprintf(g_modDir,"/"); } } if (g_grpNamePtr == NULL && g_addonNum == 0) { SCRIPT_GetStringPtr(ud.config.scripthandle, "Setup", "SelectedGRP", &g_grpNamePtr); if (g_grpNamePtr && !Bstrlen(g_grpNamePtr)) g_grpNamePtr = dup_filename(G_DefaultGrpFile()); } if (!NAM_WW2GI) { SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "Out", &ud.lockout); SCRIPT_GetString(ud.config.scripthandle, "Screen Setup", "Password", &ud.pwlockout[0]); } windowx = -1; windowy = -1; SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "MaxRefreshFreq", (int32_t *)&maxrefreshfreq); SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "ScreenBPP", &ud.setup.bpp); SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "ScreenHeight", &ud.setup.ydim); SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "ScreenMode", &ud.setup.fullscreen); SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "ScreenWidth", &ud.setup.xdim); SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "WindowPosX", (int32_t *)&windowx); SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "WindowPosY", (int32_t *)&windowy); SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "WindowPositioning", (int32_t *)&windowpos); if (ud.setup.bpp < 8) ud.setup.bpp = 32; #ifdef POLYMER int32_t rendmode = 0; SCRIPT_GetNumber(ud.config.scripthandle, "Screen Setup", "Polymer", &rendmode); glrendmode = (rendmode > 0) ? REND_POLYMER : REND_POLYMOST; #endif SCRIPT_GetNumber(ud.config.scripthandle, "Misc", "Executions", &ud.executions); #ifdef _WIN32 SCRIPT_GetNumber(ud.config.scripthandle, "Updates", "CheckForUpdates", &ud.config.CheckForUpdates); SCRIPT_GetNumber(ud.config.scripthandle, "Updates", "LastUpdateCheck", &ud.config.LastUpdateCheck); #endif ud.config.setupread = 1; return 0; } void CONFIG_WriteSettings(void) // save binds and aliases to _settings.cfg { char filename[BMAX_PATH]; if (!Bstrcmp(g_setupFileName, SETUPFILENAME)) Bsprintf(filename, "settings.cfg"); else Bsprintf(filename, "%s_settings.cfg", strtok(g_setupFileName, ".")); buildvfs_FILE fp = buildvfs_fopen_write(filename); if (fp) { buildvfs_fputstr(fp, "// this file is automatically generated by "); buildvfs_fputstrptr(fp, AppProperName); buildvfs_fputstr(fp,"\nunbindall\n"); for (int i=0; i= (MAXMOUSEBUTTONS-2)) continue; if (CONFIG_FunctionNumToName(ud.config.MouseFunctions[i][1])) { Bsprintf(buf, "MouseButtonClicked%d", i); SCRIPT_PutString(ud.config.scripthandle, "Controls", buf, CONFIG_FunctionNumToName(ud.config.MouseFunctions[i][1])); } } for (int i=0; i