Skip to content

Commit

Permalink
bugfix: Custom controls would not get loaded when starting from cmd l…
Browse files Browse the repository at this point in the history
…ine (fixes #1355)

When starting Amiberry from the command line, with one of the autoload options, if a config file was found and loaded, the custom controls would never be applied.
When doing the same from the GUI, it worked, but only by accident.

The jports ID was set to -1 by default_prefs for all ports, in the currprefs structure. This didn't apply to changed_prefs, which had the default values of 0 for those fields. When using the GUI, which always applied settings to changed_prefs, it would work by accident since the ID happened to be zero, which also is the first available joystick in the did struct.

Additionally, SDL2 detected a JOYSTICK INSERTED/REMOVED event after startup, which triggered the initialization of joysticks, which in turn loaded the default mapping back on them, overwriting any custom mapping previously loaded.

To fix the above, some refactoring was needed:
- Disabled the detection of JOYSTICK INSERTED/REMOVED during emulation. This is still triggered when the GUI is open.
- Set the first two ports (0 and 1) to their default IDs for Mouse and first Joystick. This is diverging from WinUAE's defaults, but I think it will work out fine for us
- Moved the loading of custom controls outside of cfgfile.cpp and into amiberry_input.cpp, where it belongs. This makes it easier to read, since it's not part of that huge parse_host function.
- Fixed the loading of custom controls to apply to the uae_prefs struct passed into it, instead of always on currprefs, as it was before.
- Added logical checks to ensure the port we're working on is valid (not and id of -1) and within the Joystick ports (value 0-8). We don't want to bother with unmapped ports or mouse ports.
- Some more minor refactoring and cleanup was done around those areas as well.
  • Loading branch information
midwan committed Jun 14, 2024
1 parent 2b03b42 commit 4f96fa1
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 85 deletions.
122 changes: 41 additions & 81 deletions src/cfgfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2241,29 +2241,35 @@ void cfgfile_save_options (struct zfile *f, struct uae_prefs *p, int type)
}
}
#ifdef AMIBERRY
// custom controls SAVING
std::string mode;
std::string buffer;
didata* did = &di_joystick[jp->id - JSEM_JOYS];

// custom options SAVING
const auto host_joy_id = jp->id - JSEM_JOYS;
// skip non-joystick ports
if (host_joy_id < 0 || host_joy_id > MAX_INPUT_DEVICES)
continue;

didata* did = &di_joystick[host_joy_id];

for (int m = 0; m < 2; ++m)
{
mode = (m == 0) ? "none" : "hotkey";
mode = m == 0 ? "none" : "hotkey";
for (int n = 0; n < SDL_CONTROLLER_BUTTON_MAX; ++n) // loop through all buttons
{
buffer = "joyport" + std::to_string(i) + "_amiberry_custom_" + mode + "_" + SDL_GameControllerGetStringForButton(static_cast<SDL_GameControllerButton>(n));
const auto b = (m == 0) ? did->mapping.amiberry_custom_none[n] : did->mapping.amiberry_custom_hotkey[n];
const auto b = m == 0 ? did->mapping.amiberry_custom_none[n] : did->mapping.amiberry_custom_hotkey[n];

_tcscpy(tmp2, (b > 0) ? _T(find_inputevent_name(b)) : _T(""));
_tcscpy(tmp2, b > 0 ? _T(find_inputevent_name(b)) : _T(""));
cfgfile_dwrite_str(f, buffer.c_str(), tmp2);
}

for (int n = 0; n < SDL_CONTROLLER_AXIS_MAX; ++n)
{
buffer = "joyport" + std::to_string(i) + "_amiberry_custom_axis_" + mode + "_" + SDL_GameControllerGetStringForAxis(static_cast<SDL_GameControllerAxis>(n));
const auto b = (m == 0) ? did->mapping.amiberry_custom_axis_none[n] : did->mapping.amiberry_custom_axis_hotkey[n];
const auto b = m == 0 ? did->mapping.amiberry_custom_axis_none[n] : did->mapping.amiberry_custom_axis_hotkey[n];

_tcscpy(tmp2, (b > 0) ? _T(find_inputevent_name(b)) : _T(""));
_tcscpy(tmp2, b > 0 ? _T(find_inputevent_name(b)) : _T(""));
cfgfile_dwrite_str(f, buffer.c_str(), tmp2);
}
}
Expand Down Expand Up @@ -3434,80 +3440,6 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
return 1;
}

