Skip to content

Commit

Permalink
add hotkeys for changing disks (#425)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jamiras authored Sep 26, 2024
1 parent faf06cf commit d81712a
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 46 deletions.
134 changes: 93 additions & 41 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1656,6 +1656,62 @@ void Application::enableRecent()
}
}

void Application::toggleTray()
{
if (_core.getNumDiscs() > 0)
{
_core.setTrayOpen(!_core.getTrayOpen());
updateDiscMenu(false);

if (_core.getTrayOpen())
{
_video.showMessage(_isDriveFloppy ? "Floppy ejected" : "Disc ejected", 200);
}
else
{
std::string message = "Inserted " + getDiscLabel(_core.getCurrentDiscIndex());
_video.showMessage(message.c_str(), 200);
}
}
}

void Application::readyNextDisc(int offset)
{
const unsigned numDiscs = _core.getNumDiscs();
if (numDiscs > 0)
{
if (_core.getTrayOpen())
readyDisc((_core.getCurrentDiscIndex() + numDiscs + offset) % numDiscs);
else
_video.showMessage(_isDriveFloppy ? "Cannot change floppy until previous floppy ejected" : "Cannot change disc until previous disc ejected", 200);
}
}

void Application::readyDisc(unsigned newDiscIndex)
{
if (_core.getCurrentDiscIndex() != newDiscIndex)
{
std::string path;
if (_core.getDiscPath(newDiscIndex, path))
{
if (!romLoaded(&_core, &_logger, _system, path, NULL, 0, true))
return;
}
else if (newDiscIndex < _discPaths.size())
{
path = util::replaceFileName(_gamePath, _discPaths.at(newDiscIndex).c_str());
if (!romLoaded(&_core, &_logger, _system, path, NULL, 0, true))
return;
}

_core.setCurrentDiscIndex(newDiscIndex);
updateDiscMenu(false);

std::string message = "Readied " + getDiscLabel(newDiscIndex);
_video.showMessage(message.c_str(), 200);
}
}

void Application::updateDiscMenu(bool updateLabels)
{
size_t i = 0;
Expand Down Expand Up @@ -1706,27 +1762,8 @@ void Application::updateDiscMenu(bool updateLabels)

if (updateLabels)
{
if (_core.getDiscLabel(i, discLabel))
{
info.dwTypeData = (char*)discLabel.data();
}
else if (i < _discPaths.size())
{
const std::string& path = _discPaths.at(i);
size_t index = path.find_last_of('\\');
if (index == std::string::npos)
index = path.find_last_of('/');

if (index != std::string::npos)
info.dwTypeData = (LPSTR)&path.at(index + 1);
else
info.dwTypeData = (LPSTR)&path.at(0);
}
else
{
sprintf(buffer, "Disc %d", (int)(i + 1));
info.dwTypeData = buffer;
}
discLabel = getDiscLabel(i);
info.dwTypeData = (char*)discLabel.data();
}

info.fState = (i == selectedDisc) ? MFS_CHECKED : MFS_UNCHECKED;
Expand All @@ -1740,6 +1777,33 @@ void Application::updateDiscMenu(bool updateLabels)
}
}

std::string Application::getDiscLabel(unsigned index) const
{
std::string discLabel;

if (_core.getDiscLabel(index, discLabel))
return discLabel;

if (index < _discPaths.size())
{
const std::string& path = _discPaths.at(index);
size_t lastSlashIndex = path.find_last_of('\\');
if (lastSlashIndex == std::string::npos)
lastSlashIndex = path.find_last_of('/');

if (lastSlashIndex != std::string::npos)
discLabel = path.substr(lastSlashIndex + 1);
else
discLabel = path;
}
else
{
discLabel = "Disc " + index;
}

return discLabel;
}

std::string Application::getStatePath(unsigned ndx)
{
return _states.getStatePath(ndx);
Expand Down Expand Up @@ -2263,8 +2327,7 @@ void Application::handle(const SDL_SysWMEvent* syswm)
}

case IDM_CD_OPEN_TRAY:
_core.setTrayOpen(!_core.getTrayOpen());
updateDiscMenu(false);
toggleTray();
break;

