yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
rom_old.h
Go to the documentation of this file.
1#ifndef YAZE_ROM_ROM_H
2#define YAZE_ROM_ROM_H
3
5#include <zelda.h>
6
7#include <array>
8#include <cstddef>
9#include <cstdint>
10#include <cstring>
11#include <ctime>
12#include <map>
13#include <stdexcept>
14#include <string>
15#include <variant>
16#include <vector>
17
18#include "absl/status/status.h"
19#include "absl/status/statusor.h"
20#include "absl/strings/str_format.h"
21#include "absl/strings/string_view.h"
22#include "app/gfx/core/bitmap.h"
26#include "rom/rom_diagnostics.h"
27#include "core/project.h"
28#include "util/macro.h"
29
30namespace yaze {
31
32constexpr uint32_t kNumGfxSheets = 223;
33constexpr uint32_t kNumLinkSheets = 14;
34constexpr uint32_t kTile16Ptr = 0x78000;
35constexpr uint32_t kNormalGfxSpaceStart = 0x87000;
36constexpr uint32_t kNormalGfxSpaceEnd = 0xC4200;
37
46uint32_t GetGraphicsAddress(const uint8_t* data, uint8_t addr, uint32_t ptr1,
47 uint32_t ptr2, uint32_t ptr3, size_t rom_size);
48
49constexpr uint32_t kFontSpriteLocation = 0x70000;
50constexpr uint32_t kGfxGroupsPointer = 0x6237;
51constexpr uint32_t kUncompressedSheetSize = 0x0800;
52constexpr uint32_t kNumMainBlocksets = 37;
53constexpr uint32_t kNumRoomBlocksets = 82;
54constexpr uint32_t kNumSpritesets = 144;
55constexpr uint32_t kNumPalettesets = 72;
56constexpr uint32_t kEntranceGfxGroup = 0x5D97;
57constexpr uint32_t kMaxGraphics = 0x0C3FFF; // 0xC3FB5
58
61 bool strip_header = true;
62 bool populate_metadata = true;
63 bool populate_palettes = true;
67
71};
72
76static const std::map<zelda3_version, zelda3_version_pointers>
77 kVersionConstantsMap = {
78 {zelda3_version::US, zelda3_us_pointers},
79 {zelda3_version::JP, zelda3_jp_pointers},
80 {zelda3_version::SD, {}},
81 {zelda3_version::RANDO, {}},
82};
83
87class Rom {
88 public:
89 struct SaveSettings {
90 bool backup = false;
91 bool save_new = false;
92 bool z3_save = true;
93 std::string filename;
94 };
95
96 absl::Status LoadFromFile(const std::string& filename, bool z3_load = true);
97 absl::Status LoadFromFile(const std::string& filename,
98 const RomLoadOptions& options);
99 absl::Status LoadFromData(const std::vector<uint8_t>& data,
100 bool z3_load = true);
101 absl::Status LoadFromData(const std::vector<uint8_t>& data,
102 const RomLoadOptions& options);
103 absl::Status LoadZelda3();
104 absl::Status LoadZelda3(const RomLoadOptions& options);
105 absl::Status LoadGfxGroups();
106
107 absl::Status InitializeForTesting() {
109 return absl::OkStatus();
110 }
111
112 absl::Status SaveGfxGroups();
113 absl::Status SaveToFile(const SaveSettings& settings);
114 absl::Status SavePalette(int index, const std::string& group_name,
115 gfx::SnesPalette& palette);
116 absl::Status SaveAllPalettes();
117
118 void Expand(int size) {
119 rom_data_.resize(size);
120 size_ = size;
121 }
122
123 void Close() {
124 rom_data_.clear();
126 size_ = 0;
127 }
128
129 absl::StatusOr<uint8_t> ReadByte(int offset);
130 absl::StatusOr<uint16_t> ReadWord(int offset);
131 absl::StatusOr<uint32_t> ReadLong(int offset);
132 absl::StatusOr<std::vector<uint8_t>> ReadByteVector(uint32_t offset,
133 uint32_t length) const;
134 absl::StatusOr<gfx::Tile16> ReadTile16(uint32_t tile16_id);
135
136 absl::Status WriteTile16(int tile16_id, const gfx::Tile16& tile);
137 absl::Status WriteByte(int addr, uint8_t value);
138 absl::Status WriteWord(int addr, uint16_t value);
139 absl::Status WriteShort(int addr, uint16_t value);
140 absl::Status WriteLong(uint32_t addr, uint32_t value);
141 absl::Status WriteVector(int addr, std::vector<uint8_t> data);
142 absl::Status WriteColor(uint32_t address, const gfx::SnesColor& color);
143
144 template <typename... Args>
145 absl::Status WriteTransaction(Args... args) {
146 absl::Status status;
147 // Fold expression to apply the Write function on each argument
148 ((status = WriteHelper(args)), ...);
149 return status;
150 }
151
152 template <typename T, typename... Args>
153 absl::Status ReadTransaction(T& var, int address, Args&&... args) {
154 absl::Status status = ReadHelper<T>(var, address);
155 if (!status.ok()) {
156 return status;
157 }
158 if constexpr (sizeof...(args) > 0) {
159 status = ReadTransaction(std::forward<Args>(args)...);
160 }
161 return status;
162 }
163
164 struct WriteAction {
165 using ValueType =
166 std::variant<int, uint8_t, uint16_t, short, std::vector<uint8_t>,
167 gfx::SnesColor, std::vector<gfx::SnesColor>>;
168 int address;
170 };
171
172 virtual absl::Status WriteHelper(const WriteAction& action) {
173 if (std::holds_alternative<uint8_t>(action.value)) {
174 return WriteByte(action.address, std::get<uint8_t>(action.value));
175 } else if (std::holds_alternative<uint16_t>(action.value) ||
176 std::holds_alternative<short>(action.value)) {
177 return WriteShort(action.address, std::get<uint16_t>(action.value));
178 } else if (std::holds_alternative<std::vector<uint8_t>>(action.value)) {
179 return WriteVector(action.address,
180 std::get<std::vector<uint8_t>>(action.value));
181 } else if (std::holds_alternative<gfx::SnesColor>(action.value)) {
182 return WriteColor(action.address, std::get<gfx::SnesColor>(action.value));
183 } else if (std::holds_alternative<std::vector<gfx::SnesColor>>(
184 action.value)) {
185 return absl::UnimplementedError(
186 "WriteHelper: std::vector<gfx::SnesColor>");
187 }
188 auto error_message = absl::StrFormat("Invalid write argument type: %s",
189 typeid(action.value).name());
190 return absl::InvalidArgumentError(error_message);
191 }
192
193 template <typename T>
194 absl::Status ReadHelper(T& var, int address) {
195 if constexpr (std::is_same_v<T, uint8_t>) {
196 ASSIGN_OR_RETURN(auto result, ReadByte(address));
197 var = result;
198 } else if constexpr (std::is_same_v<T, uint16_t>) {
199 ASSIGN_OR_RETURN(auto result, ReadWord(address));
200 var = result;
201 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
202 ASSIGN_OR_RETURN(auto result, ReadByteVector(address, var.size()));
203 var = result;
204 }
205 return absl::OkStatus();
206 }
207
208 uint8_t& operator[](unsigned long i) {
209 if (i >= size_)
210 throw std::out_of_range("Rom index out of range");
211 return rom_data_[i];
212 }
213
214 bool is_loaded() const { return !rom_data_.empty(); }
215 bool dirty() const { return dirty_; }
216 void set_dirty(bool dirty) { dirty_ = dirty; }
217 void ClearDirty() { dirty_ = false; }
218 auto title() const { return title_; }
219 auto size() const { return size_; }
220 auto data() const { return rom_data_.data(); }
221 auto mutable_data() { return rom_data_.data(); }
222 auto begin() { return rom_data_.begin(); }
223 auto end() { return rom_data_.end(); }
224 const auto& vector() const { return rom_data_; }
225 auto& mutable_vector() { return rom_data_; }
226 auto filename() const { return filename_; }
227 auto set_filename(std::string_view name) { filename_ = name; }
228 auto short_name() const { return short_name_; }
229 const auto& graphics_buffer() const { return graphics_buffer_; }
231 const auto& palette_group() const { return palette_groups_; }
237
242 return kVersionConstantsMap.at(version_);
243 }
244
245 std::array<std::array<uint8_t, 8>, kNumMainBlocksets> main_blockset_ids;
246 std::array<std::array<uint8_t, 4>, kNumRoomBlocksets> room_blockset_ids;
247 std::array<std::array<uint8_t, 4>, kNumSpritesets> spriteset_ids;
248 std::array<std::array<uint8_t, 4>, kNumPalettesets> paletteset_ids;
249
252
253 private:
254 // Size of the ROM data.
255 unsigned long size_ = 0;
256
257 // Title of the ROM loaded from the header
258 std::string title_ = "ROM not loaded";
259
260 // Filename of the ROM
261 std::string filename_;
262
263 // Short name of the ROM
264 std::string short_name_;
265
266 // Full contiguous rom space
267 std::vector<uint8_t> rom_data_;
268
269 // Full contiguous graphics space
270 std::vector<uint8_t> graphics_buffer_;
271
272 // Diagnostics for graphics loading
274
275 // Label manager for unique resource names.
277
278 // All palette groups in the game
280
281 // Version of the game
282 zelda3_version version_ = zelda3_version::US;
283
284 // True if there are unsaved changes
285 bool dirty_ = false;
286};
287
306absl::StatusOr<std::array<gfx::Bitmap, kNumGfxSheets>> LoadAllGraphicsData(
307 Rom& rom, bool defer_render = false);
308
309absl::Status SaveAllGraphicsData(
310 Rom& rom, std::array<gfx::Bitmap, kNumGfxSheets>& gfx_sheets);
311
320absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom);
321
325absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
326 const Rom& rom);
327
328absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom);
329
330} // namespace yaze
331
332#endif
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:24
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length) const
zelda3_version version_
Definition rom_old.h:282
project::ResourceLabelManager * resource_label()
Definition rom_old.h:238
auto mutable_graphics_buffer()
Definition rom_old.h:230
absl::Status ReadTransaction(T &var, int address, Args &&... args)
Definition rom_old.h:153
absl::Status LoadFromFile(const std::string &filename, const LoadOptions &options=LoadOptions::Defaults())
Definition rom.cc:74
auto begin()
Definition rom_old.h:222
void ClearDirty()
Definition rom_old.h:217
gfx::PaletteGroupMap palette_groups_
Definition rom_old.h:279
absl::StatusOr< gfx::Tile16 > ReadTile16(uint32_t tile16_id, uint32_t tile16_ptr)
Definition rom.cc:256
absl::Status WriteColor(uint32_t address, const gfx::SnesColor &color)
auto filename() const
Definition rom.h:141
auto mutable_palette_group()
Definition rom_old.h:232
auto end()
Definition rom_old.h:223
absl::Status WriteByte(int addr, uint8_t value)
absl::Status WriteTile16(int tile16_id, uint32_t tile16_ptr, const gfx::Tile16 &tile)
Definition rom.cc:274
void set_dirty(bool dirty)
Definition rom_old.h:216
auto mutable_data()
Definition rom_old.h:221
absl::Status LoadZelda3()
Definition rom_old.cc:851
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
Definition rom_old.h:247
const auto & vector() const
Definition rom.h:139
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
Definition rom_old.h:248
auto mutable_dungeon_palette(int i)
Definition rom_old.h:234
absl::StatusOr< uint16_t > ReadWord(int offset)
const auto & palette_group() const
Definition rom_old.h:231
absl::Status WriteVector(int addr, std::vector< uint8_t > data)
std::string title_
Definition rom.h:155
void Expand(int size)
Definition rom_old.h:118
absl::Status WriteTransaction(Args... args)
Definition rom_old.h:145
absl::Status SaveToFile(const SaveSettings &settings)
const GraphicsLoadDiagnostics & GetDiagnostics() const
Definition rom_old.h:250
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
Definition rom_old.h:246
virtual absl::Status WriteHelper(const WriteAction &action)
Definition rom_old.h:172
GraphicsLoadDiagnostics & GetMutableDiagnostics()
Definition rom_old.h:251
absl::StatusOr< uint32_t > ReadLong(int offset)
std::vector< uint8_t > rom_data_
Definition rom.h:164
auto data() const
Definition rom.h:135
auto size() const
Definition rom.h:134
std::vector< uint8_t > graphics_buffer_
Definition rom_old.h:270
zelda3_version_pointers version_constants() const
Definition rom_old.h:241
absl::Status SaveGfxGroups()
Definition rom_old.cc:1089
absl::Status LoadGfxGroups()
Definition rom_old.cc:956
bool dirty() const
Definition rom_old.h:215
bool dirty_
Definition rom.h:170
auto & mutable_vector()
Definition rom_old.h:225
absl::Status LoadFromData(const std::vector< uint8_t > &data, const LoadOptions &options=LoadOptions::Defaults())
Definition rom.cc:147
const auto & graphics_buffer() const
Definition rom_old.h:229
auto short_name() const
Definition rom_old.h:228
absl::Status ReadHelper(T &var, int address)
Definition rom_old.h:194
std::string filename_
Definition rom.h:158
unsigned long size_
Definition rom.h:152
absl::Status SavePalette(int index, const std::string &group_name, gfx::SnesPalette &palette)
Definition rom_old.cc:1218
absl::StatusOr< uint8_t > ReadByte(int offset)
absl::Status WriteShort(int addr, uint16_t value)
project::ResourceLabelManager resource_label_manager_
Definition rom.h:167
auto dungeon_palette(int i)
Definition rom_old.h:233
void Close()
Definition rom_old.h:123
uint8_t & operator[](unsigned long i)
Definition rom_old.h:208
absl::Status InitializeForTesting()
Definition rom_old.h:107
auto set_filename(std::string_view name)
Definition rom_old.h:227
std::string short_name_
Definition rom.h:161
bool is_loaded() const
Definition rom_old.h:214
absl::Status WriteWord(int addr, uint16_t value)
virtual absl::Status WriteHelper(const WriteAction &action)
Definition rom.cc:363
absl::Status WriteLong(uint32_t addr, uint32_t value)
GraphicsLoadDiagnostics diagnostics_
Definition rom_old.h:273
auto title() const
Definition rom_old.h:218
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
Definition rom_old.h:245
absl::Status SaveAllPalettes()
Definition rom_old.cc:1232
SNES Color container.
Definition snes_color.h:110
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Tile composition of four 8x8 tiles.
Definition snes_tile.h:140
zelda3_version
Different versions of the game supported by YAZE.
Definition zelda.h:33
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:62
constexpr uint32_t kMaxGraphics
Definition rom_old.h:57
constexpr uint32_t kGfxGroupsPointer
Definition rom_old.h:50
constexpr uint32_t kUncompressedSheetSize
Definition rom_old.h:51
absl::StatusOr< std::vector< uint8_t > > Load2BppGraphics(const Rom &rom)
Loads 2bpp graphics from Rom data.
Definition rom_old.cc:206
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads the players 4bpp graphics sheet from Rom data.
Definition rom_old.cc:235
uint32_t GetGraphicsAddress(const uint8_t *data, uint8_t addr, uint32_t ptr1, uint32_t ptr2, uint32_t ptr3, size_t rom_size)
Calculates ROM offset for a graphics sheet using pointer tables.
Definition rom_old.cc:175
constexpr uint32_t kNumLinkSheets
Definition rom_old.h:33
constexpr uint32_t kNormalGfxSpaceStart
Definition rom_old.h:35
constexpr uint32_t kEntranceGfxGroup
Definition rom_old.h:56
constexpr uint32_t kFontSpriteLocation
Definition rom_old.h:49
constexpr uint32_t kNumSpritesets
Definition rom_old.h:54
constexpr uint32_t kTile16Ptr
Definition rom_old.h:34
constexpr uint32_t kNumMainBlocksets
Definition rom_old.h:52
constexpr uint32_t kNumRoomBlocksets
Definition rom_old.h:53
absl::StatusOr< gfx::Bitmap > LoadFontGraphics(const Rom &rom)
Definition rom_old.cc:256
constexpr uint32_t kNumGfxSheets
Definition rom_old.h:32
absl::StatusOr< std::array< gfx::Bitmap, kNumGfxSheets > > LoadAllGraphicsData(Rom &rom, bool defer_render)
This function iterates over all graphics sheets in the Rom and loads them into memory....
Definition rom_old.cc:352
constexpr uint32_t kNumPalettesets
Definition rom_old.h:55
constexpr uint32_t kNormalGfxSpaceEnd
Definition rom_old.h:36
absl::Status SaveAllGraphicsData(Rom &rom, std::array< gfx::Bitmap, kNumGfxSheets > &gfx_sheets)
Definition rom_old.cc:663
SDL2/SDL3 compatibility layer.
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
static RomLoadOptions AppDefaults()
Definition rom_old.cc:119
bool expand_to_full_image
Definition rom_old.h:65
static RomLoadOptions CliDefaults()
Definition rom_old.cc:123
static RomLoadOptions RawDataOnly()
Definition rom_old.cc:132
bool load_resource_labels
Definition rom_old.h:66
std::string filename
Definition rom.h:29
std::variant< int, uint8_t, uint16_t, short, std::vector< uint8_t >, gfx::SnesColor, std::vector< gfx::SnesColor > > ValueType
Definition rom.h:95
ValueType value
Definition rom.h:99
Represents a mapping of palette groups.
ROM data pointers for different game versions.
Definition zelda.h:71
The Legend of Zelda: A Link to the Past - Data Structures and Constants.