#ifdef AMIBERRY
auto option_string = string(option);
// Only do this loop if the option starts with "joyport"
if (option_string.rfind("joyport", 0) == 0)
{
std::string buffer;
std::string mode;
// custom options LOADING
for (i = 0; i < MAX_JPORTS; ++i)
{
const auto host_joy_id = currprefs.jports[i].id - JSEM_JOYS;
didata* did = &di_joystick[host_joy_id];

for (int m = 0; m < 2; ++m)
{
mode = (m == 0) ? "none" : "hotkey";

for (int n = 0; n < SDL_CONTROLLER_BUTTON_MAX; ++n)
{
buffer = "joyport" + std::to_string(i) + "_amiberry_custom_" + mode + "_" + SDL_GameControllerGetStringForButton(static_cast<SDL_GameControllerButton>(n));
if (buffer == option_string)
{
auto b = (find_inputevent(value) > -1) ? remap_event_list[find_inputevent(value)] : 0;

if (m == 0)
did->mapping.amiberry_custom_none[n] = b;
else
did->mapping.amiberry_custom_hotkey[n] = b;

return 1;
}
}

for (int n = 0; n < SDL_CONTROLLER_AXIS_MAX; ++n)
{
buffer = "joyport" + std::to_string(i) + "_amiberry_custom_axis_" + mode + "_" + SDL_GameControllerGetStringForAxis(static_cast<SDL_GameControllerAxis>(n));
if (buffer == option_string)
{
auto b = (find_inputevent(value) > -1) ? remap_event_list[find_inputevent(value)] : 0;

if (m == 0)
did->mapping.amiberry_custom_axis_none[n] = b;
else
did->mapping.amiberry_custom_axis_hotkey[n] = b;

return 1;
}
}
}
}
}

if (option_string.rfind("whdload_", 0) == 0)
{
/* Read in WHDLoad Options */
if (cfgfile_string(option, value, _T("whdload_slave"), whdload_prefs.selected_slave.filename)
|| cfgfile_intval(option, value, _T("whdload_custom1"), &whdload_prefs.selected_slave.custom1.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom2"), &whdload_prefs.selected_slave.custom2.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom3"), &whdload_prefs.selected_slave.custom3.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom4"), &whdload_prefs.selected_slave.custom4.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom5"), &whdload_prefs.selected_slave.custom5.value, 1)
|| cfgfile_string(option, value, _T("whdload_custom"), whdload_prefs.custom)
|| cfgfile_yesno(option, value, _T("whdload_buttonwait"), &whdload_prefs.button_wait)
|| cfgfile_yesno(option, value, _T("whdload_showsplash"), &whdload_prefs.show_splash)
|| cfgfile_intval(option, value, _T("whdload_configdelay"), &whdload_prefs.config_delay, 1)
|| cfgfile_yesno(option, value, _T("whdload_writecache"), &whdload_prefs.write_cache)
|| cfgfile_yesno(option, value, _T("whdload_quit_on_exit"), &whdload_prefs.quit_on_exit)
)
{
return 1;
}
}
#endif

for (tmpp = option; *tmpp != '\0'; tmpp++)
if (_istupper (*tmpp))
*tmpp = _totlower (*tmpp);
Expand Down Expand Up @@ -4670,6 +4602,34 @@ static int cfgfile_parse_host (struct uae_prefs *p, TCHAR *option, TCHAR *value)
}
#endif

#ifdef AMIBERRY
auto option_string = string(option);

if (load_custom_options(p, option_string, value))
return 1;

if (option_string.rfind("whdload_", 0) == 0)
{
/* Read in WHDLoad Options */
if (cfgfile_string(option, value, _T("whdload_slave"), whdload_prefs.selected_slave.filename)
|| cfgfile_intval(option, value, _T("whdload_custom1"), &whdload_prefs.selected_slave.custom1.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom2"), &whdload_prefs.selected_slave.custom2.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom3"), &whdload_prefs.selected_slave.custom3.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom4"), &whdload_prefs.selected_slave.custom4.value, 1)
|| cfgfile_intval(option, value, _T("whdload_custom5"), &whdload_prefs.selected_slave.custom5.value, 1)
|| cfgfile_string(option, value, _T("whdload_custom"), whdload_prefs.custom)
|| cfgfile_yesno(option, value, _T("whdload_buttonwait"), &whdload_prefs.button_wait)
|| cfgfile_yesno(option, value, _T("whdload_showsplash"), &whdload_prefs.show_splash)
|| cfgfile_intval(option, value, _T("whdload_configdelay"), &whdload_prefs.config_delay, 1)
|| cfgfile_yesno(option, value, _T("whdload_writecache"), &whdload_prefs.write_cache)
|| cfgfile_yesno(option, value, _T("whdload_quit_on_exit"), &whdload_prefs.quit_on_exit)
)
{
return 1;
}
}
#endif

return 0;
}

Expand Down
7 changes: 6 additions & 1 deletion src/osdep/amiberry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,8 @@ void process_event(const SDL_Event& event)

case SDL_JOYDEVICEADDED:
case SDL_JOYDEVICEREMOVED:
handle_joy_device_event();
// Disable this for now, as it forces a re-import of joysticks which will reset the controller mappings
//handle_joy_device_event();
break;

