2016-08-10 03:28:40 +00:00
|
|
|
#ifndef INCLUDED_GAME_H
|
|
|
|
#define INCLUDED_GAME_H
|
|
|
|
|
|
|
|
#include "Util/NewConfig.h"
|
|
|
|
#include "Pkgs/unzip.h"
|
|
|
|
#include <map>
|
|
|
|
#include <set>
|
|
|
|
|
2016-08-18 04:19:36 +00:00
|
|
|
//TODO: separate Game and ROM structs
|
2016-08-10 03:28:40 +00:00
|
|
|
struct Game
|
|
|
|
{
|
2016-08-11 03:53:19 +00:00
|
|
|
std::string name;
|
2016-08-10 03:28:40 +00:00
|
|
|
std::string title;
|
|
|
|
std::string version;
|
|
|
|
std::string manufacturer;
|
2016-08-24 04:13:23 +00:00
|
|
|
unsigned year = 0;
|
2016-08-10 03:28:40 +00:00
|
|
|
std::string stepping;
|
2016-08-18 04:19:36 +00:00
|
|
|
std::string mpeg_board;
|
|
|
|
uint32_t encryption_key = 0;
|
|
|
|
enum Inputs
|
|
|
|
{
|
|
|
|
INPUT_UI = 0, // special code reserved for Supermodel UI inputs
|
|
|
|
INPUT_COMMON = 0x00000001, // common controls (coins, service, test)
|
|
|
|
INPUT_VEHICLE = 0x00000002, // vehicle controls
|
|
|
|
INPUT_JOYSTICK1 = 0x00000004, // joystick 1
|
|
|
|
INPUT_JOYSTICK2 = 0x00000008, // joystick 2
|
|
|
|
INPUT_FIGHTING = 0x00000010, // fighting game controls
|
|
|
|
INPUT_VR4 = 0x00000020, // four VR view buttons
|
|
|
|
INPUT_VIEWCHANGE = 0x00000040, // single view change button
|
|
|
|
INPUT_SHIFT4 = 0x00000080, // 4-speed shifter
|
|
|
|
INPUT_SHIFTUPDOWN = 0x00000100, // up/down shifter
|
|
|
|
INPUT_HANDBRAKE = 0x00000200, // handbrake
|
|
|
|
INPUT_HARLEY = 0x00000400, // Harley Davidson controls
|
|
|
|
INPUT_GUN1 = 0x00000800, // light gun 1
|
|
|
|
INPUT_GUN2 = 0x00001000, // light gun 2
|
|
|
|
INPUT_ANALOG_JOYSTICK = 0x00002000, // analog joystick
|
|
|
|
INPUT_TWIN_JOYSTICKS = 0x00004000, // twin joysticks
|
|
|
|
INPUT_SOCCER = 0x00008000, // soccer controls
|
|
|
|
INPUT_SPIKEOUT = 0x00010000, // Spikeout buttons
|
|
|
|
INPUT_ANALOG_GUN1 = 0x00020000, // analog gun 1
|
|
|
|
INPUT_ANALOG_GUN2 = 0x00040000, // analog gun 2
|
|
|
|
INPUT_SKI = 0x00080000, // ski controls
|
|
|
|
INPUT_MAGTRUCK = 0x00100000, // magical truck controls
|
|
|
|
INPUT_FISHING = 0x00200000, // fishing controls
|
|
|
|
INPUT_ALL = 0x003FFFFF
|
|
|
|
};
|
|
|
|
uint32_t inputs = 0;
|
2016-08-10 03:28:40 +00:00
|
|
|
// Holds a ROM region
|
|
|
|
struct ROM
|
|
|
|
{
|
|
|
|
std::shared_ptr<uint8_t> data;
|
|
|
|
size_t size = 0;
|
2016-08-11 03:53:19 +00:00
|
|
|
void CopyTo(uint8_t *dest, size_t dest_size) const;
|
2016-08-10 03:28:40 +00:00
|
|
|
};
|
|
|
|
std::map<std::string, ROM> roms;
|
2016-08-11 03:53:19 +00:00
|
|
|
ROM get_rom(const std::string ®ion) const
|
|
|
|
{
|
|
|
|
auto it = roms.find(region);
|
|
|
|
return it == roms.end() ? ROM() : it->second;
|
|
|
|
}
|
2016-08-10 03:28:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//TODO: move to separate GameLoader.cpp
|
|
|
|
class GameLoader
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
// Describes a file node in the game XML
|
|
|
|
struct File
|
|
|
|
{
|
2016-08-24 04:13:23 +00:00
|
|
|
typedef std::shared_ptr<File> ptr_t;
|
2016-08-10 03:28:40 +00:00
|
|
|
uint32_t offset;
|
|
|
|
std::string filename;
|
|
|
|
uint32_t crc32;
|
|
|
|
bool has_crc32;
|
2016-08-24 04:13:23 +00:00
|
|
|
static ptr_t Create(const GameLoader &loader, const Util::Config::Node &file_node);
|
2016-08-10 03:28:40 +00:00
|
|
|
bool Matches(const std::string &filename, uint32_t crc32) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Describes a region node in the game XML
|
|
|
|
struct Region
|
|
|
|
{
|
2016-08-24 04:13:23 +00:00
|
|
|
typedef std::shared_ptr<Region> ptr_t;
|
2016-08-10 03:28:40 +00:00
|
|
|
std::string region_name;
|
|
|
|
size_t stride;
|
|
|
|
size_t chunk_size;
|
|
|
|
bool byte_swap;
|
2016-08-24 04:13:23 +00:00
|
|
|
typedef std::map<uint32_t, File::ptr_t> FilesByOffset_t;
|
2016-08-10 03:28:40 +00:00
|
|
|
FilesByOffset_t files_by_offset;
|
2016-08-24 04:13:23 +00:00
|
|
|
static ptr_t Create(const GameLoader &loader, const Util::Config::Node ®ion_node);
|
2016-08-10 03:28:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
std::map<std::string, Game> m_game_info_by_game; // ROMs not loaded here
|
2016-08-18 04:19:36 +00:00
|
|
|
|
|
|
|
// Parsed XML
|
2016-08-24 04:13:23 +00:00
|
|
|
typedef std::map<std::string, Region::ptr_t> RegionsByName_t;
|
2016-08-10 03:28:40 +00:00
|
|
|
std::map<std::string, RegionsByName_t> m_regions_by_game;
|
|
|
|
std::string m_xml_filename;
|
2016-08-18 04:19:36 +00:00
|
|
|
|
|
|
|
// Zip file info
|
2016-08-10 03:28:40 +00:00
|
|
|
std::string m_zipfilename;
|
|
|
|
unzFile m_zf;
|
|
|
|
std::map<uint32_t, std::string> m_filename_by_crc32;
|
|
|
|
std::map<std::string, unz_file_info> m_zip_info_by_filename;
|
|
|
|
std::map<uint32_t, unz_file_info> m_zip_info_by_crc32;
|
|
|
|
|
|
|
|
static bool MissingAttrib(const GameLoader &loader, const Util::Config::Node &node, const std::string &attribute);
|
2016-08-24 04:13:23 +00:00
|
|
|
bool ParseXML(const Util::Config::Node &xml);
|
2016-08-10 03:28:40 +00:00
|
|
|
std::set<std::string> IdentifyGamesFileBelongsTo(const std::string &filename, uint32_t crc32) const;
|
2016-08-24 04:13:23 +00:00
|
|
|
const unz_file_info *LookupZippedFile(const File::ptr_t &file) const;
|
|
|
|
bool ComputeRegionSize(uint32_t *region_size, const Region::ptr_t ®ion) const;
|
|
|
|
bool LoadZippedFile(std::shared_ptr<uint8_t> *buffer, size_t *file_size, const GameLoader::File::ptr_t &file);
|
|
|
|
bool LoadRegion(Game::ROM *buffer, const GameLoader::Region::ptr_t ®ion);
|
2016-08-10 03:28:40 +00:00
|
|
|
bool LoadROMs(std::map<std::string, Game::ROM> *roms, const std::string &game_name);
|
2016-08-11 03:53:19 +00:00
|
|
|
bool LoadDefinitionXML(const std::string &filename);
|
2016-08-10 03:28:40 +00:00
|
|
|
|
|
|
|
public:
|
2016-08-11 03:53:19 +00:00
|
|
|
GameLoader(const Util::Config::Node &config);
|
2016-08-10 03:28:40 +00:00
|
|
|
bool Load(Game *game, const std::string &zipfilename);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // INCLUDED_GAME_H
|