diff options
author | 2016-02-04 14:44:49 +0100 | |
---|---|---|
committer | 2016-02-04 15:14:24 +0100 | |
commit | 701df7fe9ea4775b25c9d7263592cb3d442e2793 (patch) | |
tree | 6ce520fd10619b5f4146d9bff127d36f08a673ba /src/emu/ui/inifile.cpp | |
parent | 196e742a77f7719f61318c420e79ae08add25124 (diff) |
Initial import of MEWUI to MAME [Dankan1890]
Diffstat (limited to 'src/emu/ui/inifile.cpp')
-rw-r--r-- | src/emu/ui/inifile.cpp | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/src/emu/ui/inifile.cpp b/src/emu/ui/inifile.cpp new file mode 100644 index 00000000000..d261385b5cb --- /dev/null +++ b/src/emu/ui/inifile.cpp @@ -0,0 +1,453 @@ +// license:BSD-3-Clause +// copyright-holders:Dankan1890 +/*************************************************************************** + + mewui/inifile.cpp + + MEWUI INIs file manager. + +***************************************************************************/ + +#include "emu.h" +#include "ui/inifile.h" +#include "softlist.h" +#include "drivenum.h" +#include <algorithm> + +//------------------------------------------------- +// GLOBAL VARIABLES +//------------------------------------------------- +UINT16 inifile_manager::current_category = 0; +UINT16 inifile_manager::current_file = 0; + +//------------------------------------------------- +// ctor +//------------------------------------------------- + +inifile_manager::inifile_manager(running_machine &machine) + : m_machine(machine) +{ + ini_index.clear(); + directory_scan(); +} + +//------------------------------------------------- +// scan directories and create index +//------------------------------------------------- + +void inifile_manager::directory_scan() +{ + // open extra INIs folder + file_enumerator path(machine().options().extraini_path()); + const osd_directory_entry *dir; + + // loop into folder's file + while ((dir = path.next()) != nullptr) + { + int length = strlen(dir->name); + std::string filename(dir->name); + + // skip mewui_favorite file + if (!core_stricmp("mewui_favorite.ini", filename.c_str())) + continue; + + // check .ini file ending + if ((length > 4) && dir->name[length - 4] == '.' && tolower((UINT8)dir->name[length - 3]) == 'i' && + tolower((UINT8)dir->name[length - 2]) == 'n' && tolower((UINT8)dir->name[length - 1]) == 'i') + { + // try to open file and indexing + if (parseopen(filename.c_str())) + { + init_category(filename); + parseclose(); + } + } + } +} + +//------------------------------------------------- +// initialize category +//------------------------------------------------- + +void inifile_manager::init_category(std::string &filename) +{ + categoryindex index; + char rbuf[MAX_CHAR_INFO]; + std::string readbuf, name; + while (fgets(rbuf, MAX_CHAR_INFO, fp) != nullptr) + { + readbuf = rbuf; + if (readbuf[0] == '[') + { + size_t found = readbuf.find("]"); + name = readbuf.substr(1, found - 1); + if (name == "FOLDER_SETTINGS" || name == "ROOT_FOLDER") + continue; + else + index.emplace_back(name, ftell(fp)); + } + } + + if (!index.empty()) + ini_index.emplace_back(filename, index); +} + +//------------------------------------------------- +// load and indexing ini files +//------------------------------------------------- + +void inifile_manager::load_ini_category(std::vector<int> &temp_filter) +{ + if (ini_index.empty()) + return; + + bool search_clones = false; + std::string filename(ini_index[current_file].name); + long offset = ini_index[current_file].category[current_category].offset; + + if (!core_stricmp(filename.c_str(), "category.ini") || !core_stricmp(filename.c_str(), "alltime.ini")) + search_clones = true; + + if (parseopen(filename.c_str())) + { + fseek(fp, offset, SEEK_SET); + int num_game = driver_list::total(); + char rbuf[MAX_CHAR_INFO]; + std::string readbuf; + while (fgets(rbuf, MAX_CHAR_INFO, fp) != nullptr) + { + readbuf = chartrimcarriage(rbuf); + + if (readbuf.empty() || readbuf[0] == '[') + break; + + int dfind = driver_list::find(readbuf.c_str()); + if (dfind != -1 && search_clones) + { + temp_filter.push_back(dfind); + int clone_of = driver_list::non_bios_clone(dfind); + if (clone_of == -1) + { + for (int x = 0; x < num_game; x++) + if (readbuf == driver_list::driver(x).parent && readbuf != driver_list::driver(x).name) + temp_filter.push_back(x); + } + } + else if (dfind != -1) + temp_filter.push_back(dfind); + } + parseclose(); + } +} + +//--------------------------------------------------------- +// parseopen - Open up file for reading +//--------------------------------------------------------- + +bool inifile_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().extraini_path(), OPEN_FLAG_READ); + if (file.open(filename) != FILERR_NONE) + return false; + + m_fullpath = file.fullpath(); + file.close(); + fp = fopen(m_fullpath.c_str(), "r"); + + fgetc(fp); + fseek(fp, 0, SEEK_SET); + return true; +} + +/************************************************************************** + FAVORITE MANAGER +**************************************************************************/ + +//------------------------------------------------- +// ctor +//------------------------------------------------- + +favorite_manager::favorite_manager(running_machine &machine) + : m_machine(machine) +{ + m_current = -1; + parse_favorite(); +} + +//------------------------------------------------- +// add a game +//------------------------------------------------- + +void favorite_manager::add_favorite_game(const game_driver *driver) +{ + m_list.emplace_back(driver->name, driver->description, "", "", "", 0, "", driver, "", "", "", 1, "", "", "", true); + save_favorite_games(); +} + +//------------------------------------------------- +// add a system +//------------------------------------------------- + +void favorite_manager::add_favorite_game(ui_software_info &swinfo) +{ + m_list.push_back(swinfo); + save_favorite_games(); +} + +//------------------------------------------------- +// add a game / system +//------------------------------------------------- + +void favorite_manager::add_favorite_game() +{ + if ((machine().system().flags & MACHINE_TYPE_ARCADE) != 0) + { + add_favorite_game(&machine().system()); + return; + } + + bool software_avail = false; + image_interface_iterator iter(machine().root_device()); + for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next()) + { + if (image->exists() && image->software_entry()) + { + const software_info *swinfo = image->software_entry(); + const software_part *part = image->part_entry(); + ui_software_info tmpmatches; + tmpmatches.shortname = strensure(swinfo->shortname()); + tmpmatches.longname = strensure(image->longname()); + tmpmatches.parentname = strensure(swinfo->parentname()); + tmpmatches.year = strensure(image->year()); + tmpmatches.publisher = strensure(image->manufacturer()); + tmpmatches.supported = image->supported(); + tmpmatches.part = strensure(part->name()); + tmpmatches.driver = &machine().system(); + tmpmatches.listname = strensure(image->software_list_name()); + tmpmatches.interface = strensure(part->interface()); + tmpmatches.instance = strensure(image->instance_name()); + tmpmatches.startempty = 0; + tmpmatches.parentlongname.clear(); + if (swinfo->parentname()) + { + software_list_device *swlist = software_list_device::find_by_name(machine().config(), image->software_list_name()); + for (software_info *c_swinfo = swlist->first_software_info(); c_swinfo != nullptr; c_swinfo = c_swinfo->next()) + { + std::string c_parent(c_swinfo->parentname()); + if (!c_parent.empty() && c_parent == swinfo->shortname()) + { + tmpmatches.parentlongname = c_swinfo->longname(); + break; + } + } + } + + tmpmatches.usage.clear(); + for (feature_list_item *flist = swinfo->other_info(); flist != nullptr; flist = flist->next()) + if (!strcmp(flist->name(), "usage")) + tmpmatches.usage = flist->value(); + + tmpmatches.devicetype = strensure(image->image_type_name()); + tmpmatches.available = true; + software_avail = true; + m_list.push_back(tmpmatches); + save_favorite_games(); + } + } + + if (!software_avail) + add_favorite_game(&machine().system()); +} + +//------------------------------------------------- +// remove a favorite from list +//------------------------------------------------- + +void favorite_manager::remove_favorite_game(ui_software_info &swinfo) +{ + m_list.erase(std::remove(m_list.begin(), m_list.end(), swinfo), m_list.end()); + save_favorite_games(); +} + +//------------------------------------------------- +// remove a favorite from list +//------------------------------------------------- + +void favorite_manager::remove_favorite_game() +{ + m_list.erase(m_list.begin() + m_current); + save_favorite_games(); +} + +//------------------------------------------------- +// check if game is already in favorite list +//------------------------------------------------- + +bool favorite_manager::isgame_favorite() +{ + if ((machine().system().flags & MACHINE_TYPE_ARCADE) != 0) + return isgame_favorite(&machine().system()); + + image_interface_iterator iter(machine().root_device()); + bool image_loaded = false; + + for (device_image_interface *image = iter.first(); image != nullptr; image = iter.next()) + { + const software_info *swinfo = image->software_entry(); + if (image->exists() && swinfo != nullptr) + { + image_loaded = true; + for (size_t current = 0; current < m_list.size(); current++) + if (m_list[current].shortname == swinfo->shortname() && + m_list[current].listname == image->software_list_name()) + { + m_current = current; + return true; + } + } + } + + if (!image_loaded) + return isgame_favorite(&machine().system()); + + m_current = -1; + return false; +} + +//------------------------------------------------- +// check if game is already in favorite list +//------------------------------------------------- + +bool favorite_manager::isgame_favorite(const game_driver *driver) +{ + for (size_t x = 0; x < m_list.size(); x++) + if (m_list[x].driver == driver && m_list[x].shortname == driver->name) + { + m_current = x; + return true; + } + + m_current = -1; + return false; +} + +//------------------------------------------------- +// check if game is already in favorite list +//------------------------------------------------- + +bool favorite_manager::isgame_favorite(ui_software_info &swinfo) +{ + for (size_t x = 0; x < m_list.size(); x++) + if (m_list[x] == swinfo) + { + m_current = x; + return true; + } + + m_current = -1; + return false; +} + +//------------------------------------------------- +// parse favorite file +//------------------------------------------------- + +void favorite_manager::parse_favorite() +{ + emu_file file(machine().options().mewui_path(), OPEN_FLAG_READ); + if (file.open(favorite_filename) == FILERR_NONE) + { + char readbuf[1024]; + file.gets(readbuf, 1024); + + while (readbuf[0] == '[') + file.gets(readbuf, 1024); + + while (file.gets(readbuf, 1024)) + { + ui_software_info tmpmatches; + tmpmatches.shortname = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.longname = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.parentname = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.year = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.publisher = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.supported = atoi(readbuf); + file.gets(readbuf, 1024); + tmpmatches.part = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + chartrimcarriage(readbuf); + int dx = driver_list::find(readbuf); + if (dx == -1) continue; + tmpmatches.driver = &driver_list::driver(dx); + file.gets(readbuf, 1024); + tmpmatches.listname = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.interface = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.instance = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.startempty = atoi(readbuf); + file.gets(readbuf, 1024); + tmpmatches.parentlongname = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.usage = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.devicetype = chartrimcarriage(readbuf); + file.gets(readbuf, 1024); + tmpmatches.available = atoi(readbuf); + m_list.push_back(tmpmatches); + } + file.close(); + } +} + +//------------------------------------------------- +// save favorite +//------------------------------------------------- + +void favorite_manager::save_favorite_games() +{ + // attempt to open the output file + emu_file file(machine().options().mewui_path(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS); + if (file.open(favorite_filename) == FILERR_NONE) + { + if (m_list.empty()) + { + file.remove_on_close(); + file.close(); + return; + } + + // generate the favorite INI + std::string text("[ROOT_FOLDER]\n[Favorite]\n\n"); + for (auto & elem : m_list) + { + text += elem.shortname + "\n"; + text += elem.longname + "\n"; + text += elem.parentname + "\n"; + text += elem.year + "\n"; + text += elem.publisher + "\n"; + strcatprintf(text, "%d\n", elem.supported); + text += elem.part + "\n"; + strcatprintf(text, "%s\n", elem.driver->name); + text += elem.listname + "\n"; + text += elem.interface + "\n"; + text += elem.instance + "\n"; + strcatprintf(text, "%d\n", elem.startempty); + text += elem.parentlongname + "\n"; + text += elem.usage + "\n"; + text += elem.devicetype + "\n"; + strcatprintf(text, "%d\n", elem.available); + } + file.puts(text.c_str()); + file.close(); + } +} |