case SDL_CONTROLLERBUTTONDOWN:
Expand Down Expand Up @@ -2317,6 +2318,10 @@ void target_default_options(struct uae_prefs* p, int type)
p->use_retroarch_reset = amiberry_options.default_retroarch_reset;
p->use_retroarch_vkbd = amiberry_options.default_retroarch_vkbd;

// Default IDs for ports 0 and 1: Mouse and first joystick
p->jports[0].id = JSEM_MICE;
p->jports[1].id = JSEM_JOYS;

whdload_prefs.button_wait = amiberry_options.default_whd_buttonwait;
whdload_prefs.show_splash = amiberry_options.default_whd_showsplash;
whdload_prefs.config_delay = amiberry_options.default_whd_configdelay;
Expand Down
53 changes: 53 additions & 0 deletions src/osdep/amiberry_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,59 @@ static int init_joystick()
return 1;
}

bool load_custom_options(const uae_prefs* p, const std::string& option, const TCHAR* value)
{
// Only do this loop if the option starts with "joyport"
if (option.rfind("joyport", 0) == 0)
{
std::string buffer;

for (int i = 0; i < MAX_JPORTS; ++i)
{
const auto host_joy_id = p->jports[i].id - JSEM_JOYS;
// skip non-joystick ports
if (host_joy_id < 0 || host_joy_id > MAX_INPUT_DEVICES)
continue;

didata* did = &di_joystick[host_joy_id];

for (int m = 0; m < 2; ++m)
{
std::string mode = m == 0 ? "none" : "hotkey";
for (int n = 0; n < SDL_CONTROLLER_BUTTON_MAX; ++n)
{
buffer = "joyport" + std::to_string(i) + "_amiberry_custom_" + mode + "_" + SDL_GameControllerGetStringForButton(static_cast<SDL_GameControllerButton>(n));
if (buffer == option)
{
const auto b = (find_inputevent(value) > -1) ? remap_event_list[find_inputevent(value)] : 0;
if (m == 0)
did->mapping.amiberry_custom_none[n] = b;
else
did->mapping.amiberry_custom_hotkey[n] = b;
return true;
}
}

for (int n = 0; n < SDL_CONTROLLER_AXIS_MAX; ++n)
{
buffer = "joyport" + std::to_string(i) + "_amiberry_custom_axis_" + mode + "_" + SDL_GameControllerGetStringForAxis(static_cast<SDL_GameControllerAxis>(n));
if (buffer == option)
{
const auto b = (find_inputevent(value) > -1) ? remap_event_list[find_inputevent(value)] : 0;
if (m == 0)
did->mapping.amiberry_custom_axis_none[n] = b;
else
did->mapping.amiberry_custom_axis_hotkey[n] = b;
return true;
}
}
}
}
}

return false;
}

void import_joysticks()
{
joystick_inited = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/osdep/amiberry_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,5 @@ extern void read_controller_axis(int id, int axis, int value);

extern void save_controller_mapping_to_file(const controller_mapping& input, const std::string& filename);
extern void read_controller_mapping_from_file(controller_mapping& input, const std::string& filename);

extern bool load_custom_options(const uae_prefs* p, const std::string& option, const TCHAR* value);
6 changes: 3 additions & 3 deletions src/osdep/amiberry_whdbooter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,7 @@ void cd_auto_prefs(uae_prefs* prefs, char* filepath)
if (std::filesystem::exists(uae_config))
{
target_cfgfile_load(prefs, uae_config.c_str(), CONFIG_TYPE_DEFAULT, 0);
config_loaded = true;
return;
}

Expand Down Expand Up @@ -1180,7 +1181,6 @@ void set_booter_drives(uae_prefs* prefs, const char* filepath)

void whdload_auto_prefs(uae_prefs* prefs, const char* filepath)
{
bool custom_config_loaded = false;
write_log("WHDBooter Launched\n");

if (lstAvailableROMs.empty())
Expand Down Expand Up @@ -1242,7 +1242,7 @@ void whdload_auto_prefs(uae_prefs* prefs, const char* filepath)
{
write_log("WHDBooter - %s found. Loading Config for WHDLoad options.\n", uae_config.c_str());
target_cfgfile_load(prefs, uae_config.c_str(), CONFIG_TYPE_DEFAULT, 0);
custom_config_loaded = true;
config_loaded = true;
}

// If we have a slave, create a startup-sequence
Expand Down Expand Up @@ -1307,7 +1307,7 @@ void whdload_auto_prefs(uae_prefs* prefs, const char* filepath)
#endif

// if we already loaded a .uae config, we don't need to do the below manual setup for hardware
if (custom_config_loaded)
if (config_loaded)
{
write_log("WHDBooter - %s found; ignoring WHD Quickstart setup.\n", uae_config.c_str());
return;
Expand Down

0 comments on commit 4f96fa1

Please sign in to comment.