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:
Vas Crabb 2016-07-15 22:24:34 +10:00
parent 200adb341a
commit ce0162de56
10 changed files with 732 additions and 939 deletions

View File

@ -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();
}
}

View File

@ -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;
};

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
//-------------------------------------------------

View File

@ -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);

View File

@ -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

View File

@ -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