#include "compat.h" #include "renderlayer.h" #include "_control.h" #include "build.h" #include "cache1d.h" #include "keyboard.h" #include "control.h" #include "exhumed.h" #include "typedefs.h" #include "scriplib.h" #include "config.h" #include #include #include #include static const char gamefunctions[kMaxGameFunctions][kMaxGameFuncLen] = { "Move_Forward", "Move_Backward", "Turn_Left", "Turn_Right", "Strafe", "Strafe_Left", "Strafe_Right", "Run", "Jump", "Crouch", "Fire", "Open", "Look_Up", "Look_Down", "Look_Straight", "Aim_Up", "Aim_Down", "SendMessage", "Weapon_1", "Weapon_2", "Weapon_3", "Weapon_4", "Weapon_5", "Weapon_6", "Weapon_7", "Mouseview", "Pause", "Map", "Zoom_In", "Zoom_Out", "Gamma_Correction", "Escape", "Shrink_Screen", "Enlarge_Screen", "Inventory", "Inventory_Left", "Inventory_Right", "Mouse_Sensitivity_Up", "Mouse_Sensitivity_Down" "Show_Console", }; static const char keydefaults[kMaxGameFunctions * 2][kMaxGameFuncLen] = { "Up", "Kpad8", "Down", "Kpad2", "Left", "Kpad4", "Right", "KPad6", "LAlt", "RAlt", ",", "", ".", "", "LShift", "RShift", "A", "", "Z", "", "LCtrl", "RCtrl", "Space", "", "PgUp", "", "PgDn", "", "Home", "", "Insert", "", "Delete", "", "T", "", "1", "", "2", "", "3", "", "4", "", "5", "", "6", "", "7", "", "/", "", "Pause", "", "Tab", "", "=", "", "-", "", "F11", "", "Escape", "", "Kpad-", "", "Kpad+", "", "Enter", "", "[", "", "]", "", "F7", "", "F8", "", "`", "", }; static const char *mousedefaults[MAXMOUSEBUTTONS] = { "Fire", "Strafe", "Move_Forward" "", "", "", }; static const char *mouseclickeddefaults[MAXMOUSEBUTTONS] = { }; static const char* mouseanalogdefaults[MAXMOUSEAXES] = { "analog_strafing", "analog_moving", }; static const char* mousedigitaldefaults[MAXMOUSEDIGITAL] = { }; ud_setup_t gSetup; char setupfilename[128] = {kSetupFilename}; int lMouseSens = 32; unsigned int dword_1B82E0 = 0; int32_t FXVolume; int32_t MusicVolume; int32_t MixRate; int32_t MidiPort; int32_t NumVoices; int32_t NumChannels; int32_t NumBits; int32_t ReverseStereo; int32_t MusicDevice; int32_t FXDevice; int32_t ControllerType; int32_t scripthandle; int32_t setupread; // TODO: implement precaching toggle int32_t useprecache; int32_t MouseDeadZone, MouseBias; int32_t SmoothInput; // JBF 20031211: Store the input settings because // (currently) mact can't regurgitate them int32_t MouseFunctions[MAXMOUSEBUTTONS][2]; int32_t MouseDigitalFunctions[MAXMOUSEAXES][2]; int32_t MouseAnalogueAxes[MAXMOUSEAXES]; int32_t MouseAnalogueScale[MAXMOUSEAXES]; int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2]; int32_t JoystickDigitalFunctions[MAXJOYAXES][2]; int32_t JoystickAnalogueAxes[MAXJOYAXES]; int32_t JoystickAnalogueScale[MAXJOYAXES]; int32_t JoystickAnalogueInvert[MAXJOYAXES]; int32_t JoystickAnalogueDead[MAXJOYAXES]; int32_t JoystickAnalogueSaturate[MAXJOYAXES]; uint8_t KeyboardKeys[kMaxGameFunctions][2]; int32_t MAXCACHE1DSIZE = (96*1024*1024); void SetupGameButtons() { CONTROL_DefineFlag(gamefunc_Move_Forward, kFalse); CONTROL_DefineFlag(gamefunc_Move_Backward, kFalse); CONTROL_DefineFlag(gamefunc_Turn_Left, kFalse); CONTROL_DefineFlag(gamefunc_Turn_Right, kFalse); CONTROL_DefineFlag(gamefunc_Strafe, kFalse); CONTROL_DefineFlag(gamefunc_Strafe_Left, kFalse); CONTROL_DefineFlag(gamefunc_Strafe_Right, kFalse); CONTROL_DefineFlag(gamefunc_Jump, kFalse); CONTROL_DefineFlag(gamefunc_Crouch, kFalse); CONTROL_DefineFlag(gamefunc_Fire, kFalse); CONTROL_DefineFlag(gamefunc_Open, kFalse); CONTROL_DefineFlag(gamefunc_Aim_Up, kFalse); CONTROL_DefineFlag(gamefunc_Aim_Down, kFalse); CONTROL_DefineFlag(gamefunc_Look_Up, kFalse); CONTROL_DefineFlag(gamefunc_Look_Down, kFalse); CONTROL_DefineFlag(gamefunc_Look_Straight, kFalse); CONTROL_DefineFlag(gamefunc_Run, kFalse); CONTROL_DefineFlag(gamefunc_SendMessage, kFalse); CONTROL_DefineFlag(gamefunc_Weapon_1, kFalse); CONTROL_DefineFlag(gamefunc_Weapon_2, kFalse); CONTROL_DefineFlag(gamefunc_Weapon_3, kFalse); CONTROL_DefineFlag(gamefunc_Weapon_4, kFalse); CONTROL_DefineFlag(gamefunc_Weapon_5, kFalse); CONTROL_DefineFlag(gamefunc_Weapon_6, kFalse); CONTROL_DefineFlag(gamefunc_Weapon_7, kFalse); CONTROL_DefineFlag(gamefunc_Pause, kFalse); CONTROL_DefineFlag(gamefunc_Map, kFalse); CONTROL_DefineFlag(gamefunc_Gamma_Correction, kFalse); CONTROL_DefineFlag(gamefunc_Escape, kFalse); CONTROL_DefineFlag(gamefunc_Shrink_Screen, kFalse); CONTROL_DefineFlag(gamefunc_Enlarge_Screen, kFalse); CONTROL_DefineFlag(gamefunc_Zoom_In, kFalse); CONTROL_DefineFlag(gamefunc_Zoom_Out, kFalse); CONTROL_DefineFlag(gamefunc_Inventory_Left, kFalse); CONTROL_DefineFlag(gamefunc_Inventory_Right, kFalse); CONTROL_DefineFlag(gamefunc_Mouseview, kFalse); CONTROL_DefineFlag(gamefunc_Inventory, kFalse); CONTROL_DefineFlag(gamefunc_Mouse_Sensitivity_Up, kFalse); CONTROL_DefineFlag(gamefunc_Mouse_Sensitivity_Down, kFalse); } hashtable_t h_gamefuncs = { kMaxGameFunctions<<1, NULL }; int32_t CONFIG_FunctionNameToNum(const char *func) { if (!func) return -1; return hash_findcase(&h_gamefuncs, func); } static char const * CONFIG_FunctionNumToName(int32_t func) { if ((unsigned)func >= (unsigned)kMaxGameFunctions) return ""; 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; } static char const * 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 ""; } static void CONFIG_SetJoystickButtonFunction(int i, int j, int function) { JoystickFunctions[i][j] = function; CONTROL_MapButton(function, i, j, controldevice_joystick); } static void CONFIG_SetJoystickAnalogAxisScale(int i, int scale) { JoystickAnalogueScale[i] = scale; CONTROL_SetAnalogAxisScale(i, scale, controldevice_joystick); } static void CONFIG_SetJoystickAnalogAxisInvert(int i, int invert) { JoystickAnalogueInvert[i] = invert; CONTROL_SetAnalogAxisInvert(i, invert, controldevice_joystick); } static void CONFIG_SetJoystickAnalogAxisDeadSaturate(int i, int dead, int saturate) { JoystickAnalogueDead[i] = dead; JoystickAnalogueSaturate[i] = saturate; joySetDeadZone(i, dead, saturate); } static void CONFIG_SetJoystickDigitalAxisFunction(int i, int j, int function) { JoystickDigitalFunctions[i][j] = function; CONTROL_MapDigitalAxis(i, function, j, controldevice_joystick); } static void CONFIG_SetJoystickAnalogAxisFunction(int i, int function) { JoystickAnalogueAxes[i] = function; CONTROL_MapAnalogAxis(i, function, controldevice_joystick); } void CONFIG_SetDefaultKeys(const char (*keyptr)[kMaxGameFuncLen], bool lazy/*=false*/) { static char const s_gamefunc_[] = "gamefunc_"; int constexpr strlen_gamefunc_ = ARRAY_SIZE(s_gamefunc_) - 1; if (!lazy) { Bmemset(KeyboardKeys, 0xff, sizeof(KeyboardKeys)); CONTROL_ClearAllBinds(); } for (int i=0; i < ARRAY_SSIZE(gamefunctions); ++i) { if (gamefunctions[i][0] == '\0') continue; auto &key = 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() { scripthandle = -1; # 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) { gSetup.xdim = dm.w; gSetup.ydim = dm.h; } else # endif { gSetup.xdim = 1024; gSetup.ydim = 768; } #ifdef USE_OPENGL gSetup.bpp = 32; #else gSetup.bpp = 8; #endif // currently settings.cfg is only read after the startup window launches the game, // and rereading binds might be fickle so just enable this gSetup.usejoystick = 1; gSetup.forcesetup = 1; gSetup.noautoload = 1; gSetup.fullscreen = 1; gSetup.usemouse = 1; MixRate = 44100; FXVolume = 255; MusicVolume = 255; NumChannels = 2; NumBits = 16; NumVoices = 32; mouseaiming = 0; aimmode = 1; mouseflip = 0; runkey_mode = 0; auto_run = 1; CONFIG_SetDefaultKeys(keydefaults); memset(MouseFunctions, -1, sizeof(MouseFunctions)); memset(MouseDigitalFunctions, -1, sizeof(MouseDigitalFunctions)); memset(JoystickFunctions, -1, sizeof(JoystickFunctions)); memset(JoystickDigitalFunctions, -1, sizeof(JoystickDigitalFunctions)); CONTROL_MouseSensitivity = DEFAULTMOUSESENSITIVITY; for (int i=0; i=4) continue; MouseFunctions[i][1] = CONFIG_FunctionNameToNum(mouseclickeddefaults[i]); CONTROL_MapButton(MouseFunctions[i][1], i, 1, controldevice_mouse); } for (int i=0; i MAXCACHE1DSIZE) MAXCACHE1DSIZE = cachesize; if (g_noSetup == 0 && g_modDir[0] == '/') { SCRIPT_GetString(scripthandle, "Setup","ModDir",&g_modDir[0]); if (!buildvfs_isdir(g_modDir)) { initprintf("Invalid mod dir in cfg!\n"); Bsprintf(g_modDir,"/"); } } windowx = -1; windowy = -1; SCRIPT_GetNumber(scripthandle, "Screen Setup", "MaxRefreshFreq", (int32_t *)&maxrefreshfreq); SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenBPP", &gSetup.bpp); SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenHeight", &gSetup.ydim); SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenMode", &gSetup.fullscreen); SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenWidth", &gSetup.xdim); SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosX", (int32_t *)&windowx); SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosY", (int32_t *)&windowy); SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPositioning", (int32_t *)&windowpos); if (gSetup.bpp < 8) gSetup.bpp = 32; setupread = 1; } // 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) { char tempbuf[256]; int const keys[] = { key1, key2, oldkey1, oldkey2 }; char buf[2*kMaxGameFuncLen]; 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 (; match < ARRAY_SSIZE(sctokeylut); ++match) { if (keys[k] == sctokeylut[match].sc) break; } tempbuf[0] = 0; for (int i=kMaxGameFunctions-1; i>=0; i--) { if (KeyboardKeys[i][0] == keys[k] || 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 (scripthandle < 0) return; char str[80]; char temp[80]; for (int i=0; i_settings.cfg { char filename[BMAX_PATH]; if (!Bstrcmp(setupfilename, kSetupFilename)) Bsprintf(filename, "settings.cfg"); else Bsprintf(filename, "%s_settings.cfg", strtok(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(MouseFunctions[i][1])) { Bsprintf(buf, "MouseButtonClicked%d", i); SCRIPT_PutString(scripthandle, "Controls", buf, CONFIG_FunctionNumToName(MouseFunctions[i][1])); } } for (int i=0; i