Changes to game loader interface, added 32-bit word swapping utility function

This commit is contained in:
Bart Trzynadlowski 2016-08-11 03:53:19 +00:00
parent 41105c15d7
commit 1dc360a8b0
5 changed files with 45 additions and 12 deletions

View file

@ -6,6 +6,14 @@
#include <iostream> #include <iostream>
void Game::ROM::CopyTo(uint8_t *dest, size_t dest_size) const
{
if (!data || !size || !dest || !dest_size)
return;
size_t bytes_to_copy = std::min(size, dest_size);
const uint8_t *src = data.get();
memcpy(dest, src, bytes_to_copy);
}
bool GameLoader::MissingAttrib(const GameLoader &loader, const Util::Config::Node &node, const std::string &attribute) bool GameLoader::MissingAttrib(const GameLoader &loader, const Util::Config::Node &node, const std::string &attribute)
{ {
@ -50,11 +58,12 @@ GameLoader::Region::Ptr_t GameLoader::Region::Create(const GameLoader &loader, c
static void PopulateGameInfo(Game *game, const Util::Config::Node &game_node) static void PopulateGameInfo(Game *game, const Util::Config::Node &game_node)
{ {
game->name = game_node["name"].Value();
game->title = game_node["identity/title"].Value(); game->title = game_node["identity/title"].Value();
game->version = game_node["identity/version"].Value(); game->version = game_node["identity/version"].Value();
game->manufacturer = game_node["identity/manufacturer"].Value(); game->manufacturer = game_node["identity/manufacturer"].Value();
game->year = game_node["identity/year"].ValueAsUnsigned(); game->year = game_node["identity/year"].ValueAsUnsigned();
game->stepping = game_node["identity/stepping"].Value(); game->stepping = game_node["hardware/stepping"].Value();
} }
bool GameLoader::ParseXML(const Util::Config::Node::ConstPtr_t &xml) bool GameLoader::ParseXML(const Util::Config::Node::ConstPtr_t &xml)
@ -274,7 +283,7 @@ bool GameLoader::LoadRegion(Game::ROM *buffer, const GameLoader::Region::Ptr_t &
} }
} }
if (region->byte_swap) if (region->byte_swap)
Util::ByteSwap(buffer->data.get(), buffer->size); Util::FlipEndian16(buffer->data.get(), buffer->size);
return error; return error;
} }
@ -377,3 +386,8 @@ bool GameLoader::Load(Game *game, const std::string &zipfilename)
unzClose(m_zf); unzClose(m_zf);
return error; return error;
} }
GameLoader::GameLoader(const Util::Config::Node &config)
{
LoadDefinitionXML(config["GameXMLFile"].Value());
}

View file

@ -8,6 +8,7 @@
struct Game struct Game
{ {
std::string name;
std::string title; std::string title;
std::string version; std::string version;
std::string manufacturer; std::string manufacturer;
@ -18,8 +19,14 @@ struct Game
{ {
std::shared_ptr<uint8_t> data; std::shared_ptr<uint8_t> data;
size_t size = 0; size_t size = 0;
void CopyTo(uint8_t *dest, size_t dest_size) const;
}; };
std::map<std::string, ROM> roms; std::map<std::string, ROM> roms;
ROM get_rom(const std::string &region) const
{
auto it = roms.find(region);
return it == roms.end() ? ROM() : it->second;
}
}; };
//TODO: move to separate GameLoader.cpp //TODO: move to separate GameLoader.cpp
@ -69,13 +76,10 @@ private:
bool LoadZippedFile(std::shared_ptr<uint8_t> *buffer, size_t *file_size, const GameLoader::File::Ptr_t &file); 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 &region); bool LoadRegion(Game::ROM *buffer, const GameLoader::Region::Ptr_t &region);
bool LoadROMs(std::map<std::string, Game::ROM> *roms, const std::string &game_name); bool LoadROMs(std::map<std::string, Game::ROM> *roms, const std::string &game_name);
bool LoadDefinitionXML(const std::string &filename);
public: public:
GameLoader() GameLoader(const Util::Config::Node &config);
{
}
bool LoadDefinitionXML(const std::string &filename);
bool Load(Game *game, const std::string &zipfilename); bool Load(Game *game, const std::string &zipfilename);
}; };

View file

@ -2,13 +2,26 @@
namespace Util namespace Util
{ {
void ByteSwap(uint8_t *buffer, size_t size) void FlipEndian16(uint8_t *buffer, size_t size)
{ {
for (size_t i = 0; i < (size & ~1); i += 2) for (size_t i = 0; i < (size & ~1); i += 2)
{ {
uint8_t x = buffer[i + 0]; uint8_t tmp = buffer[i + 0];
buffer[i + 0] = buffer[i + 1]; buffer[i + 0] = buffer[i + 1];
buffer[i + 1] = x; buffer[i + 1] = tmp;
}
}
void FlipEndian32(uint8_t *buffer, size_t size)
{
for (size_t i = 0; i < (size & ~3); i += 4)
{
uint8_t tmp1 = buffer[i+0];
uint8_t tmp2 = buffer[i+1];
buffer[i+0] = buffer[i+3];
buffer[i+1] = buffer[i+2];
buffer[i+2] = tmp2;
buffer[i+3] = tmp1;
} }
} }
} // Util } // Util

View file

@ -6,7 +6,8 @@
namespace Util namespace Util
{ {
void ByteSwap(uint8_t *buffer, size_t size); void FlipEndian16(uint8_t *buffer, size_t size);
void FlipEndian32(uint8_t *buffer, size_t size);
} // Util } // Util
#endif // INCLUDED_BYTESWAP_H #endif // INCLUDED_BYTESWAP_H

View file

@ -157,7 +157,7 @@ namespace Util
const inline std::string &Value() const const inline std::string &Value() const
{ {
//TODO: if empty node, throw exception? //TODO: if empty node, throw exception? Use ValueWithDefault() otherwise.
return m_value; return m_value;
} }
@ -206,6 +206,7 @@ namespace Util
}; };
//TODO: CreateEmpty() should take a key that defaults to blank //TODO: CreateEmpty() should take a key that defaults to blank
//TODO: define deep-copy assignment operator and get rid of Ptr_t and ConstPtr_t
Node::Ptr_t CreateEmpty(); Node::Ptr_t CreateEmpty();
Node::Ptr_t FromXML(const std::string &text); Node::Ptr_t FromXML(const std::string &text);
Node::Ptr_t FromXMLFile(const std::string &filename); Node::Ptr_t FromXMLFile(const std::string &filename);