mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
The source of the issue is that the logic for rotating slot options was broken. It would count selectable options and skip over options that were not selectable, except for the specific scenario where the index was zero. I ended up largely replacing the logic to be more C++-ish.
This commit is contained in:
parent
7eacda7e8f
commit
710fc0dbd8
@ -17,6 +17,8 @@
|
||||
#include "emuopts.h"
|
||||
#include "mameopts.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
UTILITY
|
||||
@ -28,46 +30,9 @@ namespace {
|
||||
void *ITEMREF_RESET = ((void *)1);
|
||||
char DIVIDER[] = "------";
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_slot_length
|
||||
//-------------------------------------------------
|
||||
|
||||
int get_slot_length(const device_slot_interface &slot)
|
||||
{
|
||||
int val = 0;
|
||||
for (auto &option : slot.option_list())
|
||||
if (option.second->selectable())
|
||||
val++;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_slot_option
|
||||
//-------------------------------------------------
|
||||
|
||||
const char *get_slot_option(device_slot_interface &slot, int index)
|
||||
{
|
||||
if (index >= 0)
|
||||
{
|
||||
int val = 0;
|
||||
for (auto &option : slot.option_list())
|
||||
{
|
||||
if (val == index)
|
||||
return option.second->name();
|
||||
|
||||
if (option.second->selectable())
|
||||
val++;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
SLOT MENU
|
||||
***************************************************************************/
|
||||
@ -116,69 +81,6 @@ device_slot_option *menu_slot_devices::get_current_option(device_slot_interface
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_current_index
|
||||
//-------------------------------------------------
|
||||
|
||||
int menu_slot_devices::get_current_index(device_slot_interface &slot) const
|
||||
{
|
||||
const device_slot_option *current = get_current_option(slot);
|
||||
|
||||
if (current != nullptr)
|
||||
{
|
||||
int val = 0;
|
||||
for (auto &option : slot.option_list())
|
||||
{
|
||||
if (option.second.get() == current)
|
||||
return val;
|
||||
|
||||
if (option.second->selectable())
|
||||
val++;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_next_slot
|
||||
//-------------------------------------------------
|
||||
|
||||
const char *menu_slot_devices::get_next_slot(device_slot_interface &slot) const
|
||||
{
|
||||
int idx = get_current_index(slot);
|
||||
if (idx < 0)
|
||||
idx = 0;
|
||||
else
|
||||
idx++;
|
||||
|
||||
if (idx >= get_slot_length(slot))
|
||||
return "";
|
||||
|
||||
return get_slot_option(slot, idx);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// get_previous_slot
|
||||
//-------------------------------------------------
|
||||
|
||||
const char *menu_slot_devices::get_previous_slot(device_slot_interface &slot) const
|
||||
{
|
||||
int idx = get_current_index(slot);
|
||||
if (idx < 0)
|
||||
idx = get_slot_length(slot) - 1;
|
||||
else
|
||||
idx--;
|
||||
|
||||
if (idx < 0)
|
||||
return "";
|
||||
|
||||
return get_slot_option(slot, idx);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_slot_device
|
||||
//-------------------------------------------------
|
||||
@ -344,8 +246,7 @@ void menu_slot_devices::handle()
|
||||
else if (menu_event->iptkey == IPT_UI_LEFT || menu_event->iptkey == IPT_UI_RIGHT)
|
||||
{
|
||||
device_slot_interface *slot = (device_slot_interface *)menu_event->itemref;
|
||||
const char *val = (menu_event->iptkey == IPT_UI_LEFT) ? get_previous_slot(*slot) : get_next_slot(*slot);
|
||||
set_slot_device(*slot, val);
|
||||
rotate_slot_device(*slot, menu_event->iptkey == IPT_UI_LEFT ? step_t::PREVIOUS : step_t::NEXT);
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_SELECT)
|
||||
{
|
||||
@ -357,4 +258,69 @@ void menu_slot_devices::handle()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rotate_slot_device - rotates the specified slot
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_slot_devices::rotate_slot_device(device_slot_interface &slot, menu_slot_devices::step_t step)
|
||||
{
|
||||
// first, we need to make sure our cache of options is up to date
|
||||
if (m_current_option_list_slot_tag != slot.device().tag())
|
||||
{
|
||||
device_slot_option *current = get_current_option(slot);
|
||||
|
||||
// build the option list, including the blank option
|
||||
m_current_option_list.clear();
|
||||
m_current_option_list.emplace_back("");
|
||||
for (const auto &ent : slot.option_list())
|
||||
{
|
||||
if (ent.second->selectable())
|
||||
m_current_option_list.emplace_back(ent.second->name());
|
||||
}
|
||||
|
||||
// since the order is indeterminant, we need to sort the options
|
||||
std::sort(m_current_option_list.begin(), m_current_option_list.end());
|
||||
|
||||
// find the current position
|
||||
const char *target = current ? current->name() : "";
|
||||
m_current_option_list_iter = std::find_if(
|
||||
m_current_option_list.begin(),
|
||||
m_current_option_list.end(),
|
||||
[target](const std::string &opt_value)
|
||||
{
|
||||
return opt_value == target;
|
||||
});
|
||||
|
||||
// we expect the above search to succeed, because if an internal
|
||||
// option was selected, the menu item should be disabled
|
||||
assert(m_current_option_list_iter != m_current_option_list.end());
|
||||
|
||||
// we've succeeded; don't do this again
|
||||
m_current_option_list_slot_tag.assign(slot.device().tag());
|
||||
}
|
||||
|
||||
// At this point, the current option list and accompanying iterator should
|
||||
// be good; perform the rotation
|
||||
switch (step)
|
||||
{
|
||||
case step_t::NEXT:
|
||||
m_current_option_list_iter++;
|
||||
if (m_current_option_list_iter == m_current_option_list.end())
|
||||
m_current_option_list_iter = m_current_option_list.begin();
|
||||
break;
|
||||
|
||||
case step_t::PREVIOUS:
|
||||
if (m_current_option_list_iter == m_current_option_list.begin())
|
||||
m_current_option_list_iter = m_current_option_list.end();
|
||||
m_current_option_list_iter--;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw false;
|
||||
}
|
||||
|
||||
set_slot_device(slot, m_current_option_list_iter->c_str());
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -24,21 +24,28 @@ public:
|
||||
virtual ~menu_slot_devices() override;
|
||||
|
||||
private:
|
||||
enum class step_t
|
||||
{
|
||||
NEXT,
|
||||
PREVIOUS
|
||||
};
|
||||
|
||||
virtual void populate(float &customtop, float &custombottom) override;
|
||||
virtual void custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2) override;
|
||||
virtual void handle() override;
|
||||
|
||||
device_slot_option *get_current_option(device_slot_interface &slot) const;
|
||||
int get_current_index(device_slot_interface &slot) const;
|
||||
const char *get_next_slot(device_slot_interface &slot) const;
|
||||
const char *get_previous_slot(device_slot_interface &slot) const;
|
||||
void set_slot_device(device_slot_interface &slot, const char *val);
|
||||
void record_current_options();
|
||||
bool try_refresh_current_options();
|
||||
void rotate_slot_device(device_slot_interface &slot, step_t step);
|
||||
|
||||
// variables
|
||||
std::unique_ptr<machine_config> m_config;
|
||||
std::unordered_map<std::string, std::string> m_slot_options;
|
||||
std::string m_current_option_list_slot_tag;
|
||||
std::vector<std::string> m_current_option_list;
|
||||
std::vector<std::string>::const_iterator m_current_option_list_iter;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
Loading…
Reference in New Issue
Block a user