case IDM_PAUSE_GAME:
Expand Down Expand Up @@ -2382,24 +2445,7 @@ void Application::handle(const SDL_SysWMEvent* syswm)
else if (cmd >= IDM_CD_DISC_FIRST && cmd <= IDM_CD_DISC_LAST)
{
unsigned newDiscIndex = cmd - IDM_CD_DISC_FIRST;
if (_core.getCurrentDiscIndex() != newDiscIndex)
{
std::string path;
if (_core.getDiscPath(newDiscIndex, path))
{
if (!romLoaded(&_core, &_logger, _system, path, NULL, 0, true))
break;
}
else if (newDiscIndex < _discPaths.size())
{
path = util::replaceFileName(_gamePath, _discPaths.at(newDiscIndex).c_str());
if (!romLoaded(&_core, &_logger, _system, path, NULL, 0, true))
break;
}

_core.setCurrentDiscIndex(newDiscIndex);
updateDiscMenu(false);
}
readyDisc(newDiscIndex);
}
else if (cmd >= IDM_SYSTEM_FIRST && cmd <= IDM_SYSTEM_LAST)
{
Expand Down Expand Up @@ -2550,6 +2596,11 @@ void Application::handle(const KeyBinds::Action action, unsigned extra)
case KeyBinds::Action::kLoadState: loadState(extra); break;
case KeyBinds::Action::kChangeCurrentState: changeCurrentState(extra); break;

// Disc management
case KeyBinds::Action::kToggleTray: toggleTray(); break;
case KeyBinds::Action::kReadyNextDisc: readyNextDisc(1); break;
case KeyBinds::Action::kReadyPreviousDisc:readyNextDisc(-1); break;

// Window size
case KeyBinds::Action::kSetWindowSize1: resizeWindow(1); break;
case KeyBinds::Action::kSetWindowSize2: resizeWindow(2); break;
Expand Down Expand Up @@ -2621,6 +2672,7 @@ void Application::handle(const KeyBinds::Action action, unsigned extra)
updateMenu();

_video.showMessage(_keybinds.hasGameFocus() ? "Game focus enabled" : "Game focus disabled", 60);
SDL_SetRelativeMouseMode(_keybinds.hasGameFocus() ? SDL_TRUE : SDL_FALSE);
break;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ class Application
void toggleFastForwarding(unsigned extra);
void toggleBackgroundInput();
void setBackgroundInput(bool enabled);
void toggleTray();
void readyNextDisc(int offset);
void readyDisc(unsigned newDiscIndex);
std::string getDiscLabel(unsigned index) const;

Fsm _fsm;
bool lastHardcore;
Expand Down
18 changes: 18 additions & 0 deletions src/KeyBinds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,11 @@ enum
kLoadCurrent,
kSaveCurrent,

// Disc management
kToggleTray,
kReadyNextDisc,
kReadyPreviousDisc,

// Window size
kSetWindowSize1,
kSetWindowSize2,
Expand Down Expand Up @@ -166,6 +171,8 @@ static const char* bindingNames[] = {
"SLOT1", "SLOT2", "SLOT3", "SLOT4", "SLOT5", "SLOT6", "SLOT7", "SLOT8", "SLOT9", "SLOT0",
"LOAD_SLOT", "SAVE_SLOT",

"TRAY_OPEN", "DISK_NEXT", "DISK_PREV",

"WINDOW_1X", "WINDOW_2X", "WINDOW_3X", "WINDOW_4X", "WINDOW_5X",
"TOGGLE_FULLSCREEN", "ROTATE_RIGHT", "ROTATE_LEFT",

Expand Down Expand Up @@ -286,6 +293,9 @@ bool KeyBinds::init(Logger* logger)
_bindings[kToggleFullscreen] = { 0, SDLK_RETURN, Binding::Type::Key, KMOD_ALT };
_bindings[kRotateRight] = { 0, SDLK_r, Binding::Type::Key, KMOD_CTRL };
_bindings[kRotateLeft] = { 0, SDLK_r, Binding::Type::Key, KMOD_CTRL | KMOD_SHIFT };
_bindings[kToggleTray] = { 0, SDLK_MINUS, Binding::Type::Key, KMOD_ALT };
_bindings[kReadyNextDisc] = { 0, SDLK_EQUALS, Binding::Type::Key, KMOD_ALT };
_bindings[kReadyPreviousDisc] = { 0, SDLK_0, Binding::Type::Key, KMOD_ALT };

_bindings[kPauseToggle] = { 0, SDLK_ESCAPE, Binding::Type::Key, 0 };
_bindings[kPauseToggleNoOvl] = { 0, SDLK_p, Binding::Type::Key, 0 };
Expand Down Expand Up @@ -422,6 +432,11 @@ KeyBinds::Action KeyBinds::translateButtonPress(int button, unsigned* extra)
case kLoadCurrent: *extra = _slot; return Action::kLoadState;
case kSaveCurrent: *extra = _slot; return Action::kSaveState;

// Disc management
case kToggleTray: return Action::kToggleTray;
case kReadyNextDisc: return Action::kReadyNextDisc;
case kReadyPreviousDisc: return Action::kReadyPreviousDisc;

// Window size
case kSetWindowSize1: return Action::kSetWindowSize1;
case kSetWindowSize2: return Action::kSetWindowSize2;
Expand Down Expand Up @@ -1494,6 +1509,9 @@ class InputDialog : public Dialog
addButtonInput(4, 0, "Frame Advance", kStep);
addButtonInput(5, 0, "Fast Forward (Hold)", kFastForward);
addButtonInput(6, 0, "Fast Forward (Toggle)", kFastForwardToggle);
addButtonInput(7, 0, "Insert/Eject Disc", kToggleTray);
addButtonInput(8, 0, "Ready Next Disc", kReadyNextDisc);
addButtonInput(9, 0, "Ready Previous Disc", kReadyPreviousDisc);

addButtonInput(0, 2, "Window Size 1x", kSetWindowSize1);
addButtonInput(1, 2, "Window Size 2x", kSetWindowSize2);
Expand Down
7 changes: 6 additions & 1 deletion src/KeyBinds.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ class KeyBinds
kLoadState,
kChangeCurrentState,

// Disc management
kToggleTray,
kReadyNextDisc,
kReadyPreviousDisc,

// Window size
kSetWindowSize1,
kSetWindowSize2,
Expand Down Expand Up @@ -120,7 +125,7 @@ class KeyBinds
Type type;
uint16_t modifiers;
};
typedef std::array<Binding, 98> BindingList;
typedef std::array<Binding, 101> BindingList;

static void getBindingString(char buffer[32], const KeyBinds::Binding& desc);

Expand Down
4 changes: 2 additions & 2 deletions src/libretro/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ bool libretro::Core::setDiskControlExtInterface(const struct retro_disk_control_
return true;
}

bool libretro::Core::getDiscLabel(unsigned index, std::string& label)
bool libretro::Core::getDiscLabel(unsigned index, std::string& label) const
{
if (_diskControlInterface.get_image_label)
{
Expand All @@ -877,7 +877,7 @@ bool libretro::Core::getDiscLabel(unsigned index, std::string& label)
return false;
}

bool libretro::Core::getDiscPath(unsigned index, std::string& path)
bool libretro::Core::getDiscPath(unsigned index, std::string& path) const
{
if (_diskControlInterface.get_image_path)
{
Expand Down
4 changes: 2 additions & 2 deletions src/libretro/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ namespace libretro
inline unsigned getNumDiscs() const { return (_diskControlInterface.get_num_images != NULL) ? _diskControlInterface.get_num_images() : 0; }
inline unsigned getCurrentDiscIndex() const { return (_diskControlInterface.get_image_index != NULL) ? _diskControlInterface.get_image_index() : 0; }
void setCurrentDiscIndex(unsigned index);
bool getDiscLabel(unsigned index, std::string& label);
bool getDiscPath(unsigned index, std::string& path);
bool getDiscLabel(unsigned index, std::string& label) const;
bool getDiscPath(unsigned index, std::string& path) const;
inline bool getTrayOpen() const { return (_diskControlInterface.get_eject_state != NULL) ? (bool)_diskControlInterface.get_eject_state() : false; }
void setTrayOpen(bool open);

Expand Down

0 comments on commit d81712a

Please sign in to comment.