17#include "absl/status/status.h"
18#include "absl/status/statusor.h"
19#include "absl/strings/match.h"
20#include "absl/strings/str_format.h"
21#include "absl/strings/string_view.h"
69static const std::map<Z3_Version, VersionConstants> kVersionConstantsMap = {
193 absl::Status
SaveToFile(
bool backup,
bool save_new =
false,
205 absl::Status
SavePalette(
int index,
const std::string& group_name,
231 return absl::OkStatus();
239 return absl::FailedPreconditionError(
"ROM file not loaded");
242 return absl::FailedPreconditionError(
243 "File was loaded, but ROM data was empty.");
245 return absl::OkStatus();
251 if (offset >=
static_cast<int>(
rom_data_.size())) {
252 return absl::FailedPreconditionError(
"Offset out of range");
259 if (offset + 1 >=
static_cast<int>(
rom_data_.size())) {
260 return absl::FailedPreconditionError(
"Offset out of range");
272 if (offset + 2 >=
static_cast<int>(
rom_data_.size())) {
273 return absl::OutOfRangeError(
"Offset out of range");
283 if (offset + length >
static_cast<uint32_t
>(
rom_data_.size())) {
284 return absl::OutOfRangeError(
"Offset and length out of range");
286 std::vector<uint8_t> result;
287 for (uint32_t i = offset; i < offset + length; i++) {
321 return absl::OkStatus();
325 absl::Status
Write(
int addr,
int value) {
326 if (addr >=
static_cast<int>(
rom_data_.size())) {
327 return absl::InvalidArgumentError(absl::StrFormat(
328 "Attempt to write %d value failed, address %d out of range", value,
332 return absl::OkStatus();
337 if (addr >=
static_cast<int>(
rom_data_.size())) {
338 return absl::OutOfRangeError(absl::StrFormat(
339 "Attempt to write byte %#02x value failed, address %d out of range",
343 std::string log_str = absl::StrFormat(
"WriteByte: %#06X: %s", addr,
346 return absl::OkStatus();
351 if (addr + 1 >=
static_cast<int>(
rom_data_.size())) {
352 return absl::OutOfRangeError(absl::StrFormat(
353 "Attempt to write word %#04x value failed, address %d out of range",
356 rom_data_[addr] = (uint8_t)(value & 0xFF);
357 rom_data_[addr + 1] = (uint8_t)((value >> 8) & 0xFF);
360 return absl::OkStatus();
365 if (addr + 1 >=
static_cast<int>(
rom_data_.size())) {
366 return absl::OutOfRangeError(absl::StrFormat(
367 "Attempt to write short %#04x value failed, address %d out of range",
370 rom_data_[addr] = (uint8_t)(value & 0xFF);
371 rom_data_[addr + 1] = (uint8_t)((value >> 8) & 0xFF);
374 return absl::OkStatus();
379 if (addr + 2 >=
static_cast<uint32_t
>(
rom_data_.size())) {
380 return absl::OutOfRangeError(absl::StrFormat(
381 "Attempt to write long %#06x value failed, address %d out of range",
384 rom_data_[addr] = (uint8_t)(value & 0xFF);
385 rom_data_[addr + 1] = (uint8_t)((value >> 8) & 0xFF);
386 rom_data_[addr + 2] = (uint8_t)((value >> 16) & 0xFF);
389 return absl::OkStatus();
393 if (addr +
static_cast<int>(
data.size()) >
395 return absl::InvalidArgumentError(absl::StrFormat(
396 "Attempt to write vector value failed, address %d out of range",
399 for (
int i = 0; i < static_cast<int>(
data.size()); i++) {
404 return absl::OkStatus();
408 uint16_t bgr = ((color.
snes() >> 10) & 0x1F) |
409 ((color.
snes() & 0x1F) << 10) | (color.
snes() & 0x7C00);
417 template <
typename... Args>
425 template <
typename T,
typename... Args>
432 if constexpr (
sizeof...(args) > 0) {
441 std::cout <<
"ROM: Index " << i <<
" out of bounds, size: " <<
size_
449 if (!absl::StrContains(
filename_,
".sfc") &&
483 return kVersionConstantsMap.at(
version_);
493 std::variant<int, uint8_t, uint16_t, short, std::vector<uint8_t>,
500 if (std::holds_alternative<uint8_t>(action.
value)) {
502 }
else if (std::holds_alternative<uint16_t>(action.
value) ||
503 std::holds_alternative<short>(action.
value)) {
505 }
else if (std::holds_alternative<std::vector<uint8_t>>(action.
value)) {
507 std::get<std::vector<uint8_t>>(action.
value));
508 }
else if (std::holds_alternative<gfx::SnesColor>(action.
value)) {
510 }
else if (std::holds_alternative<std::vector<gfx::SnesColor>>(
512 return absl::UnimplementedError(
513 "WriteHelper: std::vector<gfx::SnesColor>");
515 auto error_message = absl::StrFormat(
"Invalid write argument type: %s",
516 typeid(action.
value).name());
517 return absl::InvalidArgumentError(error_message);
520 template <
typename T>
522 if constexpr (std::is_same_v<T, uint8_t>) {
525 }
else if constexpr (std::is_same_v<T, uint16_t>) {
528 }
else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
532 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data.
absl::Status WriteByte(int addr, uint8_t value)
auto mutable_palette_group()
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
VersionConstants version_constants() const
absl::Status WriteTransaction(Args... args)
std::vector< uint8_t > graphics_buffer() const
std::vector< uint8_t > rom_data_
absl::Status WriteLong(uint32_t addr, uint32_t value)
absl::Status LoadGfxGroups()
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
ResourceLabelManager * resource_label()
uint16_t toint16(int offset)
absl::Status SaveAllGraphicsData()
absl::Status ReadTransaction(T &var, int address, Args &&... args)
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
absl::Status SaveToFile(bool backup, bool save_new=false, std::string filename="")
Saves the Rom data to a file.
absl::StatusOr< uint32_t > ReadLong(int offset)
absl::Status SaveAllPalettes()
Saves all palettes in the Rom.
ResourceLabelManager resource_label_manager_
absl::StatusOr< gfx::Tile16 > ReadTile16(uint32_t tile16_id)
auto mutable_gfx_sheets()
std::array< gfx::Bitmap, kNumGfxSheets > graphics_sheets_
absl::Status SavePalette(int index, const std::string &group_name, gfx::SnesPalette &palette)
absl::Status LoadAllGraphicsData(bool defer_render=false)
This function iterates over all graphics sheets in the Rom and loads them into memory....
virtual absl::Status WriteHelper(const WriteAction &action)
absl::StatusOr< std::vector< uint8_t > > Load2BppGraphics()
Loads 2bpp graphics from Rom data.
void Expand(int size)
Expand the Rom data to a specified size.
absl::Status WriteTile16(int tile16_id, const gfx::Tile16 &tile)
auto set_filename(std::string name)
absl::Status LoadLinkGraphics()
Loads the players 4bpp graphics sheet from Rom data.
gfx::PaletteGroupMap palette_groups_
absl::Status WriteShort(int addr, uint16_t value)
absl::Status WriteColor(uint32_t address, const gfx::SnesColor &color)
absl::Status Write(int addr, int value)
absl::Status SaveGroupsToRom()
absl::Status Close()
Close the Rom file.
absl::StatusOr< uint16_t > ReadWord(int offset)
absl::Status ReadHelper(T &var, int address)
auto mutable_dungeon_palette(int i)
absl::Status WriteWord(int addr, uint16_t value)
auto mutable_link_graphics()
auto dungeon_palette(int i)
uint8_t & operator[](unsigned long i)
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
absl::StatusOr< uint8_t > ReadByte(int offset)
absl::Status LoadFromBytes(const std::vector< uint8_t > &data)
absl::Status WriteVector(int addr, std::vector< uint8_t > data)
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length)
std::vector< uint8_t > graphics_buffer_
absl::Status LoadFromPointer(uchar *data, size_t length, bool z3_load=true)
absl::Status ReadWritePreconditions()
Precondition check for reading and writing to the Rom.
absl::Status LoadZelda3()
std::array< gfx::Bitmap, kNumLinkSheets > link_graphics_
A class to hold a shared pointer to a Rom object.
static std::shared_ptr< Rom > shared_rom_
std::shared_ptr< Rom > shared_rom()
virtual ~SharedRom()=default
A class to manage experimental feature flags.
static void log(std::string message)
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Tile composition of four 8x8 tiles.
#define RETURN_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
std::string UppercaseHexLong(uint32_t dword)
std::string UppercaseHexByte(uint8_t byte, bool leading)
std::string UppercaseHexWord(uint16_t word, bool leading)
TileInfo WordToTileInfo(uint16_t word)
uint16_t TileInfoToWord(TileInfo tile_info)
constexpr uint32_t kTile16Ptr
constexpr uint32_t kNumRoomBlocksets
Z3_Version
Different versions of the game supported by the Rom class.
constexpr uint32_t kNormalGfxSpaceStart
constexpr uint32_t kNormalGfxSpaceEnd
constexpr uint32_t kNumSpritesets
constexpr uint32_t kNumLinkSheets
constexpr uint32_t kMaxGraphics
constexpr uint32_t kUncompressedSheetSize
constexpr uint32_t kFontSpriteLocation
constexpr uint32_t kNumGfxSheets
constexpr uint32_t kEntranceGfxGroup
constexpr uint32_t kNumMainBlocksets
constexpr uint32_t kGfxGroupsPointer
constexpr uint32_t kNumPalettesets
std::variant< int, uint8_t, uint16_t, short, std::vector< uint8_t >, gfx::SnesColor, std::vector< gfx::SnesColor > > value
Constants for each version of the game.
uint32_t overlayPointersBank
uint32_t kOverworldGfxPtr1
uint32_t kOverworldGfxGroups2
uint32_t kCompressedAllMap32PointersLow
uint32_t kGfxAnimatedPointer
uint32_t kOverworldGfxGroups1
uint32_t kCompressedAllMap32PointersHigh
uint32_t kDungeonPalettesGroups
uint32_t overworldMapPaletteGroup
uint32_t overworldTilesType
uint32_t kSpriteBlocksetPointer
uint32_t kOverworldGfxPtr3
uint32_t kOverworldGfxPtr2
Represents a mapping of palette groups.
PaletteGroup dungeon_main
auto mutable_palette(int i)