yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
rom.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ROM_H
2#define YAZE_APP_ROM_H
3
4#include <SDL.h>
5#include <zelda.h>
6
7#include <cstddef>
8#include <cstdint>
9#include <cstring>
10#include <ctime>
11#include <map>
12#include <string>
13#include <variant>
14#include <vector>
15
16#include "absl/status/status.h"
17#include "absl/status/statusor.h"
18#include "absl/strings/str_format.h"
19#include "absl/strings/string_view.h"
20#include "app/core/project.h"
21#include "app/gfx/bitmap.h"
23#include "app/gfx/snes_tile.h"
24#include "util/macro.h"
25
26namespace yaze {
27
28constexpr uint32_t kNumGfxSheets = 223;
29constexpr uint32_t kNumLinkSheets = 14;
30constexpr uint32_t kTile16Ptr = 0x78000;
31constexpr uint32_t kNormalGfxSpaceStart = 0x87000;
32constexpr uint32_t kNormalGfxSpaceEnd = 0xC4200;
33constexpr uint32_t kFontSpriteLocation = 0x70000;
34constexpr uint32_t kGfxGroupsPointer = 0x6237;
35constexpr uint32_t kUncompressedSheetSize = 0x0800;
36constexpr uint32_t kNumMainBlocksets = 37;
37constexpr uint32_t kNumRoomBlocksets = 82;
38constexpr uint32_t kNumSpritesets = 144;
39constexpr uint32_t kNumPalettesets = 72;
40constexpr uint32_t kEntranceGfxGroup = 0x5D97;
41constexpr uint32_t kMaxGraphics = 0x0C3FFF; // 0xC3FB5
42
45 bool strip_header = true;
46 bool populate_metadata = true;
47 bool populate_palettes = true;
51
55};
56
60static const std::map<zelda3_version, zelda3_version_pointers>
61 kVersionConstantsMap = {
62 {zelda3_version::US, zelda3_us_pointers},
63 {zelda3_version::JP, zelda3_jp_pointers},
64 {zelda3_version::SD, {}},
65 {zelda3_version::RANDO, {}},
66};
67
71class Rom {
72 public:
73 struct SaveSettings {
74 bool backup = false;
75 bool save_new = false;
76 bool z3_save = true;
77 std::string filename = "";
78 };
79
80 absl::Status LoadFromFile(const std::string& filename, bool z3_load = true);
81 absl::Status LoadFromFile(const std::string& filename,
82 const RomLoadOptions& options);
83 absl::Status LoadFromData(const std::vector<uint8_t>& data,
84 bool z3_load = true);
85 absl::Status LoadFromData(const std::vector<uint8_t>& data,
86 const RomLoadOptions& options);
87 absl::Status LoadZelda3();
88 absl::Status LoadZelda3(const RomLoadOptions& options);
89 absl::Status LoadGfxGroups();
90
91 absl::Status InitializeForTesting() {
93 return absl::OkStatus();
94 }
95
96 absl::Status SaveGfxGroups();
97 absl::Status SaveToFile(const SaveSettings& settings);
98 absl::Status SavePalette(int index, const std::string& group_name,
99 gfx::SnesPalette& palette);
100 absl::Status SaveAllPalettes();
101
102 void Expand(int size) {
103 rom_data_.resize(size);
104 size_ = size;
105 }
106
107 void Close() {
108 rom_data_.clear();
110 size_ = 0;
111 }
112
113 absl::StatusOr<uint8_t> ReadByte(int offset);
114 absl::StatusOr<uint16_t> ReadWord(int offset);
115 absl::StatusOr<uint32_t> ReadLong(int offset);
116 absl::StatusOr<std::vector<uint8_t>> ReadByteVector(uint32_t offset,
117 uint32_t length) const;
118 absl::StatusOr<gfx::Tile16> ReadTile16(uint32_t tile16_id);
119
120 absl::Status WriteTile16(int tile16_id, const gfx::Tile16& tile);
121 absl::Status WriteByte(int addr, uint8_t value);
122 absl::Status WriteWord(int addr, uint16_t value);
123 absl::Status WriteShort(int addr, uint16_t value);
124 absl::Status WriteLong(uint32_t addr, uint32_t value);
125 absl::Status WriteVector(int addr, std::vector<uint8_t> data);
126 absl::Status WriteColor(uint32_t address, const gfx::SnesColor& color);
127
128 template <typename... Args>
129 absl::Status WriteTransaction(Args... args) {
130 absl::Status status;
131 // Fold expression to apply the Write function on each argument
132 ((status = WriteHelper(args)), ...);
133 return status;
134 }
135
136 template <typename T, typename... Args>
137 absl::Status ReadTransaction(T& var, int address, Args&&... args) {
138 absl::Status status = ReadHelper<T>(var, address);
139 if (!status.ok()) {
140 return status;
141 }
142 if constexpr (sizeof...(args) > 0) {
143 status = ReadTransaction(std::forward<Args>(args)...);
144 }
145 return status;
146 }
147
148 struct WriteAction {
149 using ValueType =
150 std::variant<int, uint8_t, uint16_t, short, std::vector<uint8_t>,
151 gfx::SnesColor, std::vector<gfx::SnesColor>>;
154 };
155
156 virtual absl::Status WriteHelper(const WriteAction& action) {
157 if (std::holds_alternative<uint8_t>(action.value)) {
158 return WriteByte(action.address, std::get<uint8_t>(action.value));
159 } else if (std::holds_alternative<uint16_t>(action.value) ||
160 std::holds_alternative<short>(action.value)) {
161 return WriteShort(action.address, std::get<uint16_t>(action.value));
162 } else if (std::holds_alternative<std::vector<uint8_t>>(action.value)) {
163 return WriteVector(action.address,
164 std::get<std::vector<uint8_t>>(action.value));
165 } else if (std::holds_alternative<gfx::SnesColor>(action.value)) {
166 return WriteColor(action.address, std::get<gfx::SnesColor>(action.value));
167 } else if (std::holds_alternative<std::vector<gfx::SnesColor>>(
168 action.value)) {
169 return absl::UnimplementedError(
170 "WriteHelper: std::vector<gfx::SnesColor>");
171 }
172 auto error_message = absl::StrFormat("Invalid write argument type: %s",
173 typeid(action.value).name());
174 return absl::InvalidArgumentError(error_message);
175 }
176
177 template <typename T>
178 absl::Status ReadHelper(T& var, int address) {
179 if constexpr (std::is_same_v<T, uint8_t>) {
180 ASSIGN_OR_RETURN(auto result, ReadByte(address));
181 var = result;
182 } else if constexpr (std::is_same_v<T, uint16_t>) {
183 ASSIGN_OR_RETURN(auto result, ReadWord(address));
184 var = result;
185 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
186 ASSIGN_OR_RETURN(auto result, ReadByteVector(address, var.size()));
187 var = result;
188 }
189 return absl::OkStatus();
190 }
191
192 uint8_t& operator[](unsigned long i) {
193 if (i >= size_) throw std::out_of_range("Rom index out of range");
194 return rom_data_[i];
195 }
196
197 bool is_loaded() const { return !rom_data_.empty(); }
198 bool dirty() const { return dirty_; }
199 void set_dirty(bool dirty) { dirty_ = dirty; }
200 void ClearDirty() { dirty_ = false; }
201 auto title() const { return title_; }
202 auto size() const { return size_; }
203 auto data() const { return rom_data_.data(); }
204 auto mutable_data() { return rom_data_.data(); }
205 auto begin() { return rom_data_.begin(); }
206 auto end() { return rom_data_.end(); }
207 auto vector() const { return rom_data_; }
208 auto filename() const { return filename_; }
209 auto set_filename(std::string_view name) { filename_ = name; }
210 auto short_name() const { return short_name_; }
211 auto graphics_buffer() const { return graphics_buffer_; }
213 auto palette_group() const { return palette_groups_; }
219
222 return kVersionConstantsMap.at(version_);
223 }
224
225 std::array<std::array<uint8_t, 8>, kNumMainBlocksets> main_blockset_ids;
226 std::array<std::array<uint8_t, 4>, kNumRoomBlocksets> room_blockset_ids;
227 std::array<std::array<uint8_t, 4>, kNumSpritesets> spriteset_ids;
228 std::array<std::array<uint8_t, 4>, kNumPalettesets> paletteset_ids;
229
230 private:
231 // Size of the ROM data.
232 unsigned long size_ = 0;
233
234 // Title of the ROM loaded from the header
235 std::string title_ = "ROM not loaded";
236
237 // Filename of the ROM
238 std::string filename_ = "";
239
240 // Short name of the ROM
241 std::string short_name_ = "";
242
243 // Full contiguous rom space
244 std::vector<uint8_t> rom_data_;
245
246 // Full contiguous graphics space
247 std::vector<uint8_t> graphics_buffer_;
248
249 // Label manager for unique resource names.
251
252 // All palette groups in the game
254
255 // Version of the game
256 zelda3_version version_ = zelda3_version::US;
257
258 // True if there are unsaved changes
259 bool dirty_ = false;
260};
261
280absl::StatusOr<std::array<gfx::Bitmap, kNumGfxSheets>> LoadAllGraphicsData(
281 Rom& rom, bool defer_render = false);
282
283absl::Status SaveAllGraphicsData(
284 Rom& rom, std::array<gfx::Bitmap, kNumGfxSheets>& gfx_sheets);
285
294absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom);
295
299absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
300 const Rom& rom);
301
302absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom);
303
304} // namespace yaze
305
306#endif
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:71
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length) const
Definition rom.cc:682
zelda3_version version_
Definition rom.h:256
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
Definition rom.cc:289
auto mutable_graphics_buffer()
Definition rom.h:212
absl::Status ReadTransaction(T &var, int address, Args &&... args)
Definition rom.h:137
auto begin()
Definition rom.h:205
void ClearDirty()
Definition rom.h:200
std::vector< uint8_t > rom_data_
Definition rom.h:244
gfx::PaletteGroupMap palette_groups_
Definition rom.h:253
auto palette_group() const
Definition rom.h:213
absl::StatusOr< gfx::Tile16 > ReadTile16(uint32_t tile16_id)
Definition rom.cc:694
absl::Status WriteColor(uint32_t address, const gfx::SnesColor &color)
Definition rom.cc:792
auto filename() const
Definition rom.h:208
auto mutable_palette_group()
Definition rom.h:214
absl::Status LoadFromData(const std::vector< uint8_t > &data, bool z3_load=true)
Definition rom.cc:381
auto end()
Definition rom.h:206
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:725
auto vector() const
Definition rom.h:207
void set_dirty(bool dirty)
Definition rom.h:199
auto mutable_data()
Definition rom.h:204
absl::Status LoadZelda3()
Definition rom.cc:408
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
Definition rom.h:227
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
Definition rom.h:228
auto mutable_dungeon_palette(int i)
Definition rom.h:216
absl::StatusOr< uint16_t > ReadWord(int offset)
Definition rom.cc:665
absl::Status WriteVector(int addr, std::vector< uint8_t > data)
Definition rom.cc:777
std::string title_
Definition rom.h:235
absl::Status WriteTile16(int tile16_id, const gfx::Tile16 &tile)
Definition rom.cc:712
void Expand(int size)
Definition rom.h:102
absl::Status WriteTransaction(Args... args)
Definition rom.h:129
absl::Status SaveToFile(const SaveSettings &settings)
Definition rom.cc:536
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
Definition rom.h:226
virtual absl::Status WriteHelper(const WriteAction &action)
Definition rom.h:156
absl::StatusOr< uint32_t > ReadLong(int offset)
Definition rom.cc:673
auto data() const
Definition rom.h:203
auto size() const
Definition rom.h:202
std::vector< uint8_t > graphics_buffer_
Definition rom.h:247
zelda3_version_pointers version_constants() const
Definition rom.h:221
absl::Status SaveGfxGroups()
Definition rom.cc:503
absl::Status LoadGfxGroups()
Definition rom.cc:470
bool dirty() const
Definition rom.h:198
bool dirty_
Definition rom.h:259
core::ResourceLabelManager * resource_label()
Definition rom.h:220
auto short_name() const
Definition rom.h:210
absl::Status ReadHelper(T &var, int address)
Definition rom.h:178
std::string filename_
Definition rom.h:238
unsigned long size_
Definition rom.h:232
absl::Status SavePalette(int index, const std::string &group_name, gfx::SnesPalette &palette)
Definition rom.cc:631
absl::StatusOr< uint8_t > ReadByte(int offset)
Definition rom.cc:658
absl::Status WriteShort(int addr, uint16_t value)
Definition rom.cc:750
auto dungeon_palette(int i)
Definition rom.h:215
void Close()
Definition rom.h:107
core::ResourceLabelManager resource_label_manager_
Definition rom.h:250
uint8_t & operator[](unsigned long i)
Definition rom.h:192
absl::Status InitializeForTesting()
Definition rom.h:91
auto set_filename(std::string_view name)
Definition rom.h:209
std::string short_name_
Definition rom.h:241
bool is_loaded() const
Definition rom.h:197
absl::Status WriteWord(int addr, uint16_t value)
Definition rom.cc:737
absl::Status WriteLong(uint32_t addr, uint32_t value)
Definition rom.cc:763
auto title() const
Definition rom.h:201
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
Definition rom.h:225
auto graphics_buffer() const
Definition rom.h:211
absl::Status SaveAllPalettes()
Definition rom.cc:645
SNES Color container.
Definition snes_color.h:38
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
Tile composition of four 8x8 tiles.
Definition snes_tile.h:137
zelda3_version
Different versions of the game supported by YAZE.
Definition zelda.h:33
#define RETURN_IF_ERROR(expression)
Definition macro.h:53
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:61
Main namespace for the application.
constexpr uint32_t kMaxGraphics
Definition rom.h:41
constexpr uint32_t kGfxGroupsPointer
Definition rom.h:34
constexpr uint32_t kUncompressedSheetSize
Definition rom.h:35
absl::StatusOr< std::vector< uint8_t > > Load2BppGraphics(const Rom &rom)
Loads 2bpp graphics from Rom data.
Definition rom.cc:76
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads the players 4bpp graphics sheet from Rom data.
Definition rom.cc:94
constexpr uint32_t kNumLinkSheets
Definition rom.h:29
constexpr uint32_t kNormalGfxSpaceStart
Definition rom.h:31
constexpr uint32_t kEntranceGfxGroup
Definition rom.h:40
constexpr uint32_t kFontSpriteLocation
Definition rom.h:33
constexpr uint32_t kNumSpritesets
Definition rom.h:38
constexpr uint32_t kTile16Ptr
Definition rom.h:30
constexpr uint32_t kNumMainBlocksets
Definition rom.h:36
constexpr uint32_t kNumRoomBlocksets
Definition rom.h:37
absl::StatusOr< gfx::Bitmap > LoadFontGraphics(const Rom &rom)
Definition rom.cc:114
constexpr uint32_t kNumGfxSheets
Definition rom.h:28
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.cc:172
constexpr uint32_t kNumPalettesets
Definition rom.h:39
constexpr uint32_t kNormalGfxSpaceEnd
Definition rom.h:32
absl::Status SaveAllGraphicsData(Rom &rom, std::array< gfx::Bitmap, kNumGfxSheets > &gfx_sheets)
Definition rom.cc:253
bool strip_header
Definition rom.h:45
static RomLoadOptions AppDefaults()
Definition rom.cc:47
bool load_zelda3_content
Definition rom.h:44
bool expand_to_full_image
Definition rom.h:49
bool populate_palettes
Definition rom.h:47
static RomLoadOptions CliDefaults()
Definition rom.cc:49
bool populate_metadata
Definition rom.h:46
static RomLoadOptions RawDataOnly()
Definition rom.cc:58
bool populate_gfx_groups
Definition rom.h:48
bool load_resource_labels
Definition rom.h:50
std::string filename
Definition rom.h:77
std::variant< int, uint8_t, uint16_t, short, std::vector< uint8_t >, gfx::SnesColor, std::vector< gfx::SnesColor > > ValueType
Definition rom.h:151
ValueType value
Definition rom.h:153
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.