Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions core_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace DBP_Option
menu_time,
menu_transparency,
// Input
map_osd_hotkey,
map_osd,
mouse_input,
mouse_wheel,
Expand Down Expand Up @@ -324,12 +325,32 @@ static retro_core_option_v2_definition option_defs[DBP_Option::_OPTIONS_TOTAL] =
},

// Input
{
"dosbox_pure_menu_action",
"Menu Activation Inputs", NULL,
"Choose whether the DOSBox Pure menu can be opened using the L3 button, Ctrl+Home hotkey, both, or neither.", NULL,
DBP_OptionCat::Input,
{
{ "true", "L3 and Ctrl+Home (default)" },
{ "L3", "L3 button only" },
{ "hotkey", "Ctrl+Home only" },
{ "false", "Off (disable both inputs)" },
},
"true"
},
{
"dosbox_pure_on_screen_keyboard", // legacy name
"Use L3 Button to Show Menu", NULL,
"Always bind the L3 controller button to show the menu to swap CDs/Disks and use the On-Screen Keyboard.", NULL,
"Menu Behavior for L3 Button & Hotkey", NULL,
"Select which menu is opened by the L3 controller button and Ctrl+Home keyboard hotkey." "\n"
"The default setting reopens the previously viewed menu. You can swap CDs/disks on the Start Menu." "\n"
"The On-Screen Keyboard is for controllers and touchscreens. Gamepad Mapper can setup controller mapping.", NULL,
DBP_OptionCat::Input,
{ { "true", "On (Default to Menu)" }, { "keyboard", "On (Default to On-Screen Keyboard)" }, { "false", "Off" } },
{
{ "true", "Open previous menu (default)" },
{ "startmenu", "Always open Start Menu (swap CDs/discs)" },
{ "keyboard", "Always open On-Screen Keyboard" },
{ "mapper", "Always open Gamepad Mapper" },
},
"true"
},
{
Expand Down
74 changes: 72 additions & 2 deletions dosbox_pure_libretro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ static StringToPointerHashMap<void> dbp_vdisk_filter;
static unsigned dbp_image_index;

// DOSBOX INPUT
static bool dbp_hotkey_handled = false;
static char dbp_menu_action[8] = "true";
struct DBP_InputBind
{
Bit8u port, device, index, id;
Expand Down Expand Up @@ -139,6 +141,8 @@ enum DBP_Event_Type : Bit8u
DBPET_JOY2DOWN, DBPET_JOY2UP,
DBPET_KEYDOWN, DBPET_KEYUP,
DBPET_TOGGLEOSD, DBPET_TOGGLEOSDUP,
DBPET_OPENOSD_PREVIOUS, DBPET_OPENOSD_MAIN,
DBPET_OPENOSD_OSK, DBPET_OPENOSD_MAPPER,
DBPET_ACTIONWHEEL, DBPET_ACTIONWHEELUP,
DBPET_SHIFTPORT, DBPET_SHIFTPORTUP,

Expand Down Expand Up @@ -1786,6 +1790,12 @@ void GFX_Events()
static int mouse_joy_x, mouse_joy_y, hatbits;
while (dbp_event_queue_read_cursor != dbp_event_queue_write_cursor)
{
// Read the "Menu Activation Inputs" option and determine which inputs (L3 / Ctrl+Home) are enabled
const char* menu_action = retro_get_variable("dosbox_pure_menu_action", "true");

const bool allow_l3 = (menu_action[0] == 't' || menu_action[0] == 'L'); // "t" = L3 + Ctrl+Home, "L" = L3 only
const bool allow_hotkey = (menu_action[0] == 't' || menu_action[0] == 'h'); // "t" = L3 + Ctrl+Home, "h" = Ctrl+Home only

DBP_Event e = dbp_event_queue[dbp_event_queue_read_cursor];
dbp_event_queue_read_cursor = ((dbp_event_queue_read_cursor + 1) % DBP_EVENT_QUEUE_SIZE);
//log_cb(RETRO_LOG_INFO, "[DOSBOX EVENT] [%4d@%6d] %s %08x%s\n", dbp_framecount, DBP_GetTicks(), (e.type > _DBPET_MAX ? "SPECIAL" : DBP_Event_Type_Names[(int)e.type]), (unsigned)e.val, (dbp_intercept_next ? " [INTERCEPTED]" : ""));
Expand All @@ -1802,8 +1812,23 @@ void GFX_Events()
break;
case DBPET_KEYUP: KEYBOARD_AddKey((KBD_KEYS)e.val, false); break;

case DBPET_TOGGLEOSD: DBP_StartOSD(); break;
case DBPET_TOGGLEOSDUP: break;
case DBPET_TOGGLEOSD:
if (!allow_l3 && e.port < DBP_MAX_PORTS) break;

if (dbp_map_osd == 't') { DBP_QueueEvent(DBPET_OPENOSD_PREVIOUS, e.port, 0); } // Open previous menu (default)
else if (dbp_map_osd == 's') { DBP_QueueEvent(DBPET_OPENOSD_MAIN, e.port, 0); } // Always open Start Menu
else if (dbp_map_osd == 'k') { DBP_QueueEvent(DBPET_OPENOSD_OSK, e.port, 0); } // Always open On-Screen Keyboard
else if (dbp_map_osd == 'm') { DBP_QueueEvent(DBPET_OPENOSD_MAPPER, e.port, 0); } // Always open Gamepad Mapper
break;

case DBPET_TOGGLEOSDUP:
break;

// Ctrl+Home hotkey opens the OSD using the same logic as the L3 button
case DBPET_OPENOSD_MAIN: DBP_StartOSD(DBPOSD_MAIN); break;
case DBPET_OPENOSD_OSK: DBP_StartOSD(DBPOSD_OSK); break;
case DBPET_OPENOSD_MAPPER: DBP_StartOSD(DBPOSD_MAPPER); break;
case DBPET_OPENOSD_PREVIOUS: DBP_StartOSD(_DBPOSD_OPEN); break;

case DBPET_ACTIONWHEEL: DBP_WheelShiftOSD(e.port, true); break;
case DBPET_ACTIONWHEELUP: DBP_WheelShiftOSD(e.port, false); break;
Expand Down Expand Up @@ -2859,6 +2884,13 @@ void retro_init(void) //#3
{
// This can be called from another thread. Hopefully we can get away without a mutex in DBP_QueueEvent.
if (keycode >= RETROK_LAST) return;

// The Home key must be suppressed during Ctrl+Home so that the OSD menu does not receive unintended input
if ((key_modifiers & RETROKMOD_CTRL) && keycode == RETROK_HOME)
{
return;
}

int val = dbp_keymap_retro2dos[keycode];
if (!val) return;
if (down && !dbp_keys_down[val])
Expand Down Expand Up @@ -3408,6 +3440,44 @@ void retro_run(void)
//input_state_cb(0, RETRO_DEVICE_NONE, 0, 0); // poll keys?
//input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_SPACE); // get latest keyboard callbacks?

// This section is for the Ctrl+Home hotkey. It uses the same logic as the L3 button (this way is stable)
const char* hotkey_ctrlhome = DBP_Option::Get(DBP_Option::map_osd_hotkey);
const char* menu_action = retro_get_variable("dosbox_pure_menu_action", "true");

// Determine which inputs (L3 / Ctrl+Home) are enabled
const bool allow_l3 = (menu_action[0] == 't' || menu_action[0] == 'L');
const bool allow_hotkey = (menu_action[0] == 't' || menu_action[0] == 'h');

bool ctrlhome_down = (hotkey_ctrlhome[0] != 'f' &&
(input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_LCTRL) ||
input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_RCTRL)) &&
input_state_cb(0, RETRO_DEVICE_KEYBOARD, 0, RETROK_HOME) );

/* Mark this press as handled so the action only fires once per key-press,
even if the user holds Ctrl+Home or repeatedly spams it */
if (allow_hotkey && ctrlhome_down && !dbp_hotkey_handled)
{
dbp_hotkey_handled = true;
static bool dbp_osd_busy = false; // Guard against entering OSD logic twice in the same press
if (!dbp_osd_busy)
{
dbp_osd_busy = true;
if (dbp_intercept) { DBP_SetIntercept(NULL); }
else {
char mode = hotkey_ctrlhome[0], prev_osd_map = dbp_map_osd; // Store the current L3 setting
dbp_map_osd = mode; // Change the L3 setting to what Ctrl+Home is set to
DBP_QueueEvent(DBPET_TOGGLEOSD, DBP_MAX_PORTS, 0); // Open the OSD using the same logic as L3
dbp_map_osd = prev_osd_map; // Restore original L3 setting
}
dbp_osd_busy = false;
}
}
else if (!ctrlhome_down && dbp_hotkey_handled)
{
dbp_hotkey_handled = false;
DBP_QueueEvent(DBPET_TOGGLEOSDUP, DBP_MAX_PORTS, 0);
}

// query mouse movement before querying mouse buttons
if (dbp_mouse_input != 'f')
{
Expand Down