516 lines
18 KiB
C++
516 lines
18 KiB
C++
|
#include "io.h"
|
||
|
|
||
|
#include <external/robin_hood.h>
|
||
|
|
||
|
#include "bbc/io.h"
|
||
|
#include "bs/io.h"
|
||
|
#include "ddr/io.h"
|
||
|
#include "dea/io.h"
|
||
|
#include "drs/io.h"
|
||
|
#include "ftt/io.h"
|
||
|
#include "gitadora/io.h"
|
||
|
#include "hpm/io.h"
|
||
|
#include "iidx/io.h"
|
||
|
#include "jb/io.h"
|
||
|
#include "launcher/launcher.h"
|
||
|
#include "launcher/options.h"
|
||
|
#include "loveplus/io.h"
|
||
|
#include "mfc/io.h"
|
||
|
#include "mga/io.h"
|
||
|
#include "museca/io.h"
|
||
|
#include "nost/io.h"
|
||
|
#include "otoca/io.h"
|
||
|
#include "popn/io.h"
|
||
|
#include "qma/io.h"
|
||
|
#include "rb/io.h"
|
||
|
#include "rf3d/io.h"
|
||
|
#include "sc/io.h"
|
||
|
#include "scotto/io.h"
|
||
|
#include "sdvx/io.h"
|
||
|
#include "shogikai/io.h"
|
||
|
#include "silentscope/io.h"
|
||
|
#include "we/io.h"
|
||
|
#include "pcm/io.h"
|
||
|
#include "onpara/io.h"
|
||
|
#include "bc/io.h"
|
||
|
#include "ccj/io.h"
|
||
|
#include "qks/io.h"
|
||
|
|
||
|
namespace games {
|
||
|
|
||
|
// state
|
||
|
static bool IO_INITIALIZED = false;
|
||
|
static std::vector<std::string> games;
|
||
|
static robin_hood::unordered_map<std::string, std::vector<Button> &> buttons;
|
||
|
static robin_hood::unordered_map<std::string, std::vector<Button>> buttons_keypads;
|
||
|
static robin_hood::unordered_map<std::string, std::vector<Button>> buttons_overlay;
|
||
|
static robin_hood::unordered_map<std::string, std::vector<Analog> &> analogs;
|
||
|
static robin_hood::unordered_map<std::string, std::vector<Light> &> lights;
|
||
|
static robin_hood::unordered_map<std::string, std::vector<Option>> options;
|
||
|
static robin_hood::unordered_map<std::string, std::vector<std::string>> file_hints;
|
||
|
|
||
|
static void initialize() {
|
||
|
|
||
|
// check if already done
|
||
|
if (IO_INITIALIZED) {
|
||
|
return;
|
||
|
}
|
||
|
IO_INITIALIZED = true;
|
||
|
|
||
|
// bbc
|
||
|
const std::string bbc("Bishi Bashi Channel");
|
||
|
games.push_back(bbc);
|
||
|
buttons.insert({ bbc, bbc::get_buttons() });
|
||
|
analogs.insert({ bbc, bbc::get_analogs() });
|
||
|
lights.insert({ bbc, bbc::get_lights() });
|
||
|
file_hints[bbc].emplace_back("bsch.dll");
|
||
|
|
||
|
// hpm
|
||
|
const std::string hpm("HELLO! Pop'n Music");
|
||
|
games.push_back(hpm);
|
||
|
buttons.insert({ hpm, hpm::get_buttons() });
|
||
|
lights.insert({ hpm, hpm::get_lights() });
|
||
|
file_hints[hpm].emplace_back("popn.dll");
|
||
|
|
||
|
// bs
|
||
|
const std::string bs("Beatstream");
|
||
|
games.push_back(bs);
|
||
|
buttons.insert({ bs, bs::get_buttons() });
|
||
|
lights.insert({ bs, bs::get_lights() });
|
||
|
file_hints[bs].emplace_back("beatstream.dll");
|
||
|
file_hints[bs].emplace_back("beatstream1.dll");
|
||
|
file_hints[bs].emplace_back("beatstream2.dll");
|
||
|
|
||
|
// ddr
|
||
|
const std::string ddr("Dance Dance Revolution");
|
||
|
games.push_back(ddr);
|
||
|
buttons.insert({ ddr, ddr::get_buttons() });
|
||
|
lights.insert({ ddr, ddr::get_lights() });
|
||
|
file_hints[ddr].emplace_back("ddr.dll");
|
||
|
file_hints[ddr].emplace_back("mdxja_945.dll");
|
||
|
file_hints[ddr].emplace_back("arkmdxp3.dll");
|
||
|
|
||
|
// dea
|
||
|
const std::string dea("Dance Evolution");
|
||
|
games.push_back(dea);
|
||
|
buttons.insert({ dea, dea::get_buttons() });
|
||
|
lights.insert({ dea, dea::get_lights() });
|
||
|
file_hints[dea].emplace_back("arkkdm.dll");
|
||
|
|
||
|
// gitadora
|
||
|
const std::string gitadora("GitaDora");
|
||
|
games.push_back(gitadora);
|
||
|
buttons.insert({ gitadora, gitadora::get_buttons() });
|
||
|
analogs.insert({ gitadora, gitadora::get_analogs() });
|
||
|
lights.insert({ gitadora, gitadora::get_lights() });
|
||
|
file_hints[gitadora].emplace_back("gdxg.dll");
|
||
|
|
||
|
// iidx
|
||
|
const std::string iidx("Beatmania IIDX");
|
||
|
games.push_back(iidx);
|
||
|
buttons.insert({ iidx, iidx::get_buttons() });
|
||
|
analogs.insert({ iidx, iidx::get_analogs() });
|
||
|
lights.insert({ iidx, iidx::get_lights() });
|
||
|
file_hints[iidx].emplace_back("bm2dx.dll");
|
||
|
|
||
|
// jb
|
||
|
const std::string jb("Jubeat");
|
||
|
games.push_back(jb);
|
||
|
buttons.insert({ jb, jb::get_buttons() });
|
||
|
lights.insert({ jb, jb::get_lights() });
|
||
|
file_hints[jb].emplace_back("jubeat.dll");
|
||
|
|
||
|
// mga
|
||
|
const std::string mga("Metal Gear");
|
||
|
games.push_back(mga);
|
||
|
buttons.insert({ mga, mga::get_buttons() });
|
||
|
analogs.insert({ mga, mga::get_analogs() });
|
||
|
lights.insert({ mga, mga::get_lights() });
|
||
|
file_hints[mga].emplace_back("launch.dll");
|
||
|
|
||
|
// museca
|
||
|
const std::string museca("Museca");
|
||
|
games.push_back(museca);
|
||
|
buttons.insert({ museca, museca::get_buttons() });
|
||
|
analogs.insert({ museca, museca::get_analogs() });
|
||
|
lights.insert({ museca, museca::get_lights() });
|
||
|
file_hints[museca].emplace_back("museca.dll");
|
||
|
|
||
|
// nost
|
||
|
const std::string nost("Nostalgia");
|
||
|
games.push_back(nost);
|
||
|
buttons.insert({ nost, nost::get_buttons() });
|
||
|
analogs.insert({ nost, nost::get_analogs() });
|
||
|
lights.insert({ nost, nost::get_lights() });
|
||
|
file_hints[nost].emplace_back("nostalgia.dll");
|
||
|
|
||
|
// popn
|
||
|
const std::string popn("Pop'n Music");
|
||
|
games.push_back(popn);
|
||
|
buttons.insert({ popn, popn::get_buttons() });
|
||
|
lights.insert({ popn, popn::get_lights() });
|
||
|
file_hints[popn].emplace_back("popn19.dll");
|
||
|
file_hints[popn].emplace_back("popn20.dll");
|
||
|
file_hints[popn].emplace_back("popn21.dll");
|
||
|
file_hints[popn].emplace_back("popn22.dll");
|
||
|
file_hints[popn].emplace_back("popn23.dll");
|
||
|
file_hints[popn].emplace_back("popn24.dll");
|
||
|
file_hints[popn].emplace_back("popn25.dll");
|
||
|
|
||
|
// qma
|
||
|
const std::string qma("Quiz Magic Academy");
|
||
|
games.push_back(qma);
|
||
|
buttons.insert({ qma, qma::get_buttons() });
|
||
|
lights.insert({ qma, qma::get_lights() });
|
||
|
file_hints[qma].emplace_back("client.dll");
|
||
|
|
||
|
// rb
|
||
|
const std::string rb("Reflec Beat");
|
||
|
games.push_back(rb);
|
||
|
buttons.insert({ rb, rb::get_buttons() });
|
||
|
lights.insert({ rb, rb::get_lights() });
|
||
|
file_hints[rb].emplace_back("reflecbeat.dll");
|
||
|
|
||
|
// shogikai
|
||
|
std::string shogikai("Tenkaichi Shogikai");
|
||
|
games.push_back(shogikai);
|
||
|
buttons.insert({ shogikai, shogikai::get_buttons() });
|
||
|
lights.insert({ shogikai, shogikai::get_lights() });
|
||
|
file_hints[shogikai].emplace_back("shogi_engine.dll");
|
||
|
|
||
|
// rf3d
|
||
|
const std::string rf3d("Road Fighters 3D");
|
||
|
games.push_back(rf3d);
|
||
|
buttons.insert({ rf3d, rf3d::get_buttons() });
|
||
|
analogs.insert({ rf3d, rf3d::get_analogs() });
|
||
|
file_hints[rf3d].emplace_back("jgt.dll");
|
||
|
|
||
|
// sc
|
||
|
const std::string sc("Steel Chronicle");
|
||
|
games.push_back(sc);
|
||
|
buttons.insert({ sc, sc::get_buttons() });
|
||
|
analogs.insert({ sc, sc::get_analogs() });
|
||
|
lights.insert({ sc, sc::get_lights() });
|
||
|
file_hints[sc].emplace_back("gamekgg.dll");
|
||
|
|
||
|
// sdvx
|
||
|
const std::string sdvx("Sound Voltex");
|
||
|
games.push_back(sdvx);
|
||
|
buttons.insert({ sdvx, sdvx::get_buttons() });
|
||
|
analogs.insert({ sdvx, sdvx::get_analogs() });
|
||
|
lights.insert({ sdvx, sdvx::get_lights() });
|
||
|
file_hints[sdvx].emplace_back("soundvoltex.dll");
|
||
|
|
||
|
// mfc
|
||
|
const std::string mfc("Mahjong Fight Club");
|
||
|
games.push_back(mfc);
|
||
|
buttons.insert({ mfc, mfc::get_buttons() });
|
||
|
file_hints[mfc].emplace_back("allinone.dll");
|
||
|
|
||
|
// ftt
|
||
|
const std::string ftt("FutureTomTom");
|
||
|
games.push_back(ftt);
|
||
|
buttons.insert({ ftt, ftt::get_buttons() });
|
||
|
analogs.insert({ ftt, ftt::get_analogs() });
|
||
|
lights.insert({ ftt, ftt::get_lights() });
|
||
|
file_hints[ftt].emplace_back("arkmmd.dll");
|
||
|
|
||
|
// loveplus
|
||
|
const std::string loveplus("LovePlus");
|
||
|
games.push_back(loveplus);
|
||
|
buttons.insert({ loveplus, loveplus::get_buttons() });
|
||
|
lights.insert({ loveplus, loveplus::get_lights() });
|
||
|
file_hints[loveplus].emplace_back("arkklp.dll");
|
||
|
|
||
|
// scotto
|
||
|
const std::string scotto("Scotto");
|
||
|
games.push_back(scotto);
|
||
|
buttons.insert({ scotto, scotto::get_buttons() });
|
||
|
lights.insert({ scotto, scotto::get_lights() });
|
||
|
file_hints[scotto].emplace_back("scotto.dll");
|
||
|
|
||
|
// drs
|
||
|
const std::string drs("DANCERUSH");
|
||
|
games.push_back(drs);
|
||
|
buttons.insert({ drs, drs::get_buttons() });
|
||
|
lights.insert({ drs, drs::get_lights() });
|
||
|
file_hints[drs].emplace_back("superstep.dll");
|
||
|
|
||
|
// otoca
|
||
|
const std::string otoca("Otoca D'or");
|
||
|
games.push_back(otoca);
|
||
|
buttons.insert({ otoca, otoca::get_buttons() });
|
||
|
file_hints[otoca].emplace_back("arkkep.dll");
|
||
|
|
||
|
// winning eleven
|
||
|
const std::string we("Winning Eleven");
|
||
|
games.push_back(we);
|
||
|
buttons.insert({ we, we::get_buttons() });
|
||
|
analogs.insert({ we, we::get_analogs() });
|
||
|
lights.insert({ we, we::get_lights() });
|
||
|
file_hints[we].emplace_back("weac12_bootstrap_release.dll");
|
||
|
file_hints[we].emplace_back("arknck.dll");
|
||
|
|
||
|
// silent scope: bone eater
|
||
|
const std::string silentscope("Silent Scope: Bone Eater");
|
||
|
games.push_back(silentscope);
|
||
|
buttons.insert({ silentscope, silentscope::get_buttons() });
|
||
|
analogs.insert({ silentscope, silentscope::get_analogs() });
|
||
|
file_hints[silentscope].emplace_back("arkndd.dll");
|
||
|
|
||
|
// charge machine
|
||
|
const std::string pcm("Charge Machine");
|
||
|
games.push_back(pcm);
|
||
|
buttons.insert({ pcm, pcm::get_buttons() });
|
||
|
file_hints[pcm].emplace_back("launch.dll");
|
||
|
|
||
|
// ongaku paradise
|
||
|
const std::string op("Ongaku Paradise");
|
||
|
games.push_back(op);
|
||
|
buttons.insert({ op, onpara::get_buttons() });
|
||
|
file_hints[op].emplace_back("arkjc9.dll");
|
||
|
|
||
|
// bc
|
||
|
const std::string bc("Busou Shinki: Armored Princess Battle Conductor");
|
||
|
games.push_back(bc);
|
||
|
buttons.insert({ bc, bc::get_buttons() });
|
||
|
analogs.insert({ bc, bc::get_analogs() });
|
||
|
file_hints[bc].emplace_back("game/bsac_app.exe");
|
||
|
|
||
|
// ccj
|
||
|
const std::string ccj("Chase Chase Jokers");
|
||
|
games.push_back(ccj);
|
||
|
buttons.insert({ ccj, ccj::get_buttons() });
|
||
|
analogs.insert({ ccj, ccj::get_analogs() });
|
||
|
lights.insert({ ccj, ccj::get_lights() });
|
||
|
file_hints[ccj].emplace_back("game/chaseproject.exe");
|
||
|
|
||
|
// QuizKnock STADIUM
|
||
|
const std::string qks("QuizKnock STADIUM");
|
||
|
games.push_back(qks);
|
||
|
buttons.insert({ qks, qks::get_buttons() });
|
||
|
file_hints[qks].emplace_back("game/uks.exe");
|
||
|
}
|
||
|
|
||
|
const std::vector<std::string> &get_games() {
|
||
|
initialize();
|
||
|
|
||
|
return games;
|
||
|
}
|
||
|
|
||
|
std::vector<Button> *get_buttons(const std::string &game) {
|
||
|
initialize();
|
||
|
auto it = buttons.find(game);
|
||
|
if (it == buttons.end()) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
return &it->second;
|
||
|
}
|
||
|
|
||
|
static std::vector<Button> gen_buttons_keypads(const std::string &game) {
|
||
|
auto buttons = GameAPI::Buttons::getButtons(game);
|
||
|
std::vector<std::string> names;
|
||
|
std::vector<unsigned short> vkey_defaults;
|
||
|
|
||
|
// loop for 2 keypad units, only setting defaults for keypad 1
|
||
|
for (size_t unit = 0; unit < 2; unit++) {
|
||
|
std::string prefix = unit == 0 ? "P1 Keypad " : "P2 Keypad ";
|
||
|
|
||
|
names.emplace_back(prefix + "0");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD0 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "1");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD1 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "2");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD2 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "3");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD3 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "4");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD4 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "5");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD5 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "6");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD6 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "7");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD7 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "8");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD8 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "9");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_NUMPAD9 : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "00");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_RETURN : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "Decimal");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_DECIMAL : 0xFF);
|
||
|
|
||
|
names.emplace_back(prefix + "Insert Card");
|
||
|
vkey_defaults.push_back(unit == 0 ? VK_ADD : 0xFF);
|
||
|
}
|
||
|
|
||
|
// return sorted buttons
|
||
|
buttons = GameAPI::Buttons::sortButtons(buttons, names, &vkey_defaults);
|
||
|
return buttons;
|
||
|
}
|
||
|
|
||
|
std::vector<Button> *get_buttons_keypads(const std::string &game) {
|
||
|
initialize();
|
||
|
auto it = buttons_keypads.find(game);
|
||
|
if (it == buttons_keypads.end()) {
|
||
|
if (game.empty()) {
|
||
|
return nullptr;
|
||
|
} else {
|
||
|
buttons_keypads[game] = gen_buttons_keypads(game);
|
||
|
return &buttons_keypads[game];
|
||
|
}
|
||
|
}
|
||
|
return &it->second;
|
||
|
}
|
||
|
|
||
|
static std::vector<Button> gen_buttons_overlay(const std::string &game) {
|
||
|
|
||
|
// get buttons
|
||
|
auto buttons = GameAPI::Buttons::getButtons(game);
|
||
|
std::vector<std::string> names;
|
||
|
std::vector<unsigned short> vkey_defaults;
|
||
|
|
||
|
// overlay button definitions
|
||
|
names.emplace_back("Screenshot");
|
||
|
vkey_defaults.push_back(VK_SNAPSHOT);
|
||
|
names.emplace_back("Toggle Sub Screen");
|
||
|
vkey_defaults.push_back(VK_PRIOR);
|
||
|
names.emplace_back("Insert Coin");
|
||
|
vkey_defaults.push_back(VK_F1);
|
||
|
names.emplace_back("Toggle IO Panel");
|
||
|
vkey_defaults.push_back(VK_F2);
|
||
|
names.emplace_back("Toggle Config");
|
||
|
vkey_defaults.push_back(VK_F4);
|
||
|
names.emplace_back("Toggle Virtual Keypad P1");
|
||
|
vkey_defaults.push_back(VK_F5);
|
||
|
names.emplace_back("Toggle Virtual Keypad P2");
|
||
|
vkey_defaults.push_back(VK_F6);
|
||
|
names.emplace_back("Toggle Card Manager");
|
||
|
vkey_defaults.push_back(VK_F7);
|
||
|
names.emplace_back("Toggle Log");
|
||
|
vkey_defaults.push_back(VK_F8);
|
||
|
names.emplace_back("Toggle Control");
|
||
|
vkey_defaults.push_back(VK_F9);
|
||
|
names.emplace_back("Toggle Patch Manager");
|
||
|
vkey_defaults.push_back(VK_F10);
|
||
|
names.emplace_back("Toggle Screen Resize");
|
||
|
vkey_defaults.push_back(VK_F11);
|
||
|
names.emplace_back("Toggle Overlay");
|
||
|
vkey_defaults.push_back(VK_F12);
|
||
|
names.emplace_back("Toggle VR Control");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Toggle Camera Control");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Screen Resize");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Force Exit Game");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Navigator Activate");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Navigator Cancel");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Navigator Up");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Navigator Down");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Navigator Left");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Navigator Right");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Hotkey Enable 1");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Hotkey Enable 2");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
names.emplace_back("Hotkey Toggle");
|
||
|
vkey_defaults.push_back(0xFF);
|
||
|
|
||
|
// return sorted buttons
|
||
|
buttons = GameAPI::Buttons::sortButtons(buttons, names, &vkey_defaults);
|
||
|
return buttons;
|
||
|
}
|
||
|
|
||
|
std::vector<Button> *get_buttons_overlay(const std::string &game) {
|
||
|
initialize();
|
||
|
auto it = buttons_overlay.find(game);
|
||
|
if (it == buttons_overlay.end()) {
|
||
|
if (game.empty()) {
|
||
|
return nullptr;
|
||
|
} else {
|
||
|
buttons_overlay[game] = gen_buttons_overlay(game);
|
||
|
return &buttons_overlay[game];
|
||
|
}
|
||
|
}
|
||
|
return &it->second;
|
||
|
}
|
||
|
|
||
|
std::vector<Analog> *get_analogs(const std::string &game) {
|
||
|
initialize();
|
||
|
auto it = analogs.find(game);
|
||
|
if (it == analogs.end()) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
return &it->second;
|
||
|
}
|
||
|
|
||
|
std::vector<Light> *get_lights(const std::string &game) {
|
||
|
initialize();
|
||
|
auto it = lights.find(game);
|
||
|
if (it == lights.end()) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
return &it->second;
|
||
|
}
|
||
|
|
||
|
static std::vector<Option> gen_options(const std::string &game) {
|
||
|
|
||
|
// get options
|
||
|
auto options = GameAPI::Options::getOptions(game);
|
||
|
|
||
|
// sort options
|
||
|
GameAPI::Options::sortOptions(options, launcher::get_option_definitions());
|
||
|
|
||
|
// merge options
|
||
|
auto merged = launcher::merge_options(options, *LAUNCHER_OPTIONS);
|
||
|
|
||
|
// return result
|
||
|
return merged;
|
||
|
}
|
||
|
|
||
|
std::vector<Option> *get_options(const std::string &game) {
|
||
|
initialize();
|
||
|
|
||
|
if (game.empty()) {
|
||
|
return LAUNCHER_OPTIONS.get();
|
||
|
}
|
||
|
|
||
|
auto it = options.find(game);
|
||
|
if (it == options.end()) {
|
||
|
options[game] = gen_options(game);
|
||
|
return &options[game];
|
||
|
}
|
||
|
|
||
|
return &it->second;
|
||
|
}
|
||
|
|
||
|
std::vector<std::string> *get_game_file_hints(const std::string &game) {
|
||
|
initialize();
|
||
|
auto it = file_hints.find(game);
|
||
|
if (it == file_hints.end()) {
|
||
|
return nullptr;
|
||
|
}
|
||
|
return &it->second;
|
||
|
}
|
||
|
}
|