mirror of
https://github.com/holub/mame
synced 2025-07-02 00:29:37 +03:00
UI refactoring: [Vas Crabb]
* more const where it should be * don't unnecessarily copy big maps * don't make things members when they shouldn't be * get rid of a couple more function statics * move custom render and tab navigate up to base class
This commit is contained in:
parent
200adb341a
commit
ce0162de56
@ -9,11 +9,15 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ui/datfile.h"
|
||||
|
||||
#include "drivenum.h"
|
||||
#include "ui/moptions.h"
|
||||
#include "ui/datfile.h"
|
||||
#include "ui/utils.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace ui {
|
||||
namespace {
|
||||
//-------------------------------------------------
|
||||
@ -59,7 +63,7 @@ std::string datfile_manager::m_story_rev;
|
||||
std::string datfile_manager::m_ginit_rev;
|
||||
bool datfile_manager::first_run = true;
|
||||
|
||||
#define opendatsfile(f) if (parseopen(#f".dat")) { init_##f(); parseclose(); }
|
||||
#define opendatsfile(f) do { fileptr datfile = parseopen(#f".dat"); if (datfile) init_##f(std::move(datfile)); } while (false)
|
||||
|
||||
//-------------------------------------------------
|
||||
// ctor
|
||||
@ -84,10 +88,10 @@ datfile_manager::datfile_manager(running_machine &machine, ui_options &moptions)
|
||||
//-------------------------------------------------
|
||||
// initialize sysinfo.dat index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::init_sysinfo()
|
||||
void datfile_manager::init_sysinfo(fileptr &&fp)
|
||||
{
|
||||
int swcount = 0;
|
||||
auto count = index_datafile(m_sysidx, swcount, m_sysinfo_rev, TAG_SYSINFO_R, '.');
|
||||
auto count = index_datafile(std::move(fp), m_sysidx, swcount, m_sysinfo_rev, TAG_SYSINFO_R, '.');
|
||||
osd_printf_verbose("Sysinfo.dat games found = %i\n", count);
|
||||
osd_printf_verbose("Rev = %s\n", m_sysinfo_rev.c_str());
|
||||
}
|
||||
@ -95,20 +99,20 @@ void datfile_manager::init_sysinfo()
|
||||
//-------------------------------------------------
|
||||
// initialize story.dat index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::init_story()
|
||||
void datfile_manager::init_story(fileptr &&fp)
|
||||
{
|
||||
int swcount = 0;
|
||||
auto count = index_datafile(m_storyidx, swcount, m_story_rev, TAG_STORY_R, 's');
|
||||
auto count = index_datafile(std::move(fp), m_storyidx, swcount, m_story_rev, TAG_STORY_R, 's');
|
||||
osd_printf_verbose("Story.dat games found = %i\n", count);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// initialize history.dat index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::init_history()
|
||||
void datfile_manager::init_history(fileptr &&fp)
|
||||
{
|
||||
int swcount = 0;
|
||||
auto count = index_datafile(m_histidx, swcount, m_history_rev, TAG_HISTORY_R, ' ');
|
||||
auto count = index_datafile(std::move(fp), m_histidx, swcount, m_history_rev, TAG_HISTORY_R, ' ');
|
||||
osd_printf_verbose("History.dat systems found = %i\n", count);
|
||||
osd_printf_verbose("History.dat software packages found = %i\n", swcount);
|
||||
osd_printf_verbose("Rev = %s\n", m_history_rev.c_str());
|
||||
@ -117,11 +121,11 @@ void datfile_manager::init_history()
|
||||
//-------------------------------------------------
|
||||
// initialize gameinit.dat index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::init_gameinit()
|
||||
void datfile_manager::init_gameinit(fileptr &&fp)
|
||||
{
|
||||
int swcount = 0;
|
||||
drvindex tmp;
|
||||
auto count = index_mame_mess_info(m_ginitidx, tmp, swcount);
|
||||
auto count = index_mame_mess_info(std::move(fp), m_ginitidx, tmp, swcount);
|
||||
osd_printf_verbose("Gameinit.dat games found = %i\n", count);
|
||||
osd_printf_verbose("Rev = %s\n", m_ginit_rev.c_str());
|
||||
}
|
||||
@ -129,10 +133,10 @@ void datfile_manager::init_gameinit()
|
||||
//-------------------------------------------------
|
||||
// initialize mameinfo.dat index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::init_mameinfo()
|
||||
void datfile_manager::init_mameinfo(fileptr &&fp)
|
||||
{
|
||||
int drvcount = 0;
|
||||
auto count = index_mame_mess_info(m_mameidx, m_drvidx, drvcount);
|
||||
auto count = index_mame_mess_info(std::move(fp), m_mameidx, m_drvidx, drvcount);
|
||||
osd_printf_verbose("Mameinfo.dat games found = %i\n", count);
|
||||
osd_printf_verbose("Mameinfo.dat drivers found = %d\n", drvcount);
|
||||
osd_printf_verbose("Rev = %s\n", m_mame_rev.c_str());
|
||||
@ -141,10 +145,10 @@ void datfile_manager::init_mameinfo()
|
||||
//-------------------------------------------------
|
||||
// initialize messinfo.dat index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::init_messinfo()
|
||||
void datfile_manager::init_messinfo(fileptr &&fp)
|
||||
{
|
||||
int drvcount = 0;
|
||||
auto count = index_mame_mess_info(m_messidx, m_messdrvidx, drvcount);
|
||||
auto count = index_mame_mess_info(std::move(fp), m_messidx, m_messdrvidx, drvcount);
|
||||
osd_printf_verbose("Messinfo.dat games found = %i\n", count);
|
||||
osd_printf_verbose("Messinfo.dat drivers found = %d\n", drvcount);
|
||||
osd_printf_verbose("Rev = %s\n", m_mess_rev.c_str());
|
||||
@ -153,26 +157,31 @@ void datfile_manager::init_messinfo()
|
||||
//-------------------------------------------------
|
||||
// initialize command.dat index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::init_command()
|
||||
void datfile_manager::init_command(fileptr &&fp)
|
||||
{
|
||||
int swcount = 0;
|
||||
std::string tmp;
|
||||
auto count = index_datafile(m_cmdidx, swcount, tmp, std::string(), 'c');
|
||||
auto count = index_datafile(std::move(fp), m_cmdidx, swcount, tmp, std::string(), 'c');
|
||||
osd_printf_verbose("Command.dat games found = %i\n", count);
|
||||
}
|
||||
|
||||
bool datfile_manager::has_software(std::string const &softlist, std::string const &softname, std::string const &parentname)
|
||||
bool datfile_manager::has_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const
|
||||
{
|
||||
return bool(find_software(softlist, softname, parentname));
|
||||
}
|
||||
|
||||
long const *datfile_manager::find_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const
|
||||
{
|
||||
// Find software in software list index
|
||||
auto const found(m_swindex.find(softlist));
|
||||
if (found == m_swindex.end())
|
||||
return false;
|
||||
auto const software(m_swindex.find(softlist));
|
||||
if (software == m_swindex.end())
|
||||
return nullptr;
|
||||
|
||||
m_itemsiter = found->second.find(softname);
|
||||
if ((m_itemsiter == found->second.end()) && !parentname.empty())
|
||||
m_itemsiter = found->second.find(parentname);
|
||||
auto itemsiter = software->second.find(softname);
|
||||
if ((itemsiter == software->second.end()) && !parentname.empty())
|
||||
itemsiter = software->second.find(parentname);
|
||||
|
||||
return m_itemsiter != found->second.end();
|
||||
return (itemsiter != software->second.end()) ? &itemsiter->second : nullptr;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -180,18 +189,22 @@ bool datfile_manager::has_software(std::string const &softlist, std::string cons
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::load_software_info(std::string const &softlist, std::string &buffer, std::string const &softname, std::string const &parentname)
|
||||
{
|
||||
if (m_swindex.empty())
|
||||
return;
|
||||
|
||||
// Load history text
|
||||
if (!m_swindex.empty() && parseopen("history.dat"))
|
||||
fileptr const datfile = parseopen("history.dat");
|
||||
if (datfile)
|
||||
{
|
||||
// Find software in software list index
|
||||
if (!has_software(softlist, softname, parentname))
|
||||
long const *const s_offset = find_software(softlist, softname, parentname);
|
||||
if (!s_offset)
|
||||
return;
|
||||
|
||||
auto s_offset = m_itemsiter->second;
|
||||
char rbuf[64 * 1024];
|
||||
fseek(fp, s_offset, SEEK_SET);
|
||||
std::fseek(datfile.get(), *s_offset, SEEK_SET);
|
||||
std::string readbuf;
|
||||
while (fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
while (std::fgets(rbuf, 64 * 1024, datfile.get()) != nullptr)
|
||||
{
|
||||
readbuf = chartrimcarriage(rbuf);
|
||||
|
||||
@ -202,7 +215,6 @@ void datfile_manager::load_software_info(std::string const &softlist, std::strin
|
||||
// add this string to the buffer
|
||||
buffer.append(readbuf).append("\n");
|
||||
}
|
||||
parseclose();
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,66 +223,69 @@ void datfile_manager::load_software_info(std::string const &softlist, std::strin
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::load_data_info(const game_driver *drv, std::string &buffer, int type)
|
||||
{
|
||||
dataindex index_idx;
|
||||
drvindex driver_idx;
|
||||
std::string tag, filename;
|
||||
dataindex const *index_idx = nullptr;
|
||||
drvindex const *driver_idx = nullptr;
|
||||
std::string const *tag;
|
||||
std::string filename;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case UI_HISTORY_LOAD:
|
||||
filename = "history.dat";
|
||||
tag = TAG_BIO;
|
||||
index_idx = m_histidx;
|
||||
tag = &TAG_BIO;
|
||||
index_idx = &m_histidx;
|
||||
break;
|
||||
case UI_MAMEINFO_LOAD:
|
||||
filename = "mameinfo.dat";
|
||||
tag = TAG_MAME;
|
||||
index_idx = m_mameidx;
|
||||
driver_idx = m_drvidx;
|
||||
tag = &TAG_MAME;
|
||||
index_idx = &m_mameidx;
|
||||
driver_idx = &m_drvidx;
|
||||
break;
|
||||
case UI_SYSINFO_LOAD:
|
||||
filename = "sysinfo.dat";
|
||||
tag = TAG_BIO;
|
||||
index_idx = m_sysidx;
|
||||
tag = &TAG_BIO;
|
||||
index_idx = &m_sysidx;
|
||||
break;
|
||||
case UI_MESSINFO_LOAD:
|
||||
filename = "messinfo.dat";
|
||||
tag = TAG_MAME;
|
||||
index_idx = m_messidx;
|
||||
driver_idx = m_messdrvidx;
|
||||
tag = &TAG_MAME;
|
||||
index_idx = &m_messidx;
|
||||
driver_idx = &m_messdrvidx;
|
||||
break;
|
||||
case UI_STORY_LOAD:
|
||||
filename = "story.dat";
|
||||
tag = TAG_STORY;
|
||||
index_idx = m_storyidx;
|
||||
tag = &TAG_STORY;
|
||||
index_idx = &m_storyidx;
|
||||
break;
|
||||
case UI_GINIT_LOAD:
|
||||
filename = "gameinit.dat";
|
||||
tag = TAG_MAME;
|
||||
index_idx = m_ginitidx;
|
||||
tag = &TAG_MAME;
|
||||
index_idx = &m_ginitidx;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (parseopen(filename.c_str()))
|
||||
fileptr const datfile = parseopen(filename.c_str());
|
||||
if (datfile)
|
||||
{
|
||||
load_data_text(drv, buffer, index_idx, tag);
|
||||
load_data_text(datfile.get(), drv, buffer, *index_idx, *tag);
|
||||
|
||||
// load driver info
|
||||
if (!driver_idx.empty())
|
||||
load_driver_text(drv, buffer, driver_idx, TAG_DRIVER);
|
||||
if (driver_idx && !driver_idx->empty())
|
||||
load_driver_text(datfile.get(), drv, buffer, *driver_idx, TAG_DRIVER);
|
||||
|
||||
// cleanup mameinfo and sysinfo double line spacing
|
||||
if ((tag == TAG_MAME && type != UI_GINIT_LOAD) || type == UI_SYSINFO_LOAD)
|
||||
if (((*tag == TAG_MAME) && (type != UI_GINIT_LOAD)) || (type == UI_SYSINFO_LOAD))
|
||||
strreplace(buffer, "\n\n", "\n");
|
||||
|
||||
parseclose();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// load a game text into the buffer
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::load_data_text(const game_driver *drv, std::string &buffer, dataindex &idx, std::string const &tag)
|
||||
void datfile_manager::load_data_text(FILE *fp, game_driver const *drv, std::string &buffer, dataindex const &idx, std::string const &tag)
|
||||
{
|
||||
auto itemsiter = idx.find(drv);
|
||||
if (itemsiter == idx.end())
|
||||
@ -288,10 +303,10 @@ void datfile_manager::load_data_text(const game_driver *drv, std::string &buffer
|
||||
}
|
||||
|
||||
auto s_offset = itemsiter->second;
|
||||
fseek(fp, s_offset, SEEK_SET);
|
||||
std::fseek(fp, s_offset, SEEK_SET);
|
||||
char rbuf[64 * 1024];
|
||||
std::string readbuf;
|
||||
while (fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
while (std::fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
{
|
||||
readbuf = chartrimcarriage(rbuf);
|
||||
|
||||
@ -312,7 +327,7 @@ void datfile_manager::load_data_text(const game_driver *drv, std::string &buffer
|
||||
// load a driver name and offset into an
|
||||
// indexed array
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::load_driver_text(const game_driver *drv, std::string &buffer, drvindex &idx, std::string const &tag)
|
||||
void datfile_manager::load_driver_text(FILE *fp, game_driver const *drv, std::string &buffer, drvindex const &idx, std::string const &tag)
|
||||
{
|
||||
std::string s(core_filename_extract_base(drv->source_file));
|
||||
auto index = idx.find(s);
|
||||
@ -323,10 +338,10 @@ void datfile_manager::load_driver_text(const game_driver *drv, std::string &buff
|
||||
|
||||
buffer.append("\n--- DRIVER INFO ---\n").append("Driver: ").append(s).append("\n\n");
|
||||
auto s_offset = index->second;
|
||||
fseek(fp, s_offset, SEEK_SET);
|
||||
std::fseek(fp, s_offset, SEEK_SET);
|
||||
char rbuf[64 * 1024];
|
||||
std::string readbuf;
|
||||
while (fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
while (std::fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
{
|
||||
readbuf = chartrimcarriage(rbuf);
|
||||
|
||||
@ -347,7 +362,7 @@ void datfile_manager::load_driver_text(const game_driver *drv, std::string &buff
|
||||
// load a game name and offset into an
|
||||
// indexed array (mameinfo)
|
||||
//-------------------------------------------------
|
||||
int datfile_manager::index_mame_mess_info(dataindex &index, drvindex &index_drv, int &drvcount)
|
||||
int datfile_manager::index_mame_mess_info(fileptr &&fp, dataindex &index, drvindex &index_drv, int &drvcount)
|
||||
{
|
||||
size_t foundtag;
|
||||
auto t_mame = TAG_MAMEINFO_R.size();
|
||||
@ -357,7 +372,7 @@ int datfile_manager::index_mame_mess_info(dataindex &index, drvindex &index_drv,
|
||||
|
||||
char rbuf[64 * 1024];
|
||||
std::string readbuf, xid, name;
|
||||
while (fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
while (std::fgets(rbuf, 64 * 1024, fp.get()) != nullptr)
|
||||
{
|
||||
readbuf = chartrimcarriage(rbuf);
|
||||
if (m_mame_rev.empty() && readbuf.compare(0, t_mame, TAG_MAMEINFO_R) == 0)
|
||||
@ -378,7 +393,7 @@ int datfile_manager::index_mame_mess_info(dataindex &index, drvindex &index_drv,
|
||||
else if (readbuf.compare(0, t_info, TAG_INFO) == 0)
|
||||
{
|
||||
// TAG_INFO
|
||||
fgets(rbuf, 64 * 1024, fp);
|
||||
std::fgets(rbuf, 64 * 1024, fp.get());
|
||||
xid = chartrimcarriage(rbuf);
|
||||
name = readbuf.substr(t_info + 1);
|
||||
if (xid == TAG_MAME)
|
||||
@ -386,11 +401,11 @@ int datfile_manager::index_mame_mess_info(dataindex &index, drvindex &index_drv,
|
||||
// validate driver
|
||||
auto game_index = driver_list::find(name.c_str());
|
||||
if (game_index != -1)
|
||||
index.emplace(&driver_list::driver(game_index), ftell(fp));
|
||||
index.emplace(&driver_list::driver(game_index), std::ftell(fp.get()));
|
||||
}
|
||||
else if (xid == TAG_DRIVER)
|
||||
{
|
||||
index_drv.emplace(name, ftell(fp));
|
||||
index_drv.emplace(name, std::ftell(fp.get()));
|
||||
drvcount++;
|
||||
}
|
||||
}
|
||||
@ -402,14 +417,14 @@ int datfile_manager::index_mame_mess_info(dataindex &index, drvindex &index_drv,
|
||||
// load a game name and offset into an
|
||||
// indexed array
|
||||
//-------------------------------------------------
|
||||
int datfile_manager::index_datafile(dataindex &index, int &swcount, std::string &rev, std::string const &tag, char sep)
|
||||
int datfile_manager::index_datafile(fileptr &&fp, dataindex &index, int &swcount, std::string &rev, std::string const &tag, char sep)
|
||||
{
|
||||
std::string readbuf;
|
||||
auto const tag_size = tag.size();
|
||||
auto const t_info = TAG_INFO.size();
|
||||
auto const t_bio = TAG_BIO.size();
|
||||
char rbuf[64 * 1024];
|
||||
while (fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
while (std::fgets(rbuf, 64 * 1024, fp.get()) != nullptr)
|
||||
{
|
||||
readbuf = chartrimcarriage(rbuf);
|
||||
|
||||
@ -433,13 +448,13 @@ int datfile_manager::index_datafile(dataindex &index, int &swcount, std::string
|
||||
{
|
||||
auto game_index = driver_list::find(e.c_str());
|
||||
if (game_index != -1)
|
||||
index.emplace(&driver_list::driver(game_index), ftell(fp));
|
||||
index.emplace(&driver_list::driver(game_index), std::ftell(fp.get()));
|
||||
}
|
||||
}
|
||||
else if (!readbuf.empty() && readbuf[0] == DATAFILE_TAG[0])
|
||||
{
|
||||
// search for software info
|
||||
fgets(rbuf, 64 * 1024, fp);
|
||||
std::fgets(rbuf, 64 * 1024, fp.get());
|
||||
std::string readbuf_2(chartrimcarriage(rbuf));
|
||||
if (readbuf_2.compare(0, t_bio, TAG_BIO) == 0)
|
||||
{
|
||||
@ -450,7 +465,7 @@ int datfile_manager::index_datafile(dataindex &index, int &swcount, std::string
|
||||
std::vector<std::string> token_roms = tokenize(s_roms, ',');
|
||||
for (auto & li : token_list)
|
||||
for (auto & ro : token_roms)
|
||||
m_swindex[li].emplace(ro, ftell(fp));
|
||||
m_swindex[li].emplace(ro, std::ftell(fp.get()));
|
||||
swcount++;
|
||||
}
|
||||
}
|
||||
@ -461,25 +476,25 @@ int datfile_manager::index_datafile(dataindex &index, int &swcount, std::string
|
||||
//---------------------------------------------------------
|
||||
// parseopen - Open up file for reading
|
||||
//---------------------------------------------------------
|
||||
bool datfile_manager::parseopen(const char *filename)
|
||||
datfile_manager::fileptr datfile_manager::parseopen(const char *filename)
|
||||
{
|
||||
emu_file file(m_options.history_path(), OPEN_FLAG_READ);
|
||||
if (file.open(filename) != osd_file::error::NONE)
|
||||
return false;
|
||||
return fileptr(nullptr, &std::fclose);
|
||||
|
||||
m_fullpath = file.fullpath();
|
||||
std::string const fullpath = file.fullpath();
|
||||
file.close();
|
||||
fp = fopen(m_fullpath.c_str(), "rb");
|
||||
fileptr result(std::fopen(fullpath.c_str(), "rb"), &std::fclose);
|
||||
|
||||
fgetc(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
return true;
|
||||
fgetc(result.get());
|
||||
fseek(result.get(), 0, SEEK_SET);
|
||||
return result;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// create the menu index
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::index_menuidx(const game_driver *drv, dataindex const &idx, drvindex &index)
|
||||
void datfile_manager::index_menuidx(fileptr &&fp, const game_driver *drv, dataindex const &idx, drvindex &index)
|
||||
{
|
||||
auto itemsiter = idx.find(drv);
|
||||
if (itemsiter == idx.end())
|
||||
@ -495,11 +510,11 @@ void datfile_manager::index_menuidx(const game_driver *drv, dataindex const &idx
|
||||
|
||||
// seek to correct point in datafile
|
||||
auto const s_offset = itemsiter->second;
|
||||
fseek(fp, s_offset, SEEK_SET);
|
||||
std::fseek(fp.get(), s_offset, SEEK_SET);
|
||||
auto const tinfo = TAG_INFO.size();
|
||||
char rbuf[64 * 1024];
|
||||
std::string readbuf;
|
||||
while (fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
while (std::fgets(rbuf, 64 * 1024, fp.get()) != nullptr)
|
||||
{
|
||||
readbuf = chartrimcarriage(rbuf);
|
||||
|
||||
@ -509,9 +524,9 @@ void datfile_manager::index_menuidx(const game_driver *drv, dataindex const &idx
|
||||
// TAG_COMMAND identifies the driver
|
||||
if (readbuf == TAG_COMMAND)
|
||||
{
|
||||
fgets(rbuf, 64 * 1024, fp);
|
||||
std::fgets(rbuf, 64 * 1024, fp.get());
|
||||
chartrimcarriage(rbuf);
|
||||
index.emplace(rbuf, ftell(fp));
|
||||
index.emplace(rbuf, std::ftell(fp.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -519,16 +534,17 @@ void datfile_manager::index_menuidx(const game_driver *drv, dataindex const &idx
|
||||
//-------------------------------------------------
|
||||
// load command text into the buffer
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::load_command_info(std::string &buffer, std::string &sel)
|
||||
void datfile_manager::load_command_info(std::string &buffer, std::string const &sel)
|
||||
{
|
||||
if (parseopen("command.dat"))
|
||||
fileptr const datfile = parseopen("command.dat");
|
||||
if (datfile)
|
||||
{
|
||||
// open and seek to correct point in datafile
|
||||
auto offset = m_menuidx.at(sel);
|
||||
fseek(fp, offset, SEEK_SET);
|
||||
auto const offset = m_menuidx.at(sel);
|
||||
std::fseek(datfile.get(), offset, SEEK_SET);
|
||||
char rbuf[64 * 1024];
|
||||
std::string readbuf;
|
||||
while (fgets(rbuf, 64 * 1024, fp) != nullptr)
|
||||
while (std::fgets(rbuf, 64 * 1024, datfile.get()) != nullptr)
|
||||
{
|
||||
readbuf = chartrimcarriage(rbuf);
|
||||
|
||||
@ -543,7 +559,6 @@ void datfile_manager::load_command_info(std::string &buffer, std::string &sel)
|
||||
// add this string to the buffer
|
||||
buffer.append(readbuf).append("\n");;
|
||||
}
|
||||
parseclose();
|
||||
}
|
||||
}
|
||||
|
||||
@ -552,14 +567,14 @@ void datfile_manager::load_command_info(std::string &buffer, std::string &sel)
|
||||
//-------------------------------------------------
|
||||
void datfile_manager::command_sub_menu(const game_driver *drv, std::vector<std::string> &menuitems)
|
||||
{
|
||||
if (parseopen("command.dat"))
|
||||
fileptr datfile = parseopen("command.dat");
|
||||
if (datfile)
|
||||
{
|
||||
m_menuidx.clear();
|
||||
index_menuidx(drv, m_cmdidx, m_menuidx);
|
||||
index_menuidx(std::move(datfile), drv, m_cmdidx, m_menuidx);
|
||||
menuitems.reserve(m_menuidx.size());
|
||||
for (auto & elem : m_menuidx)
|
||||
for (auto const &elem : m_menuidx)
|
||||
menuitems.push_back(elem.first);
|
||||
parseclose();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
class ui_options;
|
||||
|
||||
namespace ui {
|
||||
@ -33,7 +36,7 @@ public:
|
||||
|
||||
// actions
|
||||
void load_data_info(const game_driver *drv, std::string &buffer, int type);
|
||||
void load_command_info(std::string &buffer, std::string &sel);
|
||||
void load_command_info(std::string &buffer, std::string const &sel);
|
||||
void load_software_info(std::string const &softlist, std::string &buffer, std::string const &softname, std::string const &parentname);
|
||||
void command_sub_menu(const game_driver *drv, std::vector<std::string> &menuitems);
|
||||
void reset_run() { first_run = true; }
|
||||
@ -52,9 +55,7 @@ public:
|
||||
bool has_sysinfo(game_driver const *driver) const { return m_sysidx.find(driver) != m_sysidx.end(); }
|
||||
bool has_story(game_driver const *driver) const { return m_storyidx.find(driver) != m_storyidx.end(); }
|
||||
bool has_gameinit(game_driver const *driver) const { return m_ginitidx.find(driver) != m_ginitidx.end(); }
|
||||
|
||||
// this isn't really just a getter - it affects some internal state
|
||||
bool has_software(std::string const &softlist, std::string const &softname, std::string const &parentname);
|
||||
bool has_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const;
|
||||
|
||||
bool has_data(game_driver const *a = nullptr) const
|
||||
{
|
||||
@ -66,6 +67,7 @@ private:
|
||||
using drvindex = std::unordered_map<std::string, long>;
|
||||
using dataindex = std::unordered_map<const game_driver *, long>;
|
||||
using swindex = std::unordered_map<std::string, drvindex>;
|
||||
using fileptr = std::unique_ptr<FILE, int (*)(FILE *)>;
|
||||
|
||||
// global index
|
||||
static dataindex m_histidx, m_mameidx, m_messidx, m_cmdidx, m_sysidx, m_storyidx, m_ginitidx;
|
||||
@ -73,32 +75,29 @@ private:
|
||||
static swindex m_swindex;
|
||||
|
||||
// internal helpers
|
||||
void init_history();
|
||||
void init_mameinfo();
|
||||
void init_messinfo();
|
||||
void init_command();
|
||||
void init_sysinfo();
|
||||
void init_story();
|
||||
void init_gameinit();
|
||||
void init_history(fileptr &&fp);
|
||||
void init_mameinfo(fileptr &&fp);
|
||||
void init_messinfo(fileptr &&fp);
|
||||
void init_command(fileptr &&fp);
|
||||
void init_sysinfo(fileptr &&fp);
|
||||
void init_story(fileptr &&fp);
|
||||
void init_gameinit(fileptr &&fp);
|
||||
|
||||
// file open/close/seek
|
||||
bool parseopen(const char *filename);
|
||||
void parseclose() { if (fp != nullptr) fclose(fp); }
|
||||
fileptr parseopen(char const *filename);
|
||||
|
||||
int index_mame_mess_info(dataindex &index, drvindex &index_drv, int &drvcount);
|
||||
int index_datafile(dataindex &index, int &swcount, std::string &rev, std::string const &tag, char sep);
|
||||
void index_menuidx(const game_driver *drv, dataindex const &idx, drvindex &index);
|
||||
drvindex::const_iterator m_itemsiter;
|
||||
int index_mame_mess_info(fileptr &&fp, dataindex &index, drvindex &index_drv, int &drvcount);
|
||||
int index_datafile(fileptr &&fp, dataindex &index, int &swcount, std::string &rev, std::string const &tag, char sep);
|
||||
void index_menuidx(fileptr &&fp, game_driver const *drv, dataindex const &idx, drvindex &index);
|
||||
|
||||
void load_data_text(const game_driver *drv, std::string &buffer, dataindex &idx, const std::string &tag);
|
||||
void load_driver_text(const game_driver *drv, std::string &buffer, drvindex &idx, const std::string &tag);
|
||||
long const *find_software(std::string const &softlist, std::string const &softname, std::string const &parentname) const;
|
||||
|
||||
void load_data_text(FILE *fp, game_driver const *drv, std::string &buffer, dataindex const &idx, std::string const &tag);
|
||||
void load_driver_text(FILE *fp, game_driver const *drv, std::string &buffer, drvindex const &idx, std::string const &tag);
|
||||
|
||||
// internal state
|
||||
running_machine &m_machine; // reference to our machine
|
||||
ui_options &m_options;
|
||||
std::string m_fullpath;
|
||||
static std::string m_history_rev, m_mame_rev, m_mess_rev, m_sysinfo_rev, m_story_rev, m_ginit_rev;
|
||||
FILE *fp = nullptr;
|
||||
static bool first_run;
|
||||
};
|
||||
|
||||
|
@ -313,7 +313,7 @@ bool favorite_manager::isgame_favorite(const game_driver *driver)
|
||||
// check if game is already in favorite list
|
||||
//-------------------------------------------------
|
||||
|
||||
bool favorite_manager::isgame_favorite(ui_software_info &swinfo)
|
||||
bool favorite_manager::isgame_favorite(ui_software_info const &swinfo)
|
||||
{
|
||||
for (size_t x = 0; x < m_list.size(); x++)
|
||||
if (m_list[x] == swinfo)
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
#ifndef MAME_FRONTEND_UI_INIFILE_H
|
||||
#define MAME_FRONTEND_UI_INIFILE_H
|
||||
|
||||
#ifndef __UI_INIFILE_H__
|
||||
#define __UI_INIFILE_H__
|
||||
#pragma once
|
||||
|
||||
#include "../frontend/mame/ui/utils.h"
|
||||
|
||||
@ -97,7 +97,7 @@ public:
|
||||
// check
|
||||
bool isgame_favorite();
|
||||
bool isgame_favorite(const game_driver *driver);
|
||||
bool isgame_favorite(ui_software_info &swinfo);
|
||||
bool isgame_favorite(ui_software_info const &swinfo);
|
||||
|
||||
// save
|
||||
void save_favorite_games();
|
||||
@ -120,4 +120,4 @@ private:
|
||||
ui_options &m_options;
|
||||
};
|
||||
|
||||
#endif /* __UI_INIFILE_H__ */
|
||||
#endif // MAME_FRONTEND_UI_INIFILE_H
|
||||
|
@ -37,8 +37,8 @@
|
||||
extern const char UI_VERSION_TAG[];
|
||||
|
||||
namespace ui {
|
||||
static bool first_start = true;
|
||||
static const char *dats_info[] = {
|
||||
namespace {
|
||||
char const *const dats_info[] = {
|
||||
__("General Info"),
|
||||
__("History"),
|
||||
__("Mameinfo"),
|
||||
@ -46,8 +46,12 @@ static const char *dats_info[] = {
|
||||
__("Messinfo"),
|
||||
__("Command"),
|
||||
__("Gameinit"),
|
||||
__("Mamescore") };
|
||||
__("Mamescore")
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
bool menu_select_game::first_start = true;
|
||||
std::vector<const game_driver *> menu_select_game::m_sortedlist;
|
||||
int menu_select_game::m_isabios = 0;
|
||||
|
||||
@ -57,8 +61,11 @@ int menu_select_game::m_isabios = 0;
|
||||
|
||||
menu_select_game::menu_select_game(mame_ui_manager &mui, render_container &container, const char *gamename)
|
||||
: menu_select_launch(mui, container, false)
|
||||
, m_info_buffer()
|
||||
, m_info_driver(nullptr)
|
||||
, m_info_software(nullptr)
|
||||
, m_info_view(-1)
|
||||
{
|
||||
set_focus(focused_menu::main);
|
||||
highlight = 0;
|
||||
std::string error_string, last_filter, sub_filter;
|
||||
ui_options &moptions = mui.options();
|
||||
@ -426,8 +433,9 @@ void menu_select_game::handle()
|
||||
inkey_special(menu_event);
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_UI_CONFIGURE)
|
||||
{
|
||||
inkey_navigation();
|
||||
|
||||
}
|
||||
else if (menu_event->iptkey == IPT_OTHER)
|
||||
{
|
||||
m_prev_selected = nullptr;
|
||||
@ -748,253 +756,6 @@ void menu_select_game::build_available_list()
|
||||
std::stable_sort(m_unavailsortedlist.begin(), m_unavailsortedlist.end(), sorted_game_list);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// perform our special rendering
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_select_game::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
|
||||
{
|
||||
ui_software_info *swinfo = nullptr;
|
||||
float width, maxwidth = origx2 - origx1;
|
||||
std::string tempbuf[5];
|
||||
rgb_t color = UI_BACKGROUND_COLOR;
|
||||
bool isstar = false;
|
||||
inifile_manager &inifile = mame_machine_manager::instance()->inifile();
|
||||
float tbarspace = ui().get_line_height();
|
||||
float text_size = 1.0f;
|
||||
|
||||
tempbuf[0] = string_format(_("%1$s %2$s ( %3$d / %4$d machines (%5$d BIOS) )"),
|
||||
emulator_info::get_appname(),
|
||||
bare_build_version,
|
||||
visible_items,
|
||||
(driver_list::total() - 1),
|
||||
m_isabios);
|
||||
|
||||
std::string filtered;
|
||||
if (main_filters::actual == FILTER_CATEGORY && inifile.total() > 0)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s - %3$s) - "),
|
||||
main_filters::text[main_filters::actual],
|
||||
inifile.get_file(),
|
||||
inifile.get_category());
|
||||
}
|
||||
else if (main_filters::actual == FILTER_MANUFACTURER)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s) - "),
|
||||
main_filters::text[main_filters::actual],
|
||||
c_mnfct::ui[c_mnfct::actual]);
|
||||
}
|
||||
else if (main_filters::actual == FILTER_YEAR)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s) - "),
|
||||
main_filters::text[main_filters::actual],
|
||||
c_year::ui[c_year::actual]);
|
||||
}
|
||||
|
||||
// display the current typeahead
|
||||
if (isfavorite())
|
||||
tempbuf[1].clear();
|
||||
else
|
||||
tempbuf[1] = string_format(_("%1$s Search: %2$s_"), filtered, m_search);
|
||||
|
||||
// get the size of the text
|
||||
for (int line = 0; line < 2; ++line)
|
||||
{
|
||||
ui().draw_text_full(container(), tempbuf[line].c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NONE, rgb_t::white, rgb_t::black, &width, nullptr);
|
||||
width += 2 * UI_BOX_LR_BORDER;
|
||||
maxwidth = MAX(width, maxwidth);
|
||||
}
|
||||
|
||||
if (maxwidth > origx2 - origx1)
|
||||
{
|
||||
text_size = (origx2 - origx1) / maxwidth;
|
||||
maxwidth = origx2 - origx1;
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
float x1 = 0.5f - 0.5f * maxwidth;
|
||||
float x2 = x1 + maxwidth;
|
||||
float y1 = origy1 - top;
|
||||
float y2 = origy1 - 3.0f * UI_BOX_TB_BORDER - tbarspace;
|
||||
|
||||
// draw a box
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
|
||||
|
||||
// take off the borders
|
||||
x1 += UI_BOX_LR_BORDER;
|
||||
x2 -= UI_BOX_LR_BORDER;
|
||||
y1 += UI_BOX_TB_BORDER;
|
||||
|
||||
// draw the text within it
|
||||
for (int line = 0; line < 2; ++line)
|
||||
{
|
||||
ui().draw_text_full(container(), tempbuf[line].c_str(), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
y1 += ui().get_line_height();
|
||||
}
|
||||
|
||||
// determine the text to render below
|
||||
const game_driver *driver = nullptr;
|
||||
if (!isfavorite())
|
||||
{
|
||||
driver = (FPTR(selectedref) > skip_main_items) ? (const game_driver *)selectedref : reinterpret_cast<const game_driver *>(m_prev_selected);
|
||||
}
|
||||
else
|
||||
{
|
||||
swinfo = (FPTR(selectedref) > skip_main_items) ? (ui_software_info *)selectedref : reinterpret_cast<ui_software_info *>(m_prev_selected);
|
||||
if (swinfo != nullptr && swinfo->startempty == 1)
|
||||
driver = swinfo->driver;
|
||||
}
|
||||
|
||||
if (driver)
|
||||
{
|
||||
isstar = mame_machine_manager::instance()->favorite().isgame_favorite(driver);
|
||||
|
||||
// first line is game name
|
||||
tempbuf[0] = string_format(_("Romset: %1$-.100s"), driver->name);
|
||||
|
||||
// next line is year, manufacturer
|
||||
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), driver->year, driver->manufacturer);
|
||||
|
||||
// next line is clone/parent status
|
||||
int cloneof = driver_list::non_bios_clone(*driver);
|
||||
|
||||
if (cloneof != -1)
|
||||
tempbuf[2] = string_format(_("Driver is clone of: %1$-.100s"), driver_list::driver(cloneof).description);
|
||||
else
|
||||
tempbuf[2] = _("Driver is parent");
|
||||
|
||||
// next line is overall driver status
|
||||
if (driver->flags & MACHINE_NOT_WORKING)
|
||||
tempbuf[3] = _("Overall: NOT WORKING");
|
||||
else if (driver->flags & MACHINE_UNEMULATED_PROTECTION)
|
||||
tempbuf[3] = _("Overall: Unemulated Protection");
|
||||
else
|
||||
tempbuf[3] = _("Overall: Working");
|
||||
|
||||
// next line is graphics, sound status
|
||||
if (driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS))
|
||||
tempbuf[4] = _("Graphics: Imperfect, ");
|
||||
else
|
||||
tempbuf[4] = _("Graphics: OK, ");
|
||||
|
||||
if (driver->flags & MACHINE_NO_SOUND)
|
||||
tempbuf[4].append(_("Sound: Unimplemented"));
|
||||
else if (driver->flags & MACHINE_IMPERFECT_SOUND)
|
||||
tempbuf[4].append(_("Sound: Imperfect"));
|
||||
else
|
||||
tempbuf[4].append(_("Sound: OK"));
|
||||
|
||||
color = UI_GREEN_COLOR;
|
||||
|
||||
if ((driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS
|
||||
| MACHINE_NO_SOUND | MACHINE_IMPERFECT_SOUND)) != 0)
|
||||
color = UI_YELLOW_COLOR;
|
||||
|
||||
if ((driver->flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION)) != 0)
|
||||
color = UI_RED_COLOR;
|
||||
}
|
||||
else if (swinfo != nullptr)
|
||||
{
|
||||
isstar = mame_machine_manager::instance()->favorite().isgame_favorite(*swinfo);
|
||||
|
||||
// first line is system
|
||||
tempbuf[0] = string_format(_("System: %1$-.100s"), swinfo->driver->description);
|
||||
|
||||
// next line is year, publisher
|
||||
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), swinfo->year, swinfo->publisher);
|
||||
|
||||
// next line is parent/clone
|
||||
if (!swinfo->parentname.empty())
|
||||
tempbuf[2] = string_format(_("Software is clone of: %1$-.100s"), !swinfo->parentlongname.empty() ? swinfo->parentlongname : swinfo->parentname);
|
||||
else
|
||||
tempbuf[2] = _("Software is parent");
|
||||
|
||||
// next line is supported status
|
||||
if (swinfo->supported == SOFTWARE_SUPPORTED_NO)
|
||||
{
|
||||
tempbuf[3] = _("Supported: No");
|
||||
color = UI_RED_COLOR;
|
||||
}
|
||||
else if (swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL)
|
||||
{
|
||||
tempbuf[3] = _("Supported: Partial");
|
||||
color = UI_YELLOW_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempbuf[3] = _("Supported: Yes");
|
||||
color = UI_GREEN_COLOR;
|
||||
}
|
||||
|
||||
// last line is romset name
|
||||
tempbuf[4] = string_format(_("romset: %1$-.100s"), swinfo->shortname);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string copyright(emulator_info::get_copyright());
|
||||
size_t found = copyright.find("\n");
|
||||
|
||||
tempbuf[0].clear();
|
||||
tempbuf[1] = string_format(_("%1$s %2$s"), emulator_info::get_appname(), build_version);
|
||||
tempbuf[2] = copyright.substr(0, found);
|
||||
tempbuf[3] = copyright.substr(found + 1);
|
||||
tempbuf[4].clear();
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
x1 = 0.5f - 0.5f * maxwidth;
|
||||
x2 = x1 + maxwidth;
|
||||
y1 = y2;
|
||||
y2 = origy1 - UI_BOX_TB_BORDER;
|
||||
|
||||
// draw toolbar
|
||||
draw_toolbar(x1, y1, x2, y2);
|
||||
|
||||
// get the size of the text
|
||||
maxwidth = origx2 - origx1;
|
||||
|
||||
for (auto & elem : tempbuf)
|
||||
{
|
||||
ui().draw_text_full(container(), elem.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NONE, rgb_t::white, rgb_t::black, &width, nullptr);
|
||||
width += 2 * UI_BOX_LR_BORDER;
|
||||
maxwidth = MAX(maxwidth, width);
|
||||
}
|
||||
|
||||
if (maxwidth > origx2 - origx1)
|
||||
{
|
||||
text_size = (origx2 - origx1) / maxwidth;
|
||||
maxwidth = origx2 - origx1;
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
x1 = 0.5f - 0.5f * maxwidth;
|
||||
x2 = x1 + maxwidth;
|
||||
y1 = origy2 + UI_BOX_TB_BORDER;
|
||||
y2 = origy2 + bottom;
|
||||
|
||||
// draw a box
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, color);
|
||||
|
||||
// take off the borders
|
||||
x1 += UI_BOX_LR_BORDER;
|
||||
x2 -= UI_BOX_LR_BORDER;
|
||||
y1 += UI_BOX_TB_BORDER;
|
||||
|
||||
// is favorite? draw the star
|
||||
if (isstar)
|
||||
draw_star(x1, y1);
|
||||
|
||||
// draw all lines
|
||||
for (auto & elem : tempbuf)
|
||||
{
|
||||
ui().draw_text_full(container(), elem.c_str(), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
y1 += ui().get_line_height();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// force the game select menu to be visible
|
||||
@ -1209,7 +970,7 @@ void menu_select_game::inkey_select_favorite(const event *menu_event)
|
||||
// returns if the search can be activated
|
||||
//-------------------------------------------------
|
||||
|
||||
inline bool menu_select_game::isfavorite()
|
||||
inline bool menu_select_game::isfavorite() const
|
||||
{
|
||||
return (main_filters::actual == FILTER_FAVORITE);
|
||||
}
|
||||
@ -1243,73 +1004,6 @@ void menu_select_game::inkey_special(const event *menu_event)
|
||||
}
|
||||
|
||||
|
||||
void menu_select_game::inkey_navigation()
|
||||
{
|
||||
switch (get_focus())
|
||||
{
|
||||
case focused_menu::main:
|
||||
if (selected <= visible_items)
|
||||
{
|
||||
m_prev_selected = item[selected].ref;
|
||||
selected = visible_items + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui_globals::panels_status != HIDE_LEFT_PANEL)
|
||||
set_focus(focused_menu::left);
|
||||
|
||||
else if (ui_globals::panels_status == HIDE_BOTH)
|
||||
{
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
if (item[x].ref == m_prev_selected)
|
||||
selected = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_focus(focused_menu::righttop);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case focused_menu::left:
|
||||
if (ui_globals::panels_status != HIDE_RIGHT_PANEL)
|
||||
{
|
||||
set_focus(focused_menu::righttop);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_focus(focused_menu::main);
|
||||
if (!m_prev_selected)
|
||||
{
|
||||
selected = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
if (item[x].ref == m_prev_selected)
|
||||
selected = x;
|
||||
}
|
||||
break;
|
||||
|
||||
case focused_menu::righttop:
|
||||
set_focus(focused_menu::rightbottom);
|
||||
break;
|
||||
|
||||
case focused_menu::rightbottom:
|
||||
set_focus(focused_menu::main);
|
||||
if (!m_prev_selected)
|
||||
{
|
||||
selected = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
if (item[x].ref == m_prev_selected)
|
||||
selected = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// build list
|
||||
//-------------------------------------------------
|
||||
@ -1966,38 +1660,127 @@ float menu_select_game::draw_left_panel(float x1, float y1, float x2, float y2)
|
||||
|
||||
void menu_select_game::infos_render(float origx1, float origy1, float origx2, float origy2)
|
||||
{
|
||||
float line_height = ui().get_line_height();
|
||||
static std::string buffer;
|
||||
float const line_height = ui().get_line_height();
|
||||
float text_size = ui().options().infos_size();
|
||||
std::vector<int> xstart;
|
||||
std::vector<int> xend;
|
||||
float text_size = ui().options().infos_size();
|
||||
const game_driver *driver = nullptr;
|
||||
ui_software_info *soft = nullptr;
|
||||
bool is_favorites = ((item[0].flags & FLAG_UI_FAVORITE) != 0);
|
||||
static ui_software_info *oldsoft = nullptr;
|
||||
static const game_driver *olddriver = nullptr;
|
||||
static int oldview = -1;
|
||||
static int old_sw_view = -1;
|
||||
|
||||
if (is_favorites)
|
||||
ui_software_info const *software;
|
||||
game_driver const *driver;
|
||||
get_selection(software, driver);
|
||||
|
||||
if (software && ((software->startempty != 1) || !driver))
|
||||
{
|
||||
soft = reinterpret_cast<ui_software_info *>(get_selection_ptr());
|
||||
if (soft && soft->startempty == 1)
|
||||
m_info_driver = nullptr;
|
||||
|
||||
float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f;
|
||||
float ud_arrow_width = line_height * machine().render().ui_aspect();
|
||||
float oy1 = origy1 + line_height;
|
||||
|
||||
// apply title to right panel
|
||||
if (software->usage.empty())
|
||||
{
|
||||
driver = soft->driver;
|
||||
oldsoft = nullptr;
|
||||
ui().draw_text_full(container(), _("History"), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
|
||||
ui_globals::cur_sw_dats_view = 0;
|
||||
}
|
||||
else
|
||||
olddriver = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
driver = reinterpret_cast<const game_driver *>(get_selection_ptr());
|
||||
oldsoft = nullptr;
|
||||
}
|
||||
{
|
||||
float title_size = 0.0f;
|
||||
float txt_length = 0.0f;
|
||||
std::string t_text[2];
|
||||
t_text[0] = _("History");
|
||||
t_text[1] = _("Usage");
|
||||
|
||||
if (driver)
|
||||
for (auto & elem: t_text)
|
||||
{
|
||||
ui().draw_text_full(container(), elem.c_str(), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
|
||||
mame_ui_manager::NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_length, nullptr);
|
||||
txt_length += 0.01f;
|
||||
title_size = (std::max)(txt_length, title_size);
|
||||
}
|
||||
|
||||
rgb_t fgcolor = UI_TEXT_COLOR;
|
||||
rgb_t bgcolor = UI_TEXT_BG_COLOR;
|
||||
if (get_focus() == focused_menu::rightbottom)
|
||||
{
|
||||
fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
|
||||
bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
|
||||
}
|
||||
|
||||
float middle = origx2 - origx1;
|
||||
|
||||
if (bgcolor != UI_TEXT_BG_COLOR)
|
||||
{
|
||||
ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
|
||||
origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
|
||||
}
|
||||
|
||||
ui().draw_text_full(container(), t_text[ui_globals::cur_sw_dats_view].c_str(), origx1, origy1, origx2 - origx1,
|
||||
ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
|
||||
|
||||
draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::cur_sw_dats_view, 0, 1, title_size);
|
||||
}
|
||||
|
||||
if (m_info_software != software || m_info_view != ui_globals::cur_sw_dats_view)
|
||||
{
|
||||
m_info_buffer.clear();
|
||||
m_info_view = ui_globals::cur_sw_dats_view;
|
||||
m_info_software = software;
|
||||
if (ui_globals::cur_sw_dats_view == 0)
|
||||
{
|
||||
if (software->startempty == 1)
|
||||
mame_machine_manager::instance()->datfile().load_data_info(software->driver, m_info_buffer, UI_HISTORY_LOAD);
|
||||
else
|
||||
mame_machine_manager::instance()->datfile().load_software_info(software->listname, m_info_buffer, software->shortname, software->parentname);
|
||||
}
|
||||
else
|
||||
m_info_buffer = software->usage;
|
||||
}
|
||||
|
||||
if (m_info_buffer.empty())
|
||||
{
|
||||
ui().draw_text_full(container(), _("No Infos Available"), origx1, (origy2 + origy1) * 0.5f, origx2 - origx1, ui::text_layout::CENTER,
|
||||
ui::text_layout::WORD, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
}
|
||||
|
||||
int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
|
||||
if (m_total_lines < r_visible_lines)
|
||||
r_visible_lines = m_total_lines;
|
||||
if (m_topline_datsview < 0)
|
||||
m_topline_datsview = 0;
|
||||
if (m_topline_datsview + r_visible_lines >= m_total_lines)
|
||||
m_topline_datsview = m_total_lines - r_visible_lines;
|
||||
|
||||
for (int r = 0; r < r_visible_lines; ++r)
|
||||
{
|
||||
int itemline = r + m_topline_datsview;
|
||||
std::string tempbuf(m_info_buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
|
||||
|
||||
// up arrow
|
||||
if (r == 0 && m_topline_datsview != 0)
|
||||
draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
// bottom arrow
|
||||
else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1)
|
||||
draw_info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
else
|
||||
ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT,
|
||||
ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
oy1 += (line_height * text_size);
|
||||
}
|
||||
|
||||
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines);
|
||||
}
|
||||
else if (driver)
|
||||
{
|
||||
m_info_software = nullptr;
|
||||
|
||||
float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f;
|
||||
float ud_arrow_width = line_height * machine().render().ui_aspect();
|
||||
float oy1 = origy1 + line_height;
|
||||
@ -2046,19 +1829,19 @@ void menu_select_game::infos_render(float origx1, float origy1, float origx2, fl
|
||||
|
||||
draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::curdats_view, UI_FIRST_LOAD, UI_LAST_LOAD, title_size);
|
||||
|
||||
if (driver != olddriver || ui_globals::curdats_view != oldview)
|
||||
if (driver != m_info_driver || ui_globals::curdats_view != m_info_view)
|
||||
{
|
||||
buffer.clear();
|
||||
olddriver = driver;
|
||||
oldview = ui_globals::curdats_view;
|
||||
m_info_buffer.clear();
|
||||
m_info_driver = driver;
|
||||
m_info_view = ui_globals::curdats_view;
|
||||
m_topline_datsview = 0;
|
||||
m_total_lines = 0;
|
||||
std::vector<std::string> m_item;
|
||||
|
||||
if (ui_globals::curdats_view == UI_GENERAL_LOAD)
|
||||
general_info(driver, buffer);
|
||||
general_info(driver, m_info_buffer);
|
||||
else if (ui_globals::curdats_view != UI_COMMAND_LOAD)
|
||||
mame_machine_manager::instance()->datfile().load_data_info(driver, buffer, ui_globals::curdats_view);
|
||||
mame_machine_manager::instance()->datfile().load_data_info(driver, m_info_buffer, ui_globals::curdats_view);
|
||||
else
|
||||
mame_machine_manager::instance()->datfile().command_sub_menu(driver, m_item);
|
||||
|
||||
@ -2067,25 +1850,25 @@ void menu_select_game::infos_render(float origx1, float origy1, float origx2, fl
|
||||
for (size_t x = 0; x < m_item.size(); ++x)
|
||||
{
|
||||
std::string t_buffer;
|
||||
buffer.append(m_item[x]).append("\n");
|
||||
m_info_buffer.append(m_item[x]).append("\n");
|
||||
mame_machine_manager::instance()->datfile().load_command_info(t_buffer, m_item[x]);
|
||||
if (!t_buffer.empty())
|
||||
buffer.append(t_buffer).append("\n");
|
||||
m_info_buffer.append(t_buffer).append("\n");
|
||||
}
|
||||
convert_command_glyph(buffer);
|
||||
convert_command_glyph(m_info_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.empty())
|
||||
if (m_info_buffer.empty())
|
||||
{
|
||||
ui().draw_text_full(container(), _("No Infos Available"), origx1, (origy2 + origy1) * 0.5f, origx2 - origx1, ui::text_layout::CENTER,
|
||||
ui::text_layout::WORD, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
else if (ui_globals::curdats_view != UI_STORY_LOAD && ui_globals::curdats_view != UI_COMMAND_LOAD)
|
||||
m_total_lines = ui().wrap_text(container(), buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
else
|
||||
m_total_lines = ui().wrap_text(container(), buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
m_total_lines = ui().wrap_text(container(), m_info_buffer.c_str(), 0.0f, 0.0f, 1.0f - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
|
||||
int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
|
||||
if (m_total_lines < r_visible_lines)
|
||||
@ -2099,7 +1882,7 @@ void menu_select_game::infos_render(float origx1, float origy1, float origx2, fl
|
||||
for (int r = 0; r < r_visible_lines; ++r)
|
||||
{
|
||||
int itemline = r + m_topline_datsview;
|
||||
std::string tempbuf(buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
|
||||
std::string tempbuf(m_info_buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
|
||||
|
||||
// up arrow
|
||||
if (r == 0 && m_topline_datsview != 0)
|
||||
@ -2159,8 +1942,10 @@ void menu_select_game::infos_render(float origx1, float origy1, float origx2, fl
|
||||
ui::text_layout::RIGHT, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size3);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT,
|
||||
ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, tmp_size3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2171,112 +1956,6 @@ void menu_select_game::infos_render(float origx1, float origy1, float origx2, fl
|
||||
oy1 += (line_height * text_size);
|
||||
}
|
||||
|
||||
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines);
|
||||
}
|
||||
else if (soft)
|
||||
{
|
||||
float gutter_width = 0.4f * line_height * machine().render().ui_aspect() * 1.3f;
|
||||
float ud_arrow_width = line_height * machine().render().ui_aspect();
|
||||
float oy1 = origy1 + line_height;
|
||||
|
||||
// apply title to right panel
|
||||
if (soft->usage.empty())
|
||||
{
|
||||
ui().draw_text_full(container(), _("History"), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
|
||||
ui_globals::cur_sw_dats_view = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
float title_size = 0.0f;
|
||||
float txt_length = 0.0f;
|
||||
std::string t_text[2];
|
||||
t_text[0] = _("History");
|
||||
t_text[1] = _("Usage");
|
||||
|
||||
for (auto & elem: t_text)
|
||||
{
|
||||
ui().draw_text_full(container(), elem.c_str(), origx1, origy1, origx2 - origx1, ui::text_layout::CENTER, ui::text_layout::TRUNCATE,
|
||||
mame_ui_manager::NONE, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, &txt_length, nullptr);
|
||||
txt_length += 0.01f;
|
||||
title_size = (std::max)(txt_length, title_size);
|
||||
}
|
||||
|
||||
rgb_t fgcolor = UI_TEXT_COLOR;
|
||||
rgb_t bgcolor = UI_TEXT_BG_COLOR;
|
||||
if (get_focus() == focused_menu::rightbottom)
|
||||
{
|
||||
fgcolor = rgb_t(0xff, 0xff, 0xff, 0x00);
|
||||
bgcolor = rgb_t(0xff, 0xff, 0xff, 0xff);
|
||||
}
|
||||
|
||||
float middle = origx2 - origx1;
|
||||
|
||||
if (bgcolor != UI_TEXT_BG_COLOR)
|
||||
{
|
||||
ui().draw_textured_box(container(), origx1 + ((middle - title_size) * 0.5f), origy1, origx1 + ((middle + title_size) * 0.5f),
|
||||
origy1 + line_height, bgcolor, rgb_t(255, 43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
|
||||
}
|
||||
|
||||
ui().draw_text_full(container(), t_text[ui_globals::cur_sw_dats_view].c_str(), origx1, origy1, origx2 - origx1,
|
||||
ui::text_layout::CENTER, ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr);
|
||||
|
||||
draw_common_arrow(origx1, origy1, origx2, origy2, ui_globals::cur_sw_dats_view, 0, 1, title_size);
|
||||
}
|
||||
|
||||
if (oldsoft != soft || old_sw_view != ui_globals::cur_sw_dats_view)
|
||||
{
|
||||
buffer.clear();
|
||||
old_sw_view = ui_globals::cur_sw_dats_view;
|
||||
oldsoft = soft;
|
||||
if (ui_globals::cur_sw_dats_view == 0)
|
||||
{
|
||||
if (soft->startempty == 1)
|
||||
mame_machine_manager::instance()->datfile().load_data_info(soft->driver, buffer, UI_HISTORY_LOAD);
|
||||
else
|
||||
mame_machine_manager::instance()->datfile().load_software_info(soft->listname, buffer, soft->shortname, soft->parentname);
|
||||
}
|
||||
else
|
||||
buffer = soft->usage;
|
||||
}
|
||||
|
||||
if (buffer.empty())
|
||||
{
|
||||
ui().draw_text_full(container(), _("No Infos Available"), origx1, (origy2 + origy1) * 0.5f, origx2 - origx1, ui::text_layout::CENTER,
|
||||
ui::text_layout::WORD, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_total_lines = ui().wrap_text(container(), buffer.c_str(), origx1, origy1, origx2 - origx1 - (2.0f * gutter_width), xstart, xend, text_size);
|
||||
}
|
||||
|
||||
int r_visible_lines = floor((origy2 - oy1) / (line_height * text_size));
|
||||
if (m_total_lines < r_visible_lines)
|
||||
r_visible_lines = m_total_lines;
|
||||
if (m_topline_datsview < 0)
|
||||
m_topline_datsview = 0;
|
||||
if (m_topline_datsview + r_visible_lines >= m_total_lines)
|
||||
m_topline_datsview = m_total_lines - r_visible_lines;
|
||||
|
||||
for (int r = 0; r < r_visible_lines; ++r)
|
||||
{
|
||||
int itemline = r + m_topline_datsview;
|
||||
std::string tempbuf(buffer.substr(xstart[itemline], xend[itemline] - xstart[itemline]));
|
||||
|
||||
// up arrow
|
||||
if (r == 0 && m_topline_datsview != 0)
|
||||
draw_info_arrow(0, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
// bottom arrow
|
||||
else if (r == r_visible_lines - 1 && itemline != m_total_lines - 1)
|
||||
draw_info_arrow(1, origx1, origx2, oy1, line_height, text_size, ud_arrow_width);
|
||||
else
|
||||
ui().draw_text_full(container(), tempbuf.c_str(), origx1 + gutter_width, oy1, origx2 - origx1, ui::text_layout::LEFT,
|
||||
ui::text_layout::TRUNCATE, mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
oy1 += (line_height * text_size);
|
||||
}
|
||||
|
||||
// return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
|
||||
right_visible_lines = r_visible_lines - (m_topline_datsview != 0) - (m_topline_datsview + r_visible_lines != m_total_lines);
|
||||
}
|
||||
@ -2301,4 +1980,60 @@ void menu_select_game::get_selection(ui_software_info const *&software, game_dri
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void menu_select_game::make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const
|
||||
{
|
||||
inifile_manager &inifile = mame_machine_manager::instance()->inifile();
|
||||
|
||||
line0 = string_format(_("%1$s %2$s ( %3$d / %4$d machines (%5$d BIOS) )"),
|
||||
emulator_info::get_appname(),
|
||||
bare_build_version,
|
||||
visible_items,
|
||||
(driver_list::total() - 1),
|
||||
m_isabios);
|
||||
|
||||
std::string filtered;
|
||||
if (main_filters::actual == FILTER_CATEGORY && inifile.total() > 0)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s - %3$s) - "),
|
||||
main_filters::text[main_filters::actual],
|
||||
inifile.get_file(),
|
||||
inifile.get_category());
|
||||
}
|
||||
else if (main_filters::actual == FILTER_MANUFACTURER)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s) - "),
|
||||
main_filters::text[main_filters::actual],
|
||||
c_mnfct::ui[c_mnfct::actual]);
|
||||
}
|
||||
else if (main_filters::actual == FILTER_YEAR)
|
||||
{
|
||||
filtered = string_format(_("%1$s (%2$s) - "),
|
||||
main_filters::text[main_filters::actual],
|
||||
c_year::ui[c_year::actual]);
|
||||
}
|
||||
|
||||
// display the current typeahead
|
||||
if (isfavorite())
|
||||
line1.clear();
|
||||
else
|
||||
line1 = string_format(_("%1$s Search: %2$s_"), filtered, m_search);
|
||||
|
||||
line2.clear();
|
||||
}
|
||||
|
||||
|
||||
std::string menu_select_game::make_driver_description(game_driver const &driver) const
|
||||
{
|
||||
// first line is game name
|
||||
return string_format(_("Romset: %1$-.100s"), driver.name);
|
||||
}
|
||||
|
||||
|
||||
std::string menu_select_game::make_software_description(ui_software_info const &software) const
|
||||
{
|
||||
// first line is system
|
||||
return string_format(_("System: %1$-.100s"), software.driver->description);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -27,7 +27,6 @@ public:
|
||||
static void force_game_select(mame_ui_manager &mui, render_container &container);
|
||||
|
||||
protected:
|
||||
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
|
||||
virtual bool menu_has_search_active() override { return (m_search[0] != 0); }
|
||||
|
||||
private:
|
||||
@ -40,9 +39,15 @@ private:
|
||||
|
||||
enum { VISIBLE_GAMES_IN_SEARCH = 200 };
|
||||
char m_search[40];
|
||||
static bool first_start;
|
||||
static int m_isabios;
|
||||
int highlight;
|
||||
|
||||
std::string m_info_buffer;
|
||||
game_driver const *m_info_driver;
|
||||
ui_software_info const *m_info_software;
|
||||
int m_info_view;
|
||||
|
||||
static std::vector<const game_driver *> m_sortedlist;
|
||||
std::vector<const game_driver *> m_availsortedlist;
|
||||
std::vector<const game_driver *> m_unavailsortedlist;
|
||||
@ -59,13 +64,18 @@ private:
|
||||
// get selected software and/or driver
|
||||
virtual void get_selection(ui_software_info const *&software, game_driver const *&driver) const override;
|
||||
|
||||
// text for main top/bottom panels
|
||||
virtual void make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const override;
|
||||
virtual std::string make_driver_description(game_driver const &driver) const override;
|
||||
virtual std::string make_software_description(ui_software_info const &software) const override;
|
||||
|
||||
// internal methods
|
||||
void build_custom();
|
||||
void build_category();
|
||||
void build_available_list();
|
||||
void build_list(const char *filter_text = nullptr, int filter = 0, bool bioscheck = false, std::vector<const game_driver *> vec = {});
|
||||
|
||||
bool isfavorite();
|
||||
bool isfavorite() const;
|
||||
void populate_search();
|
||||
void init_sorted_list();
|
||||
bool load_available_machines();
|
||||
@ -87,7 +97,6 @@ private:
|
||||
void inkey_select_favorite(const event *menu_event);
|
||||
void inkey_special(const event *menu_event);
|
||||
void inkey_export();
|
||||
void inkey_navigation();
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "ui/selmenu.h"
|
||||
|
||||
#include "ui/icorender.h"
|
||||
#include "ui/inifile.h"
|
||||
#include "ui/utils.h"
|
||||
|
||||
// these hold static bitmap images
|
||||
@ -26,6 +27,7 @@
|
||||
#include "drivenum.h"
|
||||
#include "emuopts.h"
|
||||
#include "rendutil.h"
|
||||
#include "softlist.h"
|
||||
#include "uiinput.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -189,75 +191,264 @@ menu_select_launch::menu_select_launch(mame_ui_manager &mui, render_container &c
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// draw right box title
|
||||
// perform our special rendering
|
||||
//-------------------------------------------------
|
||||
|
||||
float menu_select_launch::draw_right_box_title(float x1, float y1, float x2, float y2)
|
||||
void menu_select_launch::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
|
||||
{
|
||||
auto line_height = ui().get_line_height();
|
||||
float midl = (x2 - x1) * 0.5f;
|
||||
std::string tempbuf[5];
|
||||
|
||||
// add outlined box for options
|
||||
// determine the text for the header
|
||||
make_topbox_text(tempbuf[0], tempbuf[1], tempbuf[2]);
|
||||
|
||||
// get the size of the text
|
||||
float maxwidth = origx2 - origx1;
|
||||
for (int line = 0; line < 3; ++line)
|
||||
{
|
||||
float width;
|
||||
ui().draw_text_full(container(), tempbuf[line].c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NONE, rgb_t::white, rgb_t::black, &width, nullptr);
|
||||
width += 2 * UI_BOX_LR_BORDER;
|
||||
maxwidth = (std::max)(width, maxwidth);
|
||||
}
|
||||
|
||||
float text_size = 1.0f;
|
||||
if (maxwidth > origx2 - origx1)
|
||||
{
|
||||
text_size = (origx2 - origx1) / maxwidth;
|
||||
maxwidth = origx2 - origx1;
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
float tbarspace = ui().get_line_height();
|
||||
float x1 = 0.5f - 0.5f * maxwidth;
|
||||
float x2 = x1 + maxwidth;
|
||||
float y1 = origy1 - top;
|
||||
float y2 = origy1 - 3.0f * UI_BOX_TB_BORDER - tbarspace;
|
||||
|
||||
// draw a box
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
|
||||
|
||||
// add separator line
|
||||
container().add_line(x1 + midl, y1, x1 + midl, y1 + line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
// take off the borders
|
||||
x1 += UI_BOX_LR_BORDER;
|
||||
x2 -= UI_BOX_LR_BORDER;
|
||||
y1 += UI_BOX_TB_BORDER;
|
||||
|
||||
std::string buffer[RP_LAST + 1];
|
||||
buffer[RP_IMAGES] = _("Images");
|
||||
buffer[RP_INFOS] = _("Infos");
|
||||
|
||||
// check size
|
||||
float text_size = 1.0f;
|
||||
for (auto & elem : buffer)
|
||||
// draw the text within it
|
||||
for (int line = 0; line < 3; ++line)
|
||||
{
|
||||
auto textlen = ui().get_string_width(elem.c_str()) + 0.01f;
|
||||
float tmp_size = (textlen > midl) ? (midl / textlen) : 1.0f;
|
||||
text_size = MIN(text_size, tmp_size);
|
||||
ui().draw_text_full(container(), tempbuf[line].c_str(), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
y1 += ui().get_line_height();
|
||||
}
|
||||
|
||||
for (int cells = RP_FIRST; cells <= RP_LAST; ++cells)
|
||||
{
|
||||
rgb_t bgcolor = UI_TEXT_BG_COLOR;
|
||||
rgb_t fgcolor = UI_TEXT_COLOR;
|
||||
// determine the text to render below
|
||||
ui_software_info const *swinfo;
|
||||
game_driver const *driver;
|
||||
get_selection(swinfo, driver);
|
||||
|
||||
if (mouse_hit && x1 <= mouse_x && x1 + midl > mouse_x && y1 <= mouse_y && y1 + line_height > mouse_y)
|
||||
bool isstar = false;
|
||||
rgb_t color = UI_BACKGROUND_COLOR;
|
||||
if (swinfo && ((swinfo->startempty != 1) || !driver))
|
||||
{
|
||||
isstar = mame_machine_manager::instance()->favorite().isgame_favorite(*swinfo);
|
||||
|
||||
// first line is long name or system
|
||||
tempbuf[0] = make_software_description(*swinfo);
|
||||
|
||||
// next line is year, publisher
|
||||
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), swinfo->year, swinfo->publisher);
|
||||
|
||||
// next line is parent/clone
|
||||
if (!swinfo->parentname.empty())
|
||||
tempbuf[2] = string_format(_("Software is clone of: %1$-.100s"), !swinfo->parentlongname.empty() ? swinfo->parentlongname : swinfo->parentname);
|
||||
else
|
||||
tempbuf[2] = _("Software is parent");
|
||||
|
||||
// next line is supported status
|
||||
if (swinfo->supported == SOFTWARE_SUPPORTED_NO)
|
||||
{
|
||||
if (ui_globals::rpanel != cells)
|
||||
tempbuf[3] = _("Supported: No");
|
||||
color = UI_RED_COLOR;
|
||||
}
|
||||
else if (swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL)
|
||||
{
|
||||
tempbuf[3] = _("Supported: Partial");
|
||||
color = UI_YELLOW_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempbuf[3] = _("Supported: Yes");
|
||||
color = UI_GREEN_COLOR;
|
||||
}
|
||||
|
||||
// last line is romset name
|
||||
tempbuf[4] = string_format(_("romset: %1$-.100s"), swinfo->shortname);
|
||||
}
|
||||
else if (driver)
|
||||
{
|
||||
isstar = mame_machine_manager::instance()->favorite().isgame_favorite(driver);
|
||||
|
||||
// first line is game description/game name
|
||||
tempbuf[0] = make_driver_description(*driver);
|
||||
|
||||
// next line is year, manufacturer
|
||||
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), driver->year, driver->manufacturer);
|
||||
|
||||
// next line is clone/parent status
|
||||
int cloneof = driver_list::non_bios_clone(*driver);
|
||||
|
||||
if (cloneof != -1)
|
||||
tempbuf[2] = string_format(_("Driver is clone of: %1$-.100s"), driver_list::driver(cloneof).description);
|
||||
else
|
||||
tempbuf[2] = _("Driver is parent");
|
||||
|
||||
// next line is overall driver status
|
||||
if (driver->flags & MACHINE_NOT_WORKING)
|
||||
tempbuf[3] = _("Overall: NOT WORKING");
|
||||
else if (driver->flags & MACHINE_UNEMULATED_PROTECTION)
|
||||
tempbuf[3] = _("Overall: Unemulated Protection");
|
||||
else
|
||||
tempbuf[3] = _("Overall: Working");
|
||||
|
||||
// next line is graphics, sound status
|
||||
if (driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS))
|
||||
tempbuf[4] = _("Graphics: Imperfect, ");
|
||||
else
|
||||
tempbuf[4] = _("Graphics: OK, ");
|
||||
|
||||
if (driver->flags & MACHINE_NO_SOUND)
|
||||
tempbuf[4].append(_("Sound: Unimplemented"));
|
||||
else if (driver->flags & MACHINE_IMPERFECT_SOUND)
|
||||
tempbuf[4].append(_("Sound: Imperfect"));
|
||||
else
|
||||
tempbuf[4].append(_("Sound: OK"));
|
||||
|
||||
color = UI_GREEN_COLOR;
|
||||
|
||||
if ((driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS
|
||||
| MACHINE_NO_SOUND | MACHINE_IMPERFECT_SOUND)) != 0)
|
||||
color = UI_YELLOW_COLOR;
|
||||
|
||||
if ((driver->flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION)) != 0)
|
||||
color = UI_RED_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string copyright(emulator_info::get_copyright());
|
||||
size_t found = copyright.find("\n");
|
||||
|
||||
tempbuf[0].clear();
|
||||
tempbuf[1] = string_format(_("%1$s %2$s"), emulator_info::get_appname(), build_version);
|
||||
tempbuf[2] = copyright.substr(0, found);
|
||||
tempbuf[3] = copyright.substr(found + 1);
|
||||
tempbuf[4].clear();
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
x1 = 0.5f - 0.5f * maxwidth;
|
||||
x2 = x1 + maxwidth;
|
||||
y1 = y2;
|
||||
y2 = origy1 - UI_BOX_TB_BORDER;
|
||||
|
||||
// draw toolbar
|
||||
draw_toolbar(x1, y1, x2, y2);
|
||||
|
||||
// get the size of the text
|
||||
maxwidth = origx2 - origx1;
|
||||
|
||||
for (auto &elem : tempbuf)
|
||||
{
|
||||
float width;
|
||||
ui().draw_text_full(container(), elem.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NONE, rgb_t::white, rgb_t::black, &width, nullptr);
|
||||
width += 2 * UI_BOX_LR_BORDER;
|
||||
maxwidth = (std::max)(maxwidth, width);
|
||||
}
|
||||
|
||||
if (maxwidth > origx2 - origx1)
|
||||
{
|
||||
text_size = (origx2 - origx1) / maxwidth;
|
||||
maxwidth = origx2 - origx1;
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
x1 = 0.5f - 0.5f * maxwidth;
|
||||
x2 = x1 + maxwidth;
|
||||
y1 = origy2 + UI_BOX_TB_BORDER;
|
||||
y2 = origy2 + bottom;
|
||||
|
||||
// draw a box
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, color);
|
||||
|
||||
// take off the borders
|
||||
x1 += UI_BOX_LR_BORDER;
|
||||
x2 -= UI_BOX_LR_BORDER;
|
||||
y1 += UI_BOX_TB_BORDER;
|
||||
|
||||
// is favorite? draw the star
|
||||
if (isstar)
|
||||
draw_star(x1, y1);
|
||||
|
||||
// draw all lines
|
||||
for (auto &elem : tempbuf)
|
||||
{
|
||||
ui().draw_text_full(container(), elem.c_str(), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
y1 += ui().get_line_height();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void menu_select_launch::inkey_navigation()
|
||||
{
|
||||
switch (get_focus())
|
||||
{
|
||||
case focused_menu::main:
|
||||
if (selected <= visible_items)
|
||||
{
|
||||
m_prev_selected = item[selected].ref;
|
||||
selected = visible_items + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui_globals::panels_status != HIDE_LEFT_PANEL)
|
||||
set_focus(focused_menu::left);
|
||||
|
||||
else if (ui_globals::panels_status == HIDE_BOTH)
|
||||
{
|
||||
bgcolor = UI_MOUSEOVER_BG_COLOR;
|
||||
fgcolor = UI_MOUSEOVER_COLOR;
|
||||
hover = HOVER_RP_FIRST + cells;
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
if (item[x].ref == m_prev_selected)
|
||||
selected = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_focus(focused_menu::righttop);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (ui_globals::rpanel != cells)
|
||||
case focused_menu::left:
|
||||
if (ui_globals::panels_status != HIDE_RIGHT_PANEL)
|
||||
{
|
||||
container().add_line(x1, y1 + line_height, x1 + midl, y1 + line_height, UI_LINE_WIDTH,
|
||||
UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
if (fgcolor != UI_MOUSEOVER_COLOR)
|
||||
fgcolor = UI_CLONE_COLOR;
|
||||
set_focus(focused_menu::righttop);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_focus(focused_menu::main);
|
||||
select_prev();
|
||||
}
|
||||
break;
|
||||
|
||||
if (m_focus == focused_menu::righttop && ui_globals::rpanel == cells)
|
||||
{
|
||||
fgcolor = rgb_t(0xff, 0xff, 0x00);
|
||||
bgcolor = rgb_t(0xff, 0xff, 0xff);
|
||||
ui().draw_textured_box(container(), x1 + UI_LINE_WIDTH, y1 + UI_LINE_WIDTH, x1 + midl - UI_LINE_WIDTH, y1 + line_height,
|
||||
bgcolor, rgb_t(43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
|
||||
}
|
||||
else if (bgcolor == UI_MOUSEOVER_BG_COLOR)
|
||||
{
|
||||
container().add_rect(x1 + UI_LINE_WIDTH, y1 + UI_LINE_WIDTH, x1 + midl - UI_LINE_WIDTH, y1 + line_height,
|
||||
bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
|
||||
}
|
||||
case focused_menu::righttop:
|
||||
set_focus(focused_menu::rightbottom);
|
||||
break;
|
||||
|
||||
ui().draw_text_full(container(), buffer[cells].c_str(), x1 + UI_LINE_WIDTH, y1, midl - UI_LINE_WIDTH,
|
||||
ui::text_layout::CENTER, ui::text_layout::NEVER, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
|
||||
x1 += midl;
|
||||
case focused_menu::rightbottom:
|
||||
set_focus(focused_menu::main);
|
||||
select_prev();
|
||||
break;
|
||||
}
|
||||
|
||||
return (y1 + line_height + UI_LINE_WIDTH);
|
||||
}
|
||||
|
||||
|
||||
@ -340,7 +531,7 @@ void menu_select_launch::draw_info_arrow(int ub, float origx1, float origx2, flo
|
||||
// draw toolbar
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2, bool software)
|
||||
void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
// draw a box
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, rgb_t(0xEF, 0x12, 0x47, 0x7B));
|
||||
@ -351,8 +542,8 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2, bo
|
||||
y1 += UI_BOX_TB_BORDER;
|
||||
y2 -= UI_BOX_TB_BORDER;
|
||||
|
||||
texture_ptr_vector const &t_texture = software ? m_cache->sw_toolbar_texture() : m_cache->toolbar_texture();
|
||||
bitmap_ptr_vector const &t_bitmap = software ? m_cache->sw_toolbar_bitmap() : m_cache->toolbar_bitmap();
|
||||
texture_ptr_vector const &t_texture(m_is_swlist ? m_cache->sw_toolbar_texture() : m_cache->toolbar_texture());
|
||||
bitmap_ptr_vector const &t_bitmap(m_is_swlist ? m_cache->sw_toolbar_bitmap() : m_cache->toolbar_bitmap());
|
||||
|
||||
auto const num_valid(std::count_if(std::begin(t_bitmap), std::end(t_bitmap), [](bitmap_ptr const &e) { return e && e->valid(); }));
|
||||
|
||||
@ -1272,6 +1463,79 @@ void menu_select_launch::draw_right_panel(float origx1, float origy1, float orig
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// draw right box title
|
||||
//-------------------------------------------------
|
||||
|
||||
float menu_select_launch::draw_right_box_title(float x1, float y1, float x2, float y2)
|
||||
{
|
||||
auto line_height = ui().get_line_height();
|
||||
float midl = (x2 - x1) * 0.5f;
|
||||
|
||||
// add outlined box for options
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
|
||||
|
||||
// add separator line
|
||||
container().add_line(x1 + midl, y1, x1 + midl, y1 + line_height, UI_LINE_WIDTH, UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
|
||||
std::string buffer[RP_LAST + 1];
|
||||
buffer[RP_IMAGES] = _("Images");
|
||||
buffer[RP_INFOS] = _("Infos");
|
||||
|
||||
// check size
|
||||
float text_size = 1.0f;
|
||||
for (auto & elem : buffer)
|
||||
{
|
||||
auto textlen = ui().get_string_width(elem.c_str()) + 0.01f;
|
||||
float tmp_size = (textlen > midl) ? (midl / textlen) : 1.0f;
|
||||
text_size = MIN(text_size, tmp_size);
|
||||
}
|
||||
|
||||
for (int cells = RP_FIRST; cells <= RP_LAST; ++cells)
|
||||
{
|
||||
rgb_t bgcolor = UI_TEXT_BG_COLOR;
|
||||
rgb_t fgcolor = UI_TEXT_COLOR;
|
||||
|
||||
if (mouse_hit && x1 <= mouse_x && x1 + midl > mouse_x && y1 <= mouse_y && y1 + line_height > mouse_y)
|
||||
{
|
||||
if (ui_globals::rpanel != cells)
|
||||
{
|
||||
bgcolor = UI_MOUSEOVER_BG_COLOR;
|
||||
fgcolor = UI_MOUSEOVER_COLOR;
|
||||
hover = HOVER_RP_FIRST + cells;
|
||||
}
|
||||
}
|
||||
|
||||
if (ui_globals::rpanel != cells)
|
||||
{
|
||||
container().add_line(x1, y1 + line_height, x1 + midl, y1 + line_height, UI_LINE_WIDTH,
|
||||
UI_BORDER_COLOR, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
|
||||
if (fgcolor != UI_MOUSEOVER_COLOR)
|
||||
fgcolor = UI_CLONE_COLOR;
|
||||
}
|
||||
|
||||
if (m_focus == focused_menu::righttop && ui_globals::rpanel == cells)
|
||||
{
|
||||
fgcolor = rgb_t(0xff, 0xff, 0x00);
|
||||
bgcolor = rgb_t(0xff, 0xff, 0xff);
|
||||
ui().draw_textured_box(container(), x1 + UI_LINE_WIDTH, y1 + UI_LINE_WIDTH, x1 + midl - UI_LINE_WIDTH, y1 + line_height,
|
||||
bgcolor, rgb_t(43, 43, 43), hilight_main_texture(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
|
||||
}
|
||||
else if (bgcolor == UI_MOUSEOVER_BG_COLOR)
|
||||
{
|
||||
container().add_rect(x1 + UI_LINE_WIDTH, y1 + UI_LINE_WIDTH, x1 + midl - UI_LINE_WIDTH, y1 + line_height,
|
||||
bgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXWRAP(TRUE));
|
||||
}
|
||||
|
||||
ui().draw_text_full(container(), buffer[cells].c_str(), x1 + UI_LINE_WIDTH, y1, midl - UI_LINE_WIDTH,
|
||||
ui::text_layout::CENTER, ui::text_layout::NEVER, mame_ui_manager::NORMAL, fgcolor, bgcolor, nullptr, nullptr, text_size);
|
||||
x1 += midl;
|
||||
}
|
||||
|
||||
return (y1 + line_height + UI_LINE_WIDTH);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// perform our special rendering
|
||||
//-------------------------------------------------
|
||||
|
@ -46,19 +46,15 @@ protected:
|
||||
focused_menu get_focus() const { return m_focus; }
|
||||
void set_focus(focused_menu focus) { m_focus = focus; }
|
||||
|
||||
// draw right box
|
||||
float draw_right_box_title(float x1, float y1, float x2, float y2);
|
||||
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
|
||||
|
||||
// hanlders
|
||||
void inkey_navigation();
|
||||
|
||||
// draw arrow
|
||||
void draw_common_arrow(float origx1, float origy1, float origx2, float origy2, int current, int dmin, int dmax, float title);
|
||||
void draw_info_arrow(int ub, float origx1, float origx2, float oy1, float line_height, float text_size, float ud_arrow_width);
|
||||
|
||||
// draw toolbar
|
||||
void draw_toolbar(float x1, float y1, float x2, float y2, bool software = false);
|
||||
|
||||
// draw star
|
||||
void draw_star(float x0, float y0);
|
||||
|
||||
int visible_items;
|
||||
void *m_prev_selected;
|
||||
int m_total_lines;
|
||||
@ -124,7 +120,27 @@ private:
|
||||
|
||||
// get selected software and/or driver
|
||||
virtual void get_selection(ui_software_info const *&software, game_driver const *&driver) const = 0;
|
||||
void select_prev()
|
||||
{
|
||||
if (!m_prev_selected)
|
||||
{
|
||||
selected = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
{
|
||||
if (item[x].ref == m_prev_selected)
|
||||
{
|
||||
selected = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_toolbar(float x1, float y1, float x2, float y2);
|
||||
void draw_star(float x0, float y0);
|
||||
float draw_icon(int linenum, void *selectedref, float x1, float y1);
|
||||
|
||||
void get_title_search(std::string &title, std::string &search);
|
||||
@ -140,6 +156,7 @@ private:
|
||||
|
||||
// draw right panel
|
||||
void draw_right_panel(float origx1, float origy1, float origx2, float origy2);
|
||||
float draw_right_box_title(float x1, float y1, float x2, float y2);
|
||||
|
||||
// images render
|
||||
void arts_render(float origx1, float origy1, float origx2, float origy2);
|
||||
@ -147,6 +164,11 @@ private:
|
||||
void arts_render_images(bitmap_argb32 *bitmap, float origx1, float origy1, float origx2, float origy2);
|
||||
void draw_snapx(float origx1, float origy1, float origx2, float origy2);
|
||||
|
||||
// text for main top/bottom panels
|
||||
virtual void make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const = 0;
|
||||
virtual std::string make_driver_description(game_driver const &driver) const = 0;
|
||||
virtual std::string make_software_description(ui_software_info const &software) const = 0;
|
||||
|
||||
// cleanup function
|
||||
static void exit(running_machine &machine);
|
||||
|
||||
|
@ -298,9 +298,10 @@ void menu_select_software::handle()
|
||||
check_filter = true;
|
||||
m_prev_selected = nullptr;
|
||||
}
|
||||
|
||||
else if (menu_event->iptkey == IPT_UI_CONFIGURE)
|
||||
{
|
||||
inkey_navigation();
|
||||
}
|
||||
}
|
||||
|
||||
if (menu_event && !menu_event->itemref)
|
||||
@ -650,231 +651,6 @@ void menu_select_software::build_software_list()
|
||||
m_sortedlist.push_back(&m_swinfo[x]);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// perform our special rendering
|
||||
//-------------------------------------------------
|
||||
|
||||
void menu_select_software::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
|
||||
{
|
||||
ui_software_info *swinfo = (selectedref != nullptr) ? (ui_software_info *)selectedref : ((m_prev_selected != nullptr) ? (ui_software_info *)m_prev_selected : nullptr);
|
||||
const game_driver *driver = nullptr;
|
||||
float width;
|
||||
std::string tempbuf[5], filtered;
|
||||
rgb_t color = UI_BACKGROUND_COLOR;
|
||||
bool isstar = false;
|
||||
float tbarspace = ui().get_line_height();
|
||||
float text_size = 1.0f;
|
||||
|
||||
// determine the text for the header
|
||||
int vis_item = (m_search[0] != 0) ? visible_items : (m_has_empty_start ? visible_items - 1 : visible_items);
|
||||
tempbuf[0] = string_format(_("%1$s %2$s ( %3$d / %4$d software packages )"), emulator_info::get_appname(), bare_build_version, vis_item, m_swinfo.size() - 1);
|
||||
tempbuf[1] = string_format(_("Driver: \"%1$s\" software list "), m_driver->description);
|
||||
|
||||
if (sw_filters::actual == UI_SW_REGION && m_filter.region.ui.size() != 0)
|
||||
filtered = string_format(_("Region: %1$s -"), m_filter.region.ui[m_filter.region.actual]);
|
||||
else if (sw_filters::actual == UI_SW_PUBLISHERS)
|
||||
filtered = string_format(_("Publisher: %1$s -"), m_filter.publisher.ui[m_filter.publisher.actual]);
|
||||
else if (sw_filters::actual == UI_SW_YEARS)
|
||||
filtered = string_format(_("Year: %1$s -"), m_filter.year.ui[m_filter.year.actual]);
|
||||
else if (sw_filters::actual == UI_SW_LIST)
|
||||
filtered = string_format(_("Software List: %1$s -"), m_filter.swlist.description[m_filter.swlist.actual]);
|
||||
else if (sw_filters::actual == UI_SW_TYPE)
|
||||
filtered = string_format(_("Device type: %1$s -"), m_filter.type.ui[m_filter.type.actual]);
|
||||
|
||||
tempbuf[2] = string_format(_("%s Search: %s_"), filtered, m_search);
|
||||
|
||||
// get the size of the text
|
||||
float maxwidth = origx2 - origx1;
|
||||
|
||||
for (int line = 0; line < 3; ++line)
|
||||
{
|
||||
ui().draw_text_full(container(), tempbuf[line].c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NONE, rgb_t::white, rgb_t::black, &width, nullptr);
|
||||
width += 2 * UI_BOX_LR_BORDER;
|
||||
maxwidth = MAX(width, maxwidth);
|
||||
}
|
||||
|
||||
if (maxwidth > origx2 - origx1)
|
||||
{
|
||||
text_size = (origx2 - origx1) / maxwidth;
|
||||
maxwidth = origx2 - origx1;
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
float x1 = 0.5f - 0.5f * maxwidth;
|
||||
float x2 = x1 + maxwidth;
|
||||
float y1 = origy1 - top;
|
||||
float y2 = origy1 - 3.0f * UI_BOX_TB_BORDER - tbarspace;
|
||||
|
||||
// draw a box
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_BACKGROUND_COLOR);
|
||||
|
||||
// take off the borders
|
||||
x1 += UI_BOX_LR_BORDER;
|
||||
x2 -= UI_BOX_LR_BORDER;
|
||||
y1 += UI_BOX_TB_BORDER;
|
||||
|
||||
// draw the text within it
|
||||
for (int line = 0; line < 3; ++line)
|
||||
{
|
||||
ui().draw_text_full(container(), tempbuf[line].c_str(), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
y1 += ui().get_line_height();
|
||||
}
|
||||
|
||||
// determine the text to render below
|
||||
if (swinfo != nullptr && swinfo->startempty == 1)
|
||||
driver = swinfo->driver;
|
||||
|
||||
if (driver != nullptr)
|
||||
{
|
||||
isstar = mame_machine_manager::instance()->favorite().isgame_favorite(driver);
|
||||
|
||||
// first line is game description
|
||||
tempbuf[0] = string_format(_("%1$-.100s"), driver->description);
|
||||
|
||||
// next line is year, manufacturer
|
||||
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), driver->year, driver->manufacturer);
|
||||
|
||||
// next line is clone/parent status
|
||||
int cloneof = driver_list::non_bios_clone(*driver);
|
||||
|
||||
if (cloneof != -1)
|
||||
tempbuf[2] = string_format(_("Driver is clone of: %1$-.100s"), driver_list::driver(cloneof).description);
|
||||
else
|
||||
tempbuf[2] = _("Driver is parent");
|
||||
|
||||
// next line is overall driver status
|
||||
if (driver->flags & MACHINE_NOT_WORKING)
|
||||
tempbuf[3] = _("Overall: NOT WORKING");
|
||||
else if (driver->flags & MACHINE_UNEMULATED_PROTECTION)
|
||||
tempbuf[3] = _("Overall: Unemulated Protection");
|
||||
else
|
||||
tempbuf[3] = _("Overall: Working");
|
||||
|
||||
// next line is graphics, sound status
|
||||
if (driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS))
|
||||
tempbuf[4] = _("Graphics: Imperfect, ");
|
||||
else
|
||||
tempbuf[4] = _("Graphics: OK, ");
|
||||
|
||||
if (driver->flags & MACHINE_NO_SOUND)
|
||||
tempbuf[4].append(_("Sound: Unimplemented"));
|
||||
else if (driver->flags & MACHINE_IMPERFECT_SOUND)
|
||||
tempbuf[4].append(_("Sound: Imperfect"));
|
||||
else
|
||||
tempbuf[4].append(_("Sound: OK"));
|
||||
|
||||
color = UI_GREEN_COLOR;
|
||||
|
||||
if ((driver->flags & (MACHINE_IMPERFECT_GRAPHICS | MACHINE_WRONG_COLORS | MACHINE_IMPERFECT_COLORS
|
||||
| MACHINE_NO_SOUND | MACHINE_IMPERFECT_SOUND)) != 0)
|
||||
color = UI_YELLOW_COLOR;
|
||||
|
||||
if ((driver->flags & (MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION)) != 0)
|
||||
color = UI_RED_COLOR;
|
||||
}
|
||||
|
||||
else if (swinfo != nullptr)
|
||||
{
|
||||
isstar = mame_machine_manager::instance()->favorite().isgame_favorite(*swinfo);
|
||||
|
||||
// first line is long name
|
||||
tempbuf[0] = string_format(_("%1$-.100s"), swinfo->longname.c_str());
|
||||
|
||||
// next line is year, publisher
|
||||
tempbuf[1] = string_format(_("%1$s, %2$-.100s"), swinfo->year.c_str(), swinfo->publisher.c_str());
|
||||
|
||||
// next line is parent/clone
|
||||
if (!swinfo->parentname.empty())
|
||||
tempbuf[2] = string_format(_("Software is clone of: %1$-.100s"), !swinfo->parentlongname.empty() ? swinfo->parentlongname.c_str() : swinfo->parentname.c_str());
|
||||
else
|
||||
tempbuf[2] = _("Software is parent");
|
||||
|
||||
// next line is supported status
|
||||
if (swinfo->supported == SOFTWARE_SUPPORTED_NO)
|
||||
{
|
||||
tempbuf[3] = _("Supported: No");
|
||||
color = UI_RED_COLOR;
|
||||
}
|
||||
else if (swinfo->supported == SOFTWARE_SUPPORTED_PARTIAL)
|
||||
{
|
||||
tempbuf[3] = _("Supported: Partial");
|
||||
color = UI_YELLOW_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempbuf[3] = _("Supported: Yes");
|
||||
color = UI_GREEN_COLOR;
|
||||
}
|
||||
|
||||
// last line is romset name
|
||||
tempbuf[4] = string_format(_("romset: %1$-.100s"), swinfo->shortname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string copyright(emulator_info::get_copyright());
|
||||
size_t found = copyright.find("\n");
|
||||
|
||||
tempbuf[0].clear();
|
||||
tempbuf[1] = string_format("%s %s", emulator_info::get_appname(), build_version);
|
||||
tempbuf[2] = copyright.substr(0, found);
|
||||
tempbuf[3] = copyright.substr(found + 1);
|
||||
tempbuf[4].clear();
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
x1 = 0.5f - 0.5f * maxwidth;
|
||||
x2 = x1 + maxwidth;
|
||||
y1 = y2;
|
||||
y2 = origy1 - UI_BOX_TB_BORDER;
|
||||
|
||||
// draw toolbar
|
||||
draw_toolbar(x1, y1, x2, y2, true);
|
||||
|
||||
// get the size of the text
|
||||
maxwidth = origx2 - origx1;
|
||||
|
||||
for (auto &elem : tempbuf)
|
||||
{
|
||||
ui().draw_text_full(container(), elem.c_str(), 0.0f, 0.0f, 1.0f, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NONE, rgb_t::white, rgb_t::black, &width, nullptr);
|
||||
width += 2 * UI_BOX_LR_BORDER;
|
||||
maxwidth = MAX(maxwidth, width);
|
||||
}
|
||||
|
||||
if (maxwidth > origx2 - origx1)
|
||||
{
|
||||
text_size = (origx2 - origx1) / maxwidth;
|
||||
maxwidth = origx2 - origx1;
|
||||
}
|
||||
|
||||
// compute our bounds
|
||||
x1 = 0.5f - 0.5f * maxwidth;
|
||||
x2 = x1 + maxwidth;
|
||||
y1 = origy2 + UI_BOX_TB_BORDER;
|
||||
y2 = origy2 + bottom;
|
||||
|
||||
// draw a box
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, color);
|
||||
|
||||
// take off the borders
|
||||
x1 += UI_BOX_LR_BORDER;
|
||||
x2 -= UI_BOX_LR_BORDER;
|
||||
y1 += UI_BOX_TB_BORDER;
|
||||
|
||||
// is favorite? draw the star
|
||||
if (isstar)
|
||||
draw_star(x1, y1);
|
||||
|
||||
// draw all lines
|
||||
for (auto & elem : tempbuf)
|
||||
{
|
||||
ui().draw_text_full(container(), elem.c_str(), x1, y1, x2 - x1, ui::text_layout::CENTER, ui::text_layout::NEVER,
|
||||
mame_ui_manager::NORMAL, UI_TEXT_COLOR, UI_TEXT_BG_COLOR, nullptr, nullptr, text_size);
|
||||
y1 += ui().get_line_height();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// handle select key event
|
||||
@ -989,73 +765,6 @@ void menu_select_software::inkey_special(const event *menu_event)
|
||||
}
|
||||
|
||||
|
||||
void menu_select_software::inkey_navigation()
|
||||
{
|
||||
switch (get_focus())
|
||||
{
|
||||
case focused_menu::main:
|
||||
if (selected <= visible_items)
|
||||
{
|
||||
m_prev_selected = item[selected].ref;
|
||||
selected = visible_items + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ui_globals::panels_status != HIDE_LEFT_PANEL)
|
||||
set_focus(focused_menu::left);
|
||||
|
||||
else if (ui_globals::panels_status == HIDE_BOTH)
|
||||
{
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
if (item[x].ref == m_prev_selected)
|
||||
selected = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_focus(focused_menu::righttop);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case focused_menu::left:
|
||||
if (ui_globals::panels_status != HIDE_RIGHT_PANEL)
|
||||
{
|
||||
set_focus(focused_menu::righttop);
|
||||
}
|
||||
else
|
||||
{
|
||||
set_focus(focused_menu::main);
|
||||
if (m_prev_selected == nullptr)
|
||||
{
|
||||
selected = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
if (item[x].ref == m_prev_selected)
|
||||
selected = x;
|
||||
}
|
||||
break;
|
||||
|
||||
case focused_menu::righttop:
|
||||
set_focus(focused_menu::rightbottom);
|
||||
break;
|
||||
|
||||
case focused_menu::rightbottom:
|
||||
set_focus(focused_menu::main);
|
||||
if (m_prev_selected == nullptr)
|
||||
{
|
||||
selected = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int x = 0; x < item.size(); ++x)
|
||||
if (item[x].ref == m_prev_selected)
|
||||
selected = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// load custom filters info from file
|
||||
//-------------------------------------------------
|
||||
@ -1940,4 +1649,41 @@ void menu_select_software::get_selection(ui_software_info const *&software, game
|
||||
driver = software ? software->driver : nullptr;
|
||||
}
|
||||
|
||||
|
||||
void menu_select_software::make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const
|
||||
{
|
||||
// determine the text for the header
|
||||
int vis_item = (m_search[0] != 0) ? visible_items : (m_has_empty_start ? visible_items - 1 : visible_items);
|
||||
line0 = string_format(_("%1$s %2$s ( %3$d / %4$d software packages )"), emulator_info::get_appname(), bare_build_version, vis_item, m_swinfo.size() - 1);
|
||||
line1 = string_format(_("Driver: \"%1$s\" software list "), m_driver->description);
|
||||
|
||||
std::string filtered;
|
||||
if (sw_filters::actual == UI_SW_REGION && m_filter.region.ui.size() != 0)
|
||||
filtered = string_format(_("Region: %1$s -"), m_filter.region.ui[m_filter.region.actual]);
|
||||
else if (sw_filters::actual == UI_SW_PUBLISHERS)
|
||||
filtered = string_format(_("Publisher: %1$s -"), m_filter.publisher.ui[m_filter.publisher.actual]);
|
||||
else if (sw_filters::actual == UI_SW_YEARS)
|
||||
filtered = string_format(_("Year: %1$s -"), m_filter.year.ui[m_filter.year.actual]);
|
||||
else if (sw_filters::actual == UI_SW_LIST)
|
||||
filtered = string_format(_("Software List: %1$s -"), m_filter.swlist.description[m_filter.swlist.actual]);
|
||||
else if (sw_filters::actual == UI_SW_TYPE)
|
||||
filtered = string_format(_("Device type: %1$s -"), m_filter.type.ui[m_filter.type.actual]);
|
||||
|
||||
line2 = string_format(_("%s Search: %s_"), filtered, m_search);
|
||||
}
|
||||
|
||||
|
||||
std::string menu_select_software::make_driver_description(game_driver const &driver) const
|
||||
{
|
||||
// first line is game description
|
||||
return string_format(_("%1$-.100s"), driver.description);
|
||||
}
|
||||
|
||||
|
||||
std::string menu_select_software::make_software_description(ui_software_info const &software) const
|
||||
{
|
||||
// first line is long name
|
||||
return string_format(_("%1$-.100s"), software.longname);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -27,7 +27,6 @@ public:
|
||||
virtual ~menu_select_software() override;
|
||||
|
||||
protected:
|
||||
virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
|
||||
virtual bool menu_has_search_active() override { return (m_search[0] != 0); }
|
||||
|
||||
private:
|
||||
@ -47,6 +46,11 @@ private:
|
||||
// get selected software and/or driver
|
||||
virtual void get_selection(ui_software_info const *&software, game_driver const *&driver) const override;
|
||||
|
||||
// text for main top/bottom panels
|
||||
virtual void make_topbox_text(std::string &line0, std::string &line1, std::string &line2) const override;
|
||||
virtual std::string make_driver_description(game_driver const &driver) const override;
|
||||
virtual std::string make_software_description(ui_software_info const &software) const override;
|
||||
|
||||
ui_software_info *m_searchlist[VISIBLE_GAMES_IN_SEARCH + 1];
|
||||
std::vector<ui_software_info *> m_displaylist, m_tmp, m_sortedlist;
|
||||
std::vector<ui_software_info> m_swinfo;
|
||||
@ -62,7 +66,6 @@ private:
|
||||
// handlers
|
||||
void inkey_select(const event *menu_event);
|
||||
void inkey_special(const event *menu_event);
|
||||
void inkey_navigation();
|
||||
};
|
||||
|
||||
class software_parts : public menu
|
||||
|
Loading…
Reference in New Issue
Block a user