static void CopyParamCallback(void * context, const char *ParamName, m64p_type ParamType) { SCopySection *pCpyContext = (SCopySection *) context; int paramInt; float paramFloat; char paramString[1024]; // handle the parameter copy depending upon type switch (ParamType) { case M64TYPE_INT: case M64TYPE_BOOL: if (ConfigGetParameter(pCpyContext->pSrc, ParamName, ParamType, ¶mInt, sizeof(int)) == M64ERR_SUCCESS) ConfigSetParameter(pCpyContext->pDst, ParamName, ParamType, ¶mInt); break; case M64TYPE_FLOAT: if (ConfigGetParameter(pCpyContext->pSrc, ParamName, ParamType, ¶mFloat, sizeof(float)) == M64ERR_SUCCESS) ConfigSetParameter(pCpyContext->pDst, ParamName, ParamType, ¶mFloat); break; case M64TYPE_STRING: if (ConfigGetParameter(pCpyContext->pSrc, ParamName, ParamType, paramString, 1024) == M64ERR_SUCCESS) ConfigSetParameter(pCpyContext->pDst, ParamName, ParamType, paramString); break; default: // this should never happen DebugMessage(M64MSG_ERROR, "Unknown source parameter type %i in copy callback", (int) ParamType); return; } }
int main_set_core_defaults(void) { float fConfigParamsVersion; int bSaveConfig = 0, bUpgrade = 0; if (ConfigGetParameter(g_CoreConfig, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "No version number in 'Core' config section. Setting defaults."); ConfigDeleteSection("Core"); ConfigOpenSection("Core", &g_CoreConfig); bSaveConfig = 1; } else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION)) { DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'Core' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION); ConfigDeleteSection("Core"); ConfigOpenSection("Core", &g_CoreConfig); bSaveConfig = 1; } else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f) { float fVersion = (float) CONFIG_PARAM_VERSION; ConfigSetParameter(g_CoreConfig, "Version", M64TYPE_FLOAT, &fVersion); DebugMessage(M64MSG_INFO, "Updating parameter set version in 'Core' config section to %.2f", fVersion); bUpgrade = 1; bSaveConfig = 1; } /* parameters controlling the operation of the core */ ConfigSetDefaultFloat(g_CoreConfig, "Version", (float) CONFIG_PARAM_VERSION, "Mupen64Plus Core config parameter set version number. Please don't change this version number."); ConfigSetDefaultBool(g_CoreConfig, "OnScreenDisplay", 1, "Draw on-screen display if True, otherwise don't draw OSD"); #if defined(DYNAREC) ConfigSetDefaultInt(g_CoreConfig, "R4300Emulator", 2, "Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more"); #else ConfigSetDefaultInt(g_CoreConfig, "R4300Emulator", 1, "Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more"); #endif ConfigSetDefaultBool(g_CoreConfig, "NoCompiledJump", 0, "Disable compiled jump commands in dynamic recompiler (should be set to False) "); ConfigSetDefaultBool(g_CoreConfig, "DisableExtraMem", 0, "Disable 4MB expansion RAM pack. May be necessary for some games"); ConfigSetDefaultBool(g_CoreConfig, "EnableDebugger", 0, "Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support"); ConfigSetDefaultInt(g_CoreConfig, "CountPerOp", 0, "Force number of cycles per emulated instruction."); ConfigSetDefaultBool(g_CoreConfig, "DelaySI", 1, "Delay interrupt after DMA SI read/write"); if (bSaveConfig) ConfigSaveSection("Core"); return 1; }
static int load_controller_config(const char *SectionName, int i, int bIsAutoconfig) { m64p_handle pConfig; char input_str[256], value1_str[16], value2_str[16]; const char *config_ptr; int j; /* Open the configuration section for this controller */ if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName); return 0; } /* Check version number, and if it doesn't match: delete the config section and return with error */ if (!bIsAutoconfig) { float fVersion = 0.0f; if (ConfigGetParameter(pConfig, "version", M64TYPE_FLOAT, &fVersion, sizeof(float)) != M64ERR_SUCCESS) { ConfigDeleteSection(SectionName); return -1; } if (((int) fVersion) != ((int) CONFIG_VERSION)) { DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in config section '%s': current is %.2f. Clearing.", fVersion, SectionName, (float) CONFIG_VERSION); ConfigDeleteSection(SectionName); return -1; } } /* check for the required parameters */ if (ConfigGetParameter(pConfig, "plugged", M64TYPE_BOOL, &controller[i].control->Present, sizeof(int)) != M64ERR_SUCCESS) return -1; if (ConfigGetParameter(pConfig, "plugin", M64TYPE_INT, &controller[i].control->Plugin, sizeof(int)) != M64ERR_SUCCESS) return -1; if (ConfigGetParameter(pConfig, "device", M64TYPE_INT, &controller[i].device, sizeof(int)) != M64ERR_SUCCESS) return -1; /* Name validation only applies to stored configurations (not auto-configs) */ if (!bIsAutoconfig) { char device_name[256]; if (ConfigGetParameter(pConfig, "name", M64TYPE_STRING, device_name, 256) != M64ERR_SUCCESS) device_name[0] = 0; if (controller[i].device == DEVICE_NOT_JOYSTICK) { /* do not load automatically generated keyboard config that was stored to disk (prefer any joysticks attached) */ if (strcmp(device_name, "AutoKeyboard") == 0) return -2; } else if (controller[i].device >= 0 && device_name[0] != 0) { /* check that the SDL device name matches the name stored in the config section */ const char *sdl_name = get_sdl_joystick_name(controller[i].device); if (sdl_name == NULL || strncmp(device_name, sdl_name, 255) != 0) { DebugMessage(M64MSG_WARNING, "N64 Controller #%i: SDL joystick name '%s' doesn't match stored configuration name '%s'", i + 1, sdl_name, device_name); return -3; } } } /* then do the optional parameters */ ConfigGetParameter(pConfig, "mouse", M64TYPE_BOOL, &controller[i].mouse, sizeof(int)); if (ConfigGetParameter(pConfig, "MouseSensitivity", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%f,%f", &controller[i].mouse_sens[0], &controller[i].mouse_sens[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in MouseSensitivity parameter for controller %i", i + 1); } if (ConfigGetParameter(pConfig, "AnalogDeadzone", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%i,%i", &controller[i].axis_deadzone[0], &controller[i].axis_deadzone[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in AnalogDeadzone parameter for controller %i", i + 1); } if (ConfigGetParameter(pConfig, "AnalogPeak", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%i,%i", &controller[i].axis_peak[0], &controller[i].axis_peak[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in AnalogPeak parameter for controller %i", i + 1); } /* load configuration for all the digital buttons */ for (j = 0; j < X_AXIS; j++) { if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i button %i", button_names[j], i+1, j); continue; } if ((config_ptr = strstr(input_str, "key")) != NULL) if (sscanf(config_ptr, "key(%i)", (int *) &controller[i].button[j].key) != 1) DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of button '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "button")) != NULL) if (sscanf(config_ptr, "button(%i)", &controller[i].button[j].button) != 1) DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of button '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "axis")) != NULL) { char chAxisDir; if (sscanf(config_ptr, "axis(%d%c,%d", &controller[i].button[j].axis, &chAxisDir, &controller[i].button[j].axis_deadzone) != 3 && sscanf(config_ptr, "axis(%i%c", &controller[i].button[j].axis, &chAxisDir) != 2) DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of button '%s' for controller %i", button_names[j], i + 1); controller[i].button[j].axis_dir = (chAxisDir == '+' ? 1 : (chAxisDir == '-' ? -1 : 0)); } if ((config_ptr = strstr(input_str, "hat")) != NULL) { char *lastchar = NULL; if (sscanf(config_ptr, "hat(%i %15s", &controller[i].button[j].hat, value1_str) != 2) DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of button '%s' for controller %i", button_names[j], i + 1); value1_str[15] = 0; /* chop off the last character of value1_str if it is the closing parenthesis */ lastchar = &value1_str[strlen(value1_str) - 1]; if (lastchar > value1_str && *lastchar == ')') *lastchar = 0; controller[i].button[j].hat_pos = get_hat_pos_by_name(value1_str); } if ((config_ptr = strstr(input_str, "mouse")) != NULL) if (sscanf(config_ptr, "mouse(%i)", &controller[i].button[j].mouse) != 1) DebugMessage(M64MSG_WARNING, "parsing error in mouse() parameter of button '%s' for controller %i", button_names[j], i + 1); } /* load configuration for the 2 analog joystick axes */ for (j = X_AXIS; j <= Y_AXIS; j++) { int axis_idx = j - X_AXIS; if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i axis %i", button_names[j], i+1, axis_idx); continue; } if ((config_ptr = strstr(input_str, "key")) != NULL) if (sscanf(config_ptr, "key(%i,%i)", (int *) &controller[i].axis[axis_idx].key_a, (int *) &controller[i].axis[axis_idx].key_b) != 2) DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of axis '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "button")) != NULL) if (sscanf(config_ptr, "button(%i,%i)", &controller[i].axis[axis_idx].button_a, &controller[i].axis[axis_idx].button_b) != 2) DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of axis '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "axis")) != NULL) { char chAxisDir1, chAxisDir2; if (sscanf(config_ptr, "axis(%i%c,%i%c)", &controller[i].axis[axis_idx].axis_a, &chAxisDir1, &controller[i].axis[axis_idx].axis_b, &chAxisDir2) != 4) DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of axis '%s' for controller %i", button_names[j], i + 1); controller[i].axis[axis_idx].axis_dir_a = (chAxisDir1 == '+' ? 1 : (chAxisDir1 == '-' ? -1 : 0)); controller[i].axis[axis_idx].axis_dir_b = (chAxisDir2 == '+' ? 1 : (chAxisDir2 == '-' ? -1 : 0)); } if ((config_ptr = strstr(input_str, "hat")) != NULL) { char *lastchar = NULL; if (sscanf(config_ptr, "hat(%i %15s %15s", &controller[i].axis[axis_idx].hat, value1_str, value2_str) != 3) DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of axis '%s' for controller %i", button_names[j], i + 1); value1_str[15] = value2_str[15] = 0; /* chop off the last character of value2_str if it is the closing parenthesis */ lastchar = &value2_str[strlen(value2_str) - 1]; if (lastchar > value2_str && *lastchar == ')') *lastchar = 0; controller[i].axis[axis_idx].hat_pos_a = get_hat_pos_by_name(value1_str); controller[i].axis[axis_idx].hat_pos_b = get_hat_pos_by_name(value2_str); } } return 1; }
int event_set_core_defaults(void) { float fConfigParamsVersion; int bSaveConfig = 0; if (ConfigOpenSection("CoreEvents", &l_CoreEventsConfig) != M64ERR_SUCCESS || l_CoreEventsConfig == NULL) { DebugMessage(M64MSG_ERROR, "Failed to open CoreEvents config section."); return 0; /* fail */ } if (ConfigGetParameter(l_CoreEventsConfig, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "No version number in 'CoreEvents' config section. Setting defaults."); ConfigDeleteSection("CoreEvents"); ConfigOpenSection("CoreEvents", &l_CoreEventsConfig); bSaveConfig = 1; } else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION)) { DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'CoreEvents' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION); ConfigDeleteSection("CoreEvents"); ConfigOpenSection("CoreEvents", &l_CoreEventsConfig); bSaveConfig = 1; } else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f) { /* handle upgrades */ float fVersion = CONFIG_PARAM_VERSION; ConfigSetParameter(l_CoreEventsConfig, "Version", M64TYPE_FLOAT, &fVersion); DebugMessage(M64MSG_INFO, "Updating parameter set version in 'CoreEvents' config section to %.2f", fVersion); bSaveConfig = 1; } ConfigSetDefaultFloat(l_CoreEventsConfig, "Version", CONFIG_PARAM_VERSION, "Mupen64Plus CoreEvents config parameter set version number. Please don't change this version number."); /* Keyboard presses mapped to core functions */ ConfigSetDefaultInt(l_CoreEventsConfig, kbdStop, sdl_native2keysym(SDL_SCANCODE_ESCAPE), "SDL keysym for stopping the emulator"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdFullscreen, sdl_native2keysym(SDL_NUM_SCANCODES), "SDL keysym for switching between fullscreen/windowed modes"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdSave, sdl_native2keysym(SDL_SCANCODE_F5), "SDL keysym for saving the emulator state"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdLoad, sdl_native2keysym(SDL_SCANCODE_F7), "SDL keysym for loading the emulator state"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdIncrement, sdl_native2keysym(SDL_SCANCODE_UNKNOWN), "SDL keysym for advancing the save state slot"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdReset, sdl_native2keysym(SDL_SCANCODE_F9), "SDL keysym for resetting the emulator"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdSpeeddown, sdl_native2keysym(SDL_SCANCODE_F10), "SDL keysym for slowing down the emulator"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdSpeedup, sdl_native2keysym(SDL_SCANCODE_F11), "SDL keysym for speeding up the emulator"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdScreenshot, sdl_native2keysym(SDL_SCANCODE_F12), "SDL keysym for taking a screenshot"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdPause, sdl_native2keysym(SDL_SCANCODE_P), "SDL keysym for pausing the emulator"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdMute, sdl_native2keysym(SDL_SCANCODE_M), "SDL keysym for muting/unmuting the sound"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdIncrease, sdl_native2keysym(SDL_SCANCODE_RIGHTBRACKET),"SDL keysym for increasing the volume"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdDecrease, sdl_native2keysym(SDL_SCANCODE_LEFTBRACKET), "SDL keysym for decreasing the volume"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdForward, sdl_native2keysym(SDL_SCANCODE_F), "SDL keysym for temporarily going really fast"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdAdvance, sdl_native2keysym(SDL_SCANCODE_SLASH), "SDL keysym for advancing by one frame when paused"); ConfigSetDefaultInt(l_CoreEventsConfig, kbdGameshark, sdl_native2keysym(SDL_SCANCODE_G), "SDL keysym for pressing the game shark button"); /* Joystick events mapped to core functions */ ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyStop], "", "Joystick event string for stopping the emulator"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyFullscreen], "", "Joystick event string for switching between fullscreen/windowed modes"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joySave], "", "Joystick event string for saving the emulator state"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyLoad], "", "Joystick event string for loading the emulator state"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyIncrement], "", "Joystick event string for advancing the save state slot"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyScreenshot], "", "Joystick event string for taking a screenshot"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyPause], "", "Joystick event string for pausing the emulator"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyMute], "", "Joystick event string for muting/unmuting the sound"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyIncrease], "", "Joystick event string for increasing the volume"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyDecrease], "", "Joystick event string for decreasing the volume"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyForward], "", "Joystick event string for fast-forward"); ConfigSetDefaultString(l_CoreEventsConfig, JoyCmdName[joyGameshark], "", "Joystick event string for pressing the game shark button"); if (bSaveConfig) ConfigSaveSection("CoreEvents"); return 1; }
void load_configuration(int bPreConfig) { char SectionName[32]; int joy_plugged = 0; int n64CtrlIdx, sdlCtrlIdx, j; int sdlNumDevUsed = 0; int sdlDevicesUsed[4]; eModeType OrigControlMode[4], ControlMode[4]; int ControlDevice[4]; char DeviceName[4][256]; int ActiveControllers = 0; int sdlNumJoysticks = get_sdl_num_joysticks(); float fVersion = 0.0f; const char *sdl_name; int ControllersFound = 0; /* tell user how many SDL joysticks are available */ if (!bPreConfig) DebugMessage(M64MSG_INFO, "%i SDL joysticks were found.", sdlNumJoysticks); /* loop through 4 N64 controllers, initializing and validating special section parameters */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { m64p_handle pConfig; /* reset the controller configuration */ clear_controller(n64CtrlIdx); /* Open the configuration section for this controller */ sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { // this should never happen DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'. Aborting...", SectionName); return; } /* Check version number, and if it doesn't match: delete the config section */ fVersion = 0.0f; if (ConfigGetParameter(pConfig, "version", M64TYPE_FLOAT, &fVersion, sizeof(float)) != M64ERR_SUCCESS || ((int) fVersion) != ((int) CONFIG_VERSION)) { DebugMessage(M64MSG_WARNING, "Missing or incompatible config section '%s'. Clearing.", SectionName); ConfigDeleteSection(SectionName); // set local controller default parameters OrigControlMode[n64CtrlIdx] = ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; ControlDevice[n64CtrlIdx] = DEVICE_NO_JOYSTICK; DeviceName[n64CtrlIdx][0] = 0; // write blank config for GUI front-ends init_controller_config(n64CtrlIdx, "", E_MODE_FULL_AUTO); // save it to the file too ConfigSaveSection(SectionName); } else { if (ConfigGetParameter(pConfig, "mode", M64TYPE_INT, &OrigControlMode[n64CtrlIdx], sizeof(int)) != M64ERR_SUCCESS || (int) OrigControlMode[n64CtrlIdx] < 0 || (int) OrigControlMode[n64CtrlIdx] > 2) { if (!bPreConfig) DebugMessage(M64MSG_WARNING, "Missing or invalid 'mode' parameter in config section '%s'. Setting to 2 (Fully Auto)", SectionName); OrigControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; } ControlMode[n64CtrlIdx] = OrigControlMode[n64CtrlIdx]; if (ConfigGetParameter(pConfig, "device", M64TYPE_INT, &ControlDevice[n64CtrlIdx], sizeof(int)) != M64ERR_SUCCESS) { if (!bPreConfig) DebugMessage(M64MSG_WARNING, "Missing 'device' parameter in config section '%s'. Setting to -1 (No joystick)", SectionName); ControlDevice[n64CtrlIdx] = DEVICE_NO_JOYSTICK; } if (ConfigGetParameter(pConfig, "name", M64TYPE_STRING, DeviceName[n64CtrlIdx], 256) != M64ERR_SUCCESS) { DeviceName[n64CtrlIdx][0] = 0; } } } /* loop through 4 N64 controllers and set up those in Fully Manual mode */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { if (ControlMode[n64CtrlIdx] != E_MODE_MANUAL) continue; /* load the stored configuration (disregard any errors) */ sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); load_controller_config(SectionName, n64CtrlIdx, ControlDevice[n64CtrlIdx]); /* if this config uses an SDL joystick, mark it as used */ if (ControlDevice[n64CtrlIdx] == DEVICE_NO_JOYSTICK) { if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using manual config with no SDL joystick (keyboard/mouse only)", n64CtrlIdx+1); } else { sdlDevicesUsed[sdlNumDevUsed++] = ControlDevice[n64CtrlIdx]; if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using manual config for SDL joystick %i", n64CtrlIdx+1, ControlDevice[n64CtrlIdx]); } ActiveControllers++; } /* now loop through again, setting up those in Named Auto mode */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { if (ControlMode[n64CtrlIdx] != E_MODE_NAMED_AUTO) continue; /* if name is empty, then use full auto mode instead */ if (DeviceName[n64CtrlIdx][0] == 0) { ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; continue; } sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); /* if user is looking for a keyboard, set that up */ if (strcasecmp(DeviceName[n64CtrlIdx], "Keyboard") == 0) { auto_set_defaults(DEVICE_NO_JOYSTICK, "Keyboard"); if (load_controller_config("AutoConfig0", n64CtrlIdx, DEVICE_NO_JOYSTICK) > 0) { if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #%i: Using auto-config for keyboard", n64CtrlIdx+1); /* copy the auto-config settings to the controller config section */ auto_copy_inputconfig("AutoConfig0", SectionName, "Keyboard"); ActiveControllers++; ConfigSaveSection(SectionName); } else { DebugMessage(M64MSG_ERROR, "Autoconfig keyboard setup invalid"); } ConfigDeleteSection("AutoConfig0"); continue; } /* search for an unused SDL device with the matching name */ for (sdlCtrlIdx=0; sdlCtrlIdx < sdlNumJoysticks; sdlCtrlIdx++) { /* check if this one is in use */ int deviceAlreadyUsed = 0; for (j = 0; j < sdlNumDevUsed; j++) { if (sdlDevicesUsed[j] == sdlCtrlIdx) deviceAlreadyUsed = 1; } if (deviceAlreadyUsed) continue; /* check if the name matches */ sdl_name = get_sdl_joystick_name(sdlCtrlIdx); if (sdl_name != NULL && strncmp(DeviceName[n64CtrlIdx], sdl_name, 255) == 0) { /* set up one or more controllers for this SDL device, if present in InputAutoConfig.ini */ int ControllersFound = setup_auto_controllers(bPreConfig, n64CtrlIdx, sdlCtrlIdx, sdl_name, ControlMode, OrigControlMode, DeviceName); if (ControllersFound == 0) { // error: no auto-config found for this SDL device DebugMessage(M64MSG_ERROR, "No auto-config found for joystick named '%s' in InputAutoConfig.ini", sdl_name); // mark this device as being used just so we don't complain about it again sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; // quit looking for SDL joysticks which match the name, because there's no valid autoconfig for that name. // this controller will be unused; skip to the next one break; } /* mark this sdl device as used */ sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; ActiveControllers += ControllersFound; break; } } /* if we didn't find a match for this joystick name, then set the controller to fully auto */ if (sdlCtrlIdx == sdlNumJoysticks) { if (!bPreConfig) DebugMessage(M64MSG_WARNING, "N64 Controller #%i: No SDL joystick found matching name '%s'. Using full auto mode.", n64CtrlIdx+1, DeviceName[n64CtrlIdx]); ControlMode[n64CtrlIdx] = E_MODE_FULL_AUTO; } } /* Final loop through N64 controllers, setting up those in Full Auto mode */ for (n64CtrlIdx=0; n64CtrlIdx < 4; n64CtrlIdx++) { if (ControlMode[n64CtrlIdx] != E_MODE_FULL_AUTO) continue; sprintf(SectionName, "Input-SDL-Control%i", n64CtrlIdx + 1); /* search for an unused SDL device */ for (sdlCtrlIdx=0; sdlCtrlIdx < sdlNumJoysticks; sdlCtrlIdx++) { /* check if this one is in use */ int deviceAlreadyUsed = 0; for (j = 0; j < sdlNumDevUsed; j++) { if (sdlDevicesUsed[j] == sdlCtrlIdx) deviceAlreadyUsed = 1; } if (deviceAlreadyUsed) continue; /* set up one or more controllers for this SDL device, if present in InputAutoConfig.ini */ sdl_name = get_sdl_joystick_name(sdlCtrlIdx); ControllersFound = setup_auto_controllers(bPreConfig, n64CtrlIdx, sdlCtrlIdx, sdl_name, ControlMode, OrigControlMode, DeviceName); if (!bPreConfig && ControllersFound == 0) { // error: no auto-config found for this SDL device DebugMessage(M64MSG_ERROR, "No auto-config found for joystick named '%s' in InputAutoConfig.ini", sdl_name); // mark this device as being used just so we don't complain about it again sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; // keep trying more SDL devices to see if we can auto-config one for this N64 controller continue; } /* mark this sdl device as used */ sdlDevicesUsed[sdlNumDevUsed++] = sdlCtrlIdx; ActiveControllers += ControllersFound; break; } /* if this N64 controller was not activated, set device to -1 */ if (sdlCtrlIdx == sdlNumJoysticks) { m64p_handle section; if (ConfigOpenSection(SectionName, §ion) == M64ERR_SUCCESS) { const int iNoDevice = -1; ConfigSetParameter(section, "device", M64TYPE_INT, &iNoDevice); if (OrigControlMode[n64CtrlIdx] == E_MODE_FULL_AUTO) ConfigSetParameter(section, "name", M64TYPE_STRING, ""); ConfigSaveSection(SectionName); } } } /* fallback to keyboard if no controllers were configured */ if (ActiveControllers == 0) { if (!bPreConfig) DebugMessage(M64MSG_INFO, "N64 Controller #1: Forcing default keyboard configuration"); auto_set_defaults(DEVICE_NO_JOYSTICK, "Keyboard"); if (load_controller_config("AutoConfig0", 0, DEVICE_NO_JOYSTICK) > 0) { /* copy the auto-config settings to the controller config section */ if (OrigControlMode[0] == E_MODE_FULL_AUTO) auto_copy_inputconfig("AutoConfig0", "Input-SDL-Control1", "Keyboard"); else auto_copy_inputconfig("AutoConfig0", "Input-SDL-Control1", NULL); // don't overwrite 'name' parameter ActiveControllers++; ConfigSaveSection("Input-SDL-Control1"); } else { DebugMessage(M64MSG_ERROR, "Autoconfig keyboard setup invalid"); } ConfigDeleteSection("AutoConfig0"); } /* see how many joysticks are plugged in */ joy_plugged = 0; for (j = 0; j < 4; j++) { if (controller[j].control->Present) joy_plugged++; } /* print out summary info message */ if (!bPreConfig) { if (joy_plugged > 0) { DebugMessage(M64MSG_INFO, "%i controller(s) found, %i plugged in and usable in the emulator", ActiveControllers, joy_plugged); } else { if (ActiveControllers == 0) DebugMessage(M64MSG_WARNING, "No joysticks/controllers found"); else DebugMessage(M64MSG_WARNING, "%i controllers found, but none were 'plugged in'", ActiveControllers); } } }
static int load_controller_config(const char *SectionName, int i, int sdlDeviceIdx) { m64p_handle pConfig; char input_str[256], value1_str[NUM_BUTTONS], value2_str[NUM_BUTTONS]; const char *config_ptr; int j; /* Open the configuration section for this controller */ if (ConfigOpenSection(SectionName, &pConfig) != M64ERR_SUCCESS) { DebugMessage(M64MSG_ERROR, "Couldn't open config section '%s'", SectionName); return 0; } /* set SDL device number */ controller[i].device = sdlDeviceIdx; /* throw warnings if 'plugged' or 'plugin' are missing */ if (ConfigGetParameter(pConfig, "plugged", M64TYPE_BOOL, &controller[i].control->Present, sizeof(int)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing 'plugged' parameter from config section %s. Setting to 1 (true).", SectionName); controller[i].control->Present = 1; } if (ConfigGetParameter(pConfig, "plugin", M64TYPE_INT, &controller[i].control->Plugin, sizeof(int)) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing 'plugin' parameter from config section %s. Setting to 1 (none).", SectionName); controller[i].control->Plugin = PLUGIN_NONE; } /* load optional parameters */ ConfigGetParameter(pConfig, "mouse", M64TYPE_BOOL, &controller[i].mouse, sizeof(int)); if (ConfigGetParameter(pConfig, "MouseSensitivity", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%f,%f", &controller[i].mouse_sens[0], &controller[i].mouse_sens[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in MouseSensitivity parameter for controller %i", i + 1); } if (ConfigGetParameter(pConfig, "AnalogDeadzone", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%i,%i", &controller[i].axis_deadzone[0], &controller[i].axis_deadzone[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in AnalogDeadzone parameter for controller %i", i + 1); } if (ConfigGetParameter(pConfig, "AnalogPeak", M64TYPE_STRING, input_str, 256) == M64ERR_SUCCESS) { if (sscanf(input_str, "%i,%i", &controller[i].axis_peak[0], &controller[i].axis_peak[1]) != 2) DebugMessage(M64MSG_WARNING, "parsing error in AnalogPeak parameter for controller %i", i + 1); } /* load configuration for all the digital buttons */ for (j = 0; j < X_AXIS; j++) { if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i button %i", button_names[j], i+1, j); continue; } if ((config_ptr = strstr(input_str, "key")) != NULL) if (sscanf(config_ptr, "key(%i)", (int *) &controller[i].button[j].key) != 1) DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of button '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "button")) != NULL) if (sscanf(config_ptr, "button(%i)", &controller[i].button[j].button) != 1) DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of button '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "axis")) != NULL) { char chAxisDir; if (sscanf(config_ptr, "axis(%d%c,%d", &controller[i].button[j].axis, &chAxisDir, &controller[i].button[j].axis_deadzone) != 3 && sscanf(config_ptr, "axis(%i%c", &controller[i].button[j].axis, &chAxisDir) != 2) DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of button '%s' for controller %i", button_names[j], i + 1); controller[i].button[j].axis_dir = (chAxisDir == '+' ? 1 : (chAxisDir == '-' ? -1 : 0)); } if ((config_ptr = strstr(input_str, "hat")) != NULL) { char *lastchar = NULL; if (sscanf(config_ptr, "hat(%i %15s", &controller[i].button[j].hat, value1_str) != 2) DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of button '%s' for controller %i", button_names[j], i + 1); value1_str[15] = 0; /* chop off the last character of value1_str if it is the closing parenthesis */ lastchar = &value1_str[strlen(value1_str) - 1]; if (lastchar > value1_str && *lastchar == ')') *lastchar = 0; controller[i].button[j].hat_pos = get_hat_pos_by_name(value1_str); } if ((config_ptr = strstr(input_str, "mouse")) != NULL) { // check for mouse_pseudo button first if ((config_ptr = strstr(input_str, "mouse_up")) != NULL) {controller[i].button[j].mouse_up=1; controller[i].mouse_up=1;} else if ((config_ptr = strstr(input_str, "mouse_down")) != NULL) {controller[i].button[j].mouse_down=1; controller[i].mouse_down=1;} else if ((config_ptr = strstr(input_str, "mouse_left")) != NULL) {controller[i].button[j].mouse_left=1; controller[i].mouse_left=1;} else if ((config_ptr = strstr(input_str, "mouse_right")) != NULL) {controller[i].button[j].mouse_right=1; controller[i].mouse_right=1;} else if (sscanf(config_ptr, "mouse(%i)", &controller[i].button[j].mouse) != 1) DebugMessage(M64MSG_WARNING, "parsing error in mouse() parameter of button '%s' for controller %i", button_names[j], i + 1); } } /* load configuration for the 2 analog joystick axes */ for (j = X_AXIS; j <= Y_AXIS; j++) { int axis_idx = j - X_AXIS; if (ConfigGetParameter(pConfig, button_names[j], M64TYPE_STRING, input_str, 256) != M64ERR_SUCCESS) { DebugMessage(M64MSG_WARNING, "missing config key '%s' for controller %i axis %i", button_names[j], i+1, axis_idx); continue; } if ((config_ptr = strstr(input_str, "key")) != NULL) if (sscanf(config_ptr, "key(%i,%i)", (int *) &controller[i].axis[axis_idx].key_a, (int *) &controller[i].axis[axis_idx].key_b) != 2) DebugMessage(M64MSG_WARNING, "parsing error in key() parameter of axis '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "button")) != NULL) if (sscanf(config_ptr, "button(%i,%i)", &controller[i].axis[axis_idx].button_a, &controller[i].axis[axis_idx].button_b) != 2) DebugMessage(M64MSG_WARNING, "parsing error in button() parameter of axis '%s' for controller %i", button_names[j], i + 1); if ((config_ptr = strstr(input_str, "axis")) != NULL) { char chAxisDir1, chAxisDir2; if (sscanf(config_ptr, "axis(%i%c,%i%c)", &controller[i].axis[axis_idx].axis_a, &chAxisDir1, &controller[i].axis[axis_idx].axis_b, &chAxisDir2) != 4) DebugMessage(M64MSG_WARNING, "parsing error in axis() parameter of axis '%s' for controller %i", button_names[j], i + 1); controller[i].axis[axis_idx].axis_dir_a = (chAxisDir1 == '+' ? 1 : (chAxisDir1 == '-' ? -1 : 0)); controller[i].axis[axis_idx].axis_dir_b = (chAxisDir2 == '+' ? 1 : (chAxisDir2 == '-' ? -1 : 0)); } if ((config_ptr = strstr(input_str, "hat")) != NULL) { char *lastchar = NULL; if (sscanf(config_ptr, "hat(%i %15s %15s", &controller[i].axis[axis_idx].hat, value1_str, value2_str) != 3) DebugMessage(M64MSG_WARNING, "parsing error in hat() parameter of axis '%s' for controller %i", button_names[j], i + 1); value1_str[15] = value2_str[15] = 0; /* chop off the last character of value2_str if it is the closing parenthesis */ lastchar = &value2_str[strlen(value2_str) - 1]; if (lastchar > value2_str && *lastchar == ')') *lastchar = 0; controller[i].axis[axis_idx].hat_pos_a = get_hat_pos_by_name(value1_str); controller[i].axis[axis_idx].hat_pos_b = get_hat_pos_by_name(value2_str); } } return 1; }