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 <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 "core/project.h"
23#include "app/gfx/core/bitmap.h"
27#include "util/macro.h"
28
29namespace yaze {
30
31constexpr uint32_t kNumGfxSheets = 223;
32constexpr uint32_t kNumLinkSheets = 14;
33constexpr uint32_t kTile16Ptr = 0x78000;
34constexpr uint32_t kNormalGfxSpaceStart = 0x87000;
35constexpr uint32_t kNormalGfxSpaceEnd = 0xC4200;
36constexpr uint32_t kFontSpriteLocation = 0x70000;
37constexpr uint32_t kGfxGroupsPointer = 0x6237;
38constexpr uint32_t kUncompressedSheetSize = 0x0800;
39constexpr uint32_t kNumMainBlocksets = 37;
40constexpr uint32_t kNumRoomBlocksets = 82;
41constexpr uint32_t kNumSpritesets = 144;
42constexpr uint32_t kNumPalettesets = 72;
43constexpr uint32_t kEntranceGfxGroup = 0x5D97;
44constexpr uint32_t kMaxGraphics = 0x0C3FFF; // 0xC3FB5
45
48 bool strip_header = true;
49 bool populate_metadata = true;
50 bool populate_palettes = true;
54
58};
59
63static const std::map<zelda3_version, zelda3_version_pointers>
64 kVersionConstantsMap = {
65 {zelda3_version::US, zelda3_us_pointers},
66 {zelda3_version::JP, zelda3_jp_pointers},
67 {zelda3_version::SD, {}},
68 {zelda3_version::RANDO, {}},
69};
70
74class Rom {
75 public:
76 struct SaveSettings {
77 bool backup = false;
78 bool save_new = false;
79 bool z3_save = true;
80 std::string filename;
81 };
82
83 absl::Status LoadFromFile(const std::string& filename, bool z3_load = true);
84 absl::Status LoadFromFile(const std::string& filename,
85 const RomLoadOptions& options);
86 absl::Status LoadFromData(const std::vector<uint8_t>& data,
87 bool z3_load = true);
88 absl::Status LoadFromData(const std::vector<uint8_t>& data,
89 const RomLoadOptions& options);
90 absl::Status LoadZelda3();
91 absl::Status LoadZelda3(const RomLoadOptions& options);
92 absl::Status LoadGfxGroups();
93
94 absl::Status InitializeForTesting() {
96 return absl::OkStatus();
97 }
98
99 absl::Status SaveGfxGroups();
100 absl::Status SaveToFile(const SaveSettings& settings);
101 absl::Status SavePalette(int index, const std::string& group_name,
102 gfx::SnesPalette& palette);
103 absl::Status SaveAllPalettes();
104
105 void Expand(int size) {
106 rom_data_.resize(size);
107 size_ = size;
108 }
109
110 void Close() {
111 rom_data_.clear();
113 size_ = 0;
114 }
115
116 absl::StatusOr<uint8_t> ReadByte(int offset);
117 absl::StatusOr<uint16_t> ReadWord(int offset);
118 absl::StatusOr<uint32_t> ReadLong(int offset);
119 absl::StatusOr<std::vector<uint8_t>> ReadByteVector(uint32_t offset,
120 uint32_t length) const;
121 absl::StatusOr<gfx::Tile16> ReadTile16(uint32_t tile16_id);
122
123 absl::Status WriteTile16(int tile16_id, const gfx::Tile16& tile);
124 absl::Status WriteByte(int addr, uint8_t value);
125 absl::Status WriteWord(int addr, uint16_t value);
126 absl::Status WriteShort(int addr, uint16_t value);
127 absl::Status WriteLong(uint32_t addr, uint32_t value);
128 absl::Status WriteVector(int addr, std::vector<uint8_t> data);
129 absl::Status WriteColor(uint32_t address, const gfx::SnesColor& color);
130
131 template <typename... Args>
132 absl::Status WriteTransaction(Args... args) {
133 absl::Status status;
134 // Fold expression to apply the Write function on each argument
135 ((status = WriteHelper(args)), ...);
136 return status;
137 }
138
139 template <typename T, typename... Args>
140 absl::Status ReadTransaction(T& var, int address, Args&&... args) {
141 absl::Status status = ReadHelper<T>(var, address);
142 if (!status.ok()) {
143 return status;
144 }
145 if constexpr (sizeof...(args) > 0) {
146 status = ReadTransaction(std::forward<Args>(args)...);
147 }
148 return status;
149 }
150
151 struct WriteAction {
152 using ValueType =
153 std::variant<int, uint8_t, uint16_t, short, std::vector<uint8_t>,
154 gfx::SnesColor, std::vector<gfx::SnesColor>>;
157 };
158
159 virtual absl::Status WriteHelper(const WriteAction& action) {
160 if (std::holds_alternative<uint8_t>(action.value)) {
161 return WriteByte(action.address, std::get<uint8_t>(action.value));
162 } else if (std::holds_alternative<uint16_t>(action.value) ||
163 std::holds_alternative<short>(action.value)) {
164 return WriteShort(action.address, std::get<uint16_t>(action.value));
165 } else if (std::holds_alternative<std::vector<uint8_t>>(action.value)) {
166 return WriteVector(action.address,
167 std::get<std::vector<uint8_t>>(action.value));
168 } else if (std::holds_alternative<gfx::SnesColor>(action.value)) {
169 return WriteColor(action.address, std::get<gfx::SnesColor>(action.value));
170 } else if (std::holds_alternative<std::vector<gfx::SnesColor>>(
171 action.value)) {
172 return absl::UnimplementedError(
173 "WriteHelper: std::vector<gfx::SnesColor>");
174 }
175 auto error_message = absl::StrFormat("Invalid write argument type: %s",
176 typeid(action.value).name());
177 return absl::InvalidArgumentError(error_message);
178 }
179
180 template <typename T>
181 absl::Status ReadHelper(T& var, int address) {
182 if constexpr (std::is_same_v<T, uint8_t>) {
183 ASSIGN_OR_RETURN(auto result, ReadByte(address));
184 var = result;
185 } else if constexpr (std::is_same_v<T, uint16_t>) {
186 ASSIGN_OR_RETURN(auto result, ReadWord(address));
187 var = result;
188 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
189 ASSIGN_OR_RETURN(auto result, ReadByteVector(address, var.size()));
190 var = result;
191 }
192 return absl::OkStatus();
193 }
194
195 uint8_t& operator[](unsigned long i) {
196 if (i >= size_) throw std::out_of_range("Rom index out of range");
197 return rom_data_[i];
198 }
199
200 bool is_loaded() const { return !rom_data_.empty(); }
201 bool dirty() const { return dirty_; }
202 void set_dirty(bool dirty) { dirty_ = dirty; }
203 void ClearDirty() { dirty_ = false; }
204 auto title() const { return title_; }
205 auto size() const { return size_; }
206 auto data() const { return rom_data_.data(); }
207 auto mutable_data() { return rom_data_.data(); }
208 auto begin() { return rom_data_.begin(); }
209 auto end() { return rom_data_.end(); }
210 auto vector() const { return rom_data_; }
211 auto filename() const { return filename_; }
212 auto set_filename(std::string_view name) { filename_ = name; }
213 auto short_name() const { return short_name_; }
214 auto graphics_buffer() const { return graphics_buffer_; }
216 auto palette_group() const { return palette_groups_; }
222
225 return kVersionConstantsMap.at(version_);
226 }
227
228 std::array<std::array<uint8_t, 8>, kNumMainBlocksets> main_blockset_ids;
229 std::array<std::array<uint8_t, 4>, kNumRoomBlocksets> room_blockset_ids;
230 std::array<std::array<uint8_t, 4>, kNumSpritesets> spriteset_ids;
231 std::array<std::array<uint8_t, 4>, kNumPalettesets> paletteset_ids;
232
233 private:
234 // Size of the ROM data.
235 unsigned long size_ = 0;
236
237 // Title of the ROM loaded from the header
238 std::string title_ = "ROM not loaded";
239
240 // Filename of the ROM
241 std::string filename_;
242
243 // Short name of the ROM
244 std::string short_name_;
245
246 // Full contiguous rom space
247 std::vector<uint8_t> rom_data_;
248
249 // Full contiguous graphics space
250 std::vector<uint8_t> graphics_buffer_;
251
252 // Label manager for unique resource names.
254
255 // All palette groups in the game
257
258 // Version of the game
259 zelda3_version version_ = zelda3_version::US;
260
261 // True if there are unsaved changes
262 bool dirty_ = false;
263};
264
283absl::StatusOr<std::array<gfx::Bitmap, kNumGfxSheets>> LoadAllGraphicsData(
284 Rom& rom, bool defer_render = false);
285
286absl::Status SaveAllGraphicsData(
287 Rom& rom, std::array<gfx::Bitmap, kNumGfxSheets>& gfx_sheets);
288
297absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom);
298
302absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
303 const Rom& rom);
304
305absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom);
306
307} // namespace yaze
308
309#endif
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:74
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length) const
Definition rom.cc:685
zelda3_version version_
Definition rom.h:259
project::ResourceLabelManager * resource_label()
Definition rom.h:223
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
Definition rom.cc:292
auto mutable_graphics_buffer()
Definition rom.h:215
absl::Status ReadTransaction(T &var, int address, Args &&... args)
Definition rom.h:140
auto begin()
Definition rom.h:208
void ClearDirty()
Definition rom.h:203
std::vector< uint8_t > rom_data_
Definition rom.h:247
gfx::PaletteGroupMap palette_groups_
Definition rom.h:256
auto palette_group() const
Definition rom.h:216
absl::StatusOr< gfx::Tile16 > ReadTile16(uint32_t tile16_id)
Definition rom.cc:697
absl::Status WriteColor(uint32_t address, const gfx::SnesColor &color)
Definition rom.cc:795
auto filename() const
Definition rom.h:211
auto mutable_palette_group()
Definition rom.h:217
absl::Status LoadFromData(const std::vector< uint8_t > &data, bool z3_load=true)
Definition rom.cc:384
auto end()
Definition rom.h:209
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:728
auto vector() const
Definition rom.h:210
void set_dirty(bool dirty)
Definition rom.h:202
auto mutable_data()
Definition rom.h:207
absl::Status LoadZelda3()
Definition rom.cc:411
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
Definition rom.h:230
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
Definition rom.h:231
auto mutable_dungeon_palette(int i)
Definition rom.h:219
absl::StatusOr< uint16_t > ReadWord(int offset)
Definition rom.cc:668
absl::Status WriteVector(int addr, std::vector< uint8_t > data)
Definition rom.cc:780
std::string title_
Definition rom.h:238
absl::Status WriteTile16(int tile16_id, const gfx::Tile16 &tile)
Definition rom.cc:715
void Expand(int size)
Definition rom.h:105
absl::Status WriteTransaction(Args... args)
Definition rom.h:132
absl::Status SaveToFile(const SaveSettings &settings)
Definition rom.cc:539
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
Definition rom.h:229
virtual absl::Status WriteHelper(const WriteAction &action)
Definition rom.h:159
absl::StatusOr< uint32_t > ReadLong(int offset)
Definition rom.cc:676
auto data() const
Definition rom.h:206
auto size() const
Definition rom.h:205
std::vector< uint8_t > graphics_buffer_
Definition rom.h:250
zelda3_version_pointers version_constants() const
Definition rom.h:224
absl::Status SaveGfxGroups()
Definition rom.cc:506
absl::Status LoadGfxGroups()
Definition rom.cc:473
bool dirty() const
Definition rom.h:201
bool dirty_
Definition rom.h:262
auto short_name() const
Definition rom.h:213
absl::Status ReadHelper(T &var, int address)
Definition rom.h:181
std::string filename_
Definition rom.h:241
unsigned long size_
Definition rom.h:235
absl::Status SavePalette(int index, const std::string &group_name, gfx::SnesPalette &palette)
Definition rom.cc:634
absl::StatusOr< uint8_t > ReadByte(int offset)
Definition rom.cc:661
absl::Status WriteShort(int addr, uint16_t value)
Definition rom.cc:753
project::ResourceLabelManager resource_label_manager_
Definition rom.h:253
auto dungeon_palette(int i)
Definition rom.h:218
void Close()
Definition rom.h:110
uint8_t & operator[](unsigned long i)
Definition rom.h:195
absl::Status InitializeForTesting()
Definition rom.h:94
auto set_filename(std::string_view name)
Definition rom.h:212
std::string short_name_
Definition rom.h:244
bool is_loaded() const
Definition rom.h:200
absl::Status WriteWord(int addr, uint16_t value)
Definition rom.cc:740
absl::Status WriteLong(uint32_t addr, uint32_t value)
Definition rom.cc:766
auto title() const
Definition rom.h:204
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
Definition rom.h:228
auto graphics_buffer() const
Definition rom.h:214
absl::Status SaveAllPalettes()
Definition rom.cc:648
SNES Color container.
Definition snes_color.h:109
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.
Definition controller.cc:20
constexpr uint32_t kMaxGraphics
Definition rom.h:44
constexpr uint32_t kGfxGroupsPointer
Definition rom.h:37
constexpr uint32_t kUncompressedSheetSize
Definition rom.h:38
absl::StatusOr< std::vector< uint8_t > > Load2BppGraphics(const Rom &rom)
Loads 2bpp graphics from Rom data.
Definition rom.cc:79
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads the players 4bpp graphics sheet from Rom data.
Definition rom.cc:97
constexpr uint32_t kNumLinkSheets
Definition rom.h:32
constexpr uint32_t kNormalGfxSpaceStart
Definition rom.h:34
constexpr uint32_t kEntranceGfxGroup
Definition rom.h:43
constexpr uint32_t kFontSpriteLocation
Definition rom.h:36
constexpr uint32_t kNumSpritesets
Definition rom.h:41
constexpr uint32_t kTile16Ptr
Definition rom.h:33
constexpr uint32_t kNumMainBlocksets
Definition rom.h:39
constexpr uint32_t kNumRoomBlocksets
Definition rom.h:40
absl::StatusOr< gfx::Bitmap > LoadFontGraphics(const Rom &rom)
Definition rom.cc:117
constexpr uint32_t kNumGfxSheets
Definition rom.h:31
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:175
constexpr uint32_t kNumPalettesets
Definition rom.h:42
constexpr uint32_t kNormalGfxSpaceEnd
Definition rom.h:35
absl::Status SaveAllGraphicsData(Rom &rom, std::array< gfx::Bitmap, kNumGfxSheets > &gfx_sheets)
Definition rom.cc:256
bool strip_header
Definition rom.h:48
static RomLoadOptions AppDefaults()
Definition rom.cc:50
bool load_zelda3_content
Definition rom.h:47
bool expand_to_full_image
Definition rom.h:52
bool populate_palettes
Definition rom.h:50
static RomLoadOptions CliDefaults()
Definition rom.cc:52
bool populate_metadata
Definition rom.h:49
static RomLoadOptions RawDataOnly()
Definition rom.cc:61
bool populate_gfx_groups
Definition rom.h:51
bool load_resource_labels
Definition rom.h:53
std::string filename
Definition rom.h:80
std::variant< int, uint8_t, uint16_t, short, std::vector< uint8_t >, gfx::SnesColor, std::vector< gfx::SnesColor > > ValueType
Definition rom.h:154
ValueType value
Definition rom.h:156
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.