diff options
Diffstat (limited to 'src/emu/ui/datfile.cpp')
-rw-r--r-- | src/emu/ui/datfile.cpp | 642 |
1 files changed, 642 insertions, 0 deletions
diff --git a/src/emu/ui/datfile.cpp b/src/emu/ui/datfile.cpp new file mode 100644 index 00000000000..f0e938fbd4d --- /dev/null +++ b/src/emu/ui/datfile.cpp @@ -0,0 +1,642 @@ +// license:BSD-3-Clause +// copyright-holders:Dankan1890 +/*************************************************************************** + + mewui/datfile.cpp + + MEWUI DATs manager. + +***************************************************************************/ + +#include "emu.h" +#include "drivenum.h" +#include "ui/datfile.h" +#include "ui/utils.h" + +//------------------------------------------------- +// TAGS +//------------------------------------------------- +static std::string DATAFILE_TAG("$"); +static std::string TAG_BIO("$bio"); +static std::string TAG_INFO("$info"); +static std::string TAG_MAME("$mame"); +static std::string TAG_COMMAND("$cmd"); +static std::string TAG_END("$end"); +static std::string TAG_DRIVER("$drv"); +static std::string TAG_STORY("$story"); +static std::string TAG_HISTORY_R("## REVISION:"); +static std::string TAG_MAMEINFO_R("# MAMEINFO.DAT"); +static std::string TAG_MESSINFO_R("# MESSINFO.DAT"); +static std::string TAG_SYSINFO_R("# This file was generated on"); +static std::string TAG_STORY_R("# version"); +static std::string TAG_COMMAND_SEPARATOR("-----------------------------------------------"); + +//------------------------------------------------- +// Statics +//------------------------------------------------- +datfile_manager::dataindex datfile_manager::m_histidx; +datfile_manager::dataindex datfile_manager::m_mameidx; +datfile_manager::dataindex datfile_manager::m_messidx; +datfile_manager::dataindex datfile_manager::m_cmdidx; +datfile_manager::dataindex datfile_manager::m_sysidx; +datfile_manager::dataindex datfile_manager::m_storyidx; +datfile_manager::drvindex datfile_manager::m_drvidx; +datfile_manager::drvindex datfile_manager::m_messdrvidx; +datfile_manager::drvindex datfile_manager::m_menuidx; +datfile_manager::swindex datfile_manager::m_swindex; +std::string datfile_manager::m_history_rev; +std::string datfile_manager::m_mame_rev; +std::string datfile_manager::m_mess_rev; +std::string datfile_manager::m_sysinfo_rev; +std::string datfile_manager::m_story_rev; +bool datfile_manager::first_run = true; + +//------------------------------------------------- +// ctor +//------------------------------------------------- +datfile_manager::datfile_manager(running_machine &machine) : m_machine(machine) +{ + if (machine.options().enabled_dats() && first_run) + { + first_run = false; + if (parseopen("mameinfo.dat")) + { + init_mameinfo(); + parseclose(); + } + + if (parseopen("command.dat")) + { + init_command(); + parseclose(); + } + + if (parseopen("story.dat")) + { + init_storyinfo(); + parseclose(); + } + + if (parseopen("messinfo.dat")) + { + init_messinfo(); + parseclose(); + } + + if (parseopen("sysinfo.dat")) + { + init_sysinfo(); + parseclose(); + } + + if (parseopen("history.dat")) + { + init_history(); + parseclose(); + } + } +} + +//------------------------------------------------- +// initialize sysinfo.dat index +//------------------------------------------------- +void datfile_manager::init_sysinfo() +{ + int swcount = 0; + int count = index_datafile(m_sysidx, swcount); + osd_printf_verbose("Sysinfo.dat games found = %i\n", count); + osd_printf_verbose("Rev = %s\n", m_sysinfo_rev.c_str()); +} + +//------------------------------------------------- +// initialize story.dat index +//------------------------------------------------- +void datfile_manager::init_storyinfo() +{ + int swcount = 0; + int count = index_datafile(m_storyidx, swcount); + osd_printf_verbose("Story.dat games found = %i\n", count); +} + +//------------------------------------------------- +// initialize history.dat index +//------------------------------------------------- +void datfile_manager::init_history() +{ + int swcount = 0; + int count = index_datafile(m_histidx, swcount); + osd_printf_verbose("History.dat games found = %i\n", count); + osd_printf_verbose("History.dat softwares found = %i\n", swcount); + osd_printf_verbose("Rev = %s\n", m_history_rev.c_str()); +} + +//------------------------------------------------- +// initialize mameinfo.dat index +//------------------------------------------------- +void datfile_manager::init_mameinfo() +{ + int drvcount = 0; + int count = index_mame_mess_info(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()); +} + +//------------------------------------------------- +// initialize messinfo.dat index +//------------------------------------------------- +void datfile_manager::init_messinfo() +{ + int drvcount = 0; + int count = index_mame_mess_info(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()); +} + +//------------------------------------------------- +// initialize command.dat index +//------------------------------------------------- +void datfile_manager::init_command() +{ + int swcount = 0; + int count = index_datafile(m_cmdidx, swcount); + osd_printf_verbose("Command.dat games found = %i\n", count); +} + +//------------------------------------------------- +// load software info +//------------------------------------------------- +void datfile_manager::load_software_info(std::string &softlist, std::string &buffer, std::string &softname, std::string &parentname) +{ + // Load history text + if (!m_swindex.empty() && parseopen("history.dat")) + { + // Find software in software list index + if (m_swindex.find(softlist) == m_swindex.end()) + return; + + drvindex::iterator itemsiter; + itemsiter = m_swindex[softlist].find(softname); + if (itemsiter == m_swindex[softlist].end() && !parentname.empty()) + itemsiter = m_swindex[softlist].find(parentname); + + if (itemsiter == m_swindex[softlist].end()) + return; + + long s_offset = (*itemsiter).second; + char rbuf[64 * 1024]; + fseek(fp, s_offset, SEEK_SET); + std::string readbuf; + while (fgets(rbuf, 64 * 1024, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + + // end entry when a end tag is encountered + if (readbuf == TAG_END) + break; + + // add this string to the buffer + buffer.append(readbuf).append("\n"); + } + parseclose(); + } +} + +//------------------------------------------------- +// load_data_info +//------------------------------------------------- +void datfile_manager::load_data_info(const game_driver *drv, std::string &buffer, int type) +{ + dataindex index_idx; + drvindex driver_idx; + std::string tag; + std::string filename; + + switch (type) + { + case MEWUI_HISTORY_LOAD: + filename = "history.dat"; + tag = TAG_BIO; + index_idx = m_histidx; + break; + case MEWUI_MAMEINFO_LOAD: + filename = "mameinfo.dat"; + tag = TAG_MAME; + index_idx = m_mameidx; + driver_idx = m_drvidx; + break; + case MEWUI_SYSINFO_LOAD: + filename = "sysinfo.dat"; + tag = TAG_BIO; + index_idx = m_sysidx; + break; + case MEWUI_MESSINFO_LOAD: + filename = "messinfo.dat"; + tag = TAG_MAME; + index_idx = m_messidx; + driver_idx = m_messdrvidx; + break; + case MEWUI_STORY_LOAD: + filename = "story.dat"; + tag = TAG_STORY; + index_idx = m_storyidx; + break; + } + + if (parseopen(filename.c_str())) + { + load_data_text(drv, buffer, index_idx, tag); + + // load driver info + if (!driver_idx.empty()) + load_driver_text(drv, buffer, driver_idx, TAG_DRIVER); + + // cleanup mameinfo and sysinfo double line spacing + if (tag == TAG_MAME || type == MEWUI_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 &tag) +{ + dataindex::iterator itemsiter = idx.find(drv); + if (itemsiter == idx.end()) + { + int cloneof = driver_list::non_bios_clone(*drv); + if (cloneof == -1) + return; + else + { + const game_driver *c_drv = &driver_list::driver(cloneof); + itemsiter = idx.find(c_drv); + if (itemsiter == idx.end()) + return; + } + } + + long s_offset = (*itemsiter).second; + fseek(fp, s_offset, SEEK_SET); + char rbuf[64 * 1024]; + std::string readbuf; + while (fgets(rbuf, 64 * 1024, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + + // end entry when a end tag is encountered + if (readbuf == TAG_END) + break; + + // continue if a specific tag is encountered + if (readbuf == tag) + continue; + + // add this string to the buffer + buffer.append(readbuf).append("\n"); + } +} + +//------------------------------------------------- +// 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 &tag) +{ + std::string s(core_filename_extract_base(drv->source_file)); + drvindex::const_iterator index = idx.find(s); + + // if driver not found, return + if (index == idx.end()) + return; + + buffer.append("\n--- DRIVER INFO ---\n").append("Driver: ").append(s).append("\n\n"); + long s_offset = (*index).second; + fseek(fp, s_offset, SEEK_SET); + char rbuf[64 * 1024]; + std::string readbuf; + while (fgets(rbuf, 64 * 1024, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + + // end entry when a end tag is encountered + if (readbuf == TAG_END) + break; + + // continue if a specific tag is encountered + if (readbuf == tag) + continue; + + // add this string to the buffer + buffer.append(readbuf).append("\n"); + } +} + +//------------------------------------------------- +// 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) +{ + std::string name; + size_t foundtag; + size_t t_mame = TAG_MAMEINFO_R.size(); + size_t t_mess = TAG_MESSINFO_R.size(); + size_t t_info = TAG_INFO.size(); + + char rbuf[64 * 1024]; + std::string readbuf, xid; + while (fgets(rbuf, 64 * 1024, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + if (m_mame_rev.empty() && readbuf.compare(0, t_mame, TAG_MAMEINFO_R) == 0) + { + size_t found = readbuf.find(" ", t_mame + 1); + m_mame_rev = readbuf.substr(t_mame + 1, found - t_mame); + } + else if (m_mess_rev.empty() && (foundtag = readbuf.find(TAG_MESSINFO_R)) != std::string::npos) + { + size_t found = readbuf.find(" ", foundtag + t_mess + 1); + m_mess_rev = readbuf.substr(foundtag + t_mess + 1, found - t_mess - foundtag); + } + else if (readbuf.compare(0, t_info, TAG_INFO) == 0) + { + // TAG_INFO + fgets(rbuf, 64 * 1024, fp); + xid = chartrimcarriage(rbuf); + name = readbuf.substr(t_info + 1); + if (xid == TAG_MAME) + { + // validate driver + int game_index = driver_list::find(name.c_str()); + if (game_index != -1) + index.emplace(&driver_list::driver(game_index), ftell(fp)); + } + else if (xid == TAG_DRIVER) + { + index_drv.emplace(name, ftell(fp)); + drvcount++; + } + } + } + return index.size(); +} + +//------------------------------------------------- +// load a game name and offset into an +// indexed array +//------------------------------------------------- +int datfile_manager::index_datafile(dataindex &index, int &swcount) +{ + std::string readbuf, name; + size_t t_hist = TAG_HISTORY_R.size(); + size_t t_story = TAG_STORY_R.size(); + size_t t_sysinfo = TAG_SYSINFO_R.size(); + size_t t_info = TAG_INFO.size(); + size_t t_bio = TAG_BIO.size(); + char rbuf[64 * 1024]; + while (fgets(rbuf, 64 * 1024, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + + if (m_history_rev.empty() && readbuf.compare(0, t_hist, TAG_HISTORY_R) == 0) + { + size_t found = readbuf.find(" ", t_hist + 1); + m_history_rev = readbuf.substr(t_hist + 1, found - t_hist); + } + else if (m_sysinfo_rev.empty() && readbuf.compare(0, t_sysinfo, TAG_SYSINFO_R) == 0) + { + size_t found = readbuf.find(".", t_sysinfo + 1); + m_sysinfo_rev = readbuf.substr(t_sysinfo + 1, found - t_sysinfo); + } + else if (m_story_rev.empty() && readbuf.compare(0, t_story, TAG_STORY_R) == 0) + m_story_rev = readbuf.substr(t_story + 1); + + // TAG_INFO identifies the driver + else if (readbuf.compare(0, t_info, TAG_INFO) == 0) + { + int curpoint = t_info + 1; + int ends = readbuf.size(); + while (curpoint < ends) + { + // search for comma + size_t found = readbuf.find(",", curpoint); + + // found it + if (found != std::string::npos) + { + // copy data and validate driver + name = readbuf.substr(curpoint, found - curpoint); + + // validate driver + int game_index = driver_list::find(name.c_str()); + if (game_index != -1) + index.emplace(&driver_list::driver(game_index), ftell(fp)); + + // update current point + curpoint = ++found; + } + // if comma not found, copy data while until reach the end of string + else if (curpoint < ends) + { + name = readbuf.substr(curpoint); + int game_index = driver_list::find(name.c_str()); + if (game_index != -1) + index.emplace(&driver_list::driver(game_index), ftell(fp)); + + // update current point + curpoint = ends; + } + } + } + // search for software info + else if (!readbuf.empty() && readbuf[0] == DATAFILE_TAG[0]) + { + fgets(rbuf, 64 * 1024, fp); + std::string readbuf_2(chartrimcarriage(rbuf)); + + // TAG_BIO identifies software list + if (readbuf_2.compare(0, t_bio, TAG_BIO) == 0) + { + size_t eq_sign = readbuf.find("="); + std::string s_list(readbuf.substr(1, eq_sign - 1)); + std::string s_roms(readbuf.substr(eq_sign + 1)); + int ends = s_list.size(); + int curpoint = 0; + + while (curpoint < ends) + { + size_t found = s_list.find(",", curpoint); + + // found it + if (found != std::string::npos) + { + name = s_list.substr(curpoint, found - curpoint); + curpoint = ++found; + } + else + { + name = s_list; + curpoint = ends; + } + + // search for a software list in the index, if not found then allocates + std::string lname(name); + int cpoint = 0; + int cends = s_roms.size(); + + while (cpoint < cends) + { + // search for comma + size_t found = s_roms.find(",", cpoint); + + // found it + if (found != std::string::npos) + { + // copy data + name = s_roms.substr(cpoint, found - cpoint); + + // add a SoftwareItem + m_swindex[lname].emplace(name, ftell(fp)); + + // update current point + cpoint = ++found; + swcount++; + } + else + { + // if reach the end, bail out + if (s_roms[cpoint] == '\r' || s_roms[cpoint] == '\n') + break; + + // copy data + name = s_roms.substr(cpoint); + + // add a SoftwareItem + m_swindex[lname].emplace(name, ftell(fp)); + + // update current point + cpoint = cends; + swcount++; + } + } + } + } + } + } + return index.size(); +} + +//--------------------------------------------------------- +// parseopen - Open up file for reading +//--------------------------------------------------------- +bool datfile_manager::parseopen(const char *filename) +{ + // MAME core file parsing functions fail in recognizing UNICODE chars in UTF-8 without BOM, + // so it's better and faster use standard C fileio functions. + + emu_file file(machine().options().history_path(), OPEN_FLAG_READ); + if (file.open(filename) != FILERR_NONE) + return false; + + m_fullpath = file.fullpath(); + file.close(); + fp = fopen(m_fullpath.c_str(), "rb"); + + fgetc(fp); + fseek(fp, 0, SEEK_SET); + return true; +} + +//------------------------------------------------- +// create the menu index +//------------------------------------------------- +void datfile_manager::index_menuidx(const game_driver *drv, dataindex &idx, drvindex &index) +{ + dataindex::iterator itemsiter = idx.find(drv); + if (itemsiter == idx.end()) + { + int cloneof = driver_list::non_bios_clone(*drv); + if (cloneof == -1) + return; + else + { + const game_driver *c_drv = &driver_list::driver(cloneof); + itemsiter = idx.find(c_drv); + if (itemsiter == idx.end()) + return; + } + } + + // seek to correct point in datafile + long s_offset = (*itemsiter).second; + fseek(fp, s_offset, SEEK_SET); + size_t tinfo = TAG_INFO.size(); + char rbuf[64 * 1024]; + std::string readbuf; + while (fgets(rbuf, 64 * 1024, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + + if (!core_strnicmp(TAG_INFO.c_str(), readbuf.c_str(), tinfo)) + break; + + // TAG_COMMAND identifies the driver + if (readbuf == TAG_COMMAND) + { + fgets(rbuf, 64 * 1024, fp); + chartrimcarriage(rbuf); + index.emplace(rbuf, ftell(fp)); + } + } +} + +//------------------------------------------------- +// load command text into the buffer +//------------------------------------------------- +void datfile_manager::load_command_info(std::string &buffer, std::string &sel) +{ + if (parseopen("command.dat")) + { + // open and seek to correct point in datafile + long offset = m_menuidx.at(sel); + fseek(fp, offset, SEEK_SET); + char rbuf[64 * 1024]; + std::string readbuf; + while (fgets(rbuf, 64 * 1024, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + + // skip separator lines + if (readbuf == TAG_COMMAND_SEPARATOR) + continue; + + // end entry when a tag is encountered + if (readbuf == TAG_END) + break; + + // add this string to the buffer + buffer.append(readbuf).append("\n");; + } + parseclose(); + } +} + +//------------------------------------------------- +// load submenu item for command.dat +//------------------------------------------------- +void datfile_manager::command_sub_menu(const game_driver *drv, std::vector<std::string> &menuitems) +{ + if (parseopen("command.dat")) + { + m_menuidx.clear(); + index_menuidx(drv, m_cmdidx, m_menuidx); + for (auto & elem : m_menuidx) + menuitems.push_back(elem.first); + parseclose(); + } +}
\ No newline at end of file |