yaze 0.2.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 <memory>
13#include <string>
14#include <variant>
15#include <vector>
16
17#include "absl/status/status.h"
18#include "absl/status/statusor.h"
19#include "absl/strings/str_format.h"
20#include "absl/strings/string_view.h"
21#include "app/core/project.h"
22#include "app/gfx/bitmap.h"
24#include "app/gfx/snes_tile.h"
25#include "util/macro.h"
26
27namespace yaze {
28
29constexpr uint32_t kNumGfxSheets = 223;
30constexpr uint32_t kNumLinkSheets = 14;
31constexpr uint32_t kTile16Ptr = 0x78000;
32constexpr uint32_t kNormalGfxSpaceStart = 0x87000;
33constexpr uint32_t kNormalGfxSpaceEnd = 0xC4200;
34constexpr uint32_t kFontSpriteLocation = 0x70000;
35constexpr uint32_t kGfxGroupsPointer = 0x6237;
36constexpr uint32_t kUncompressedSheetSize = 0x0800;
37constexpr uint32_t kNumMainBlocksets = 37;
38constexpr uint32_t kNumRoomBlocksets = 82;
39constexpr uint32_t kNumSpritesets = 144;
40constexpr uint32_t kNumPalettesets = 72;
41constexpr uint32_t kEntranceGfxGroup = 0x5D97;
42constexpr uint32_t kMaxGraphics = 0x0C3FFF; // 0xC3FB5
43
47static const std::map<zelda3_version, zelda3_version_pointers>
48 kVersionConstantsMap = {
49 {zelda3_version::US, zelda3_us_pointers},
50 {zelda3_version::JP, zelda3_jp_pointers},
53};
54
58class Rom {
59 public:
60 struct SaveSettings {
61 bool backup = false;
62 bool save_new = false;
63 bool z3_save = true;
64 std::string filename = "";
65 };
66
67 absl::Status LoadFromFile(const std::string& filename, bool z3_load = true);
68 absl::Status LoadFromData(const std::vector<uint8_t>& data,
69 bool z3_load = true);
70 absl::Status LoadZelda3();
71 absl::Status LoadGfxGroups();
72
73 absl::Status SaveGfxGroups();
74 absl::Status SaveToFile(const SaveSettings& settings);
75 absl::Status SavePalette(int index, const std::string& group_name,
76 gfx::SnesPalette& palette);
77 absl::Status SaveAllPalettes();
78
79 void Expand(int size) {
80 rom_data_.resize(size);
81 size_ = size;
82 }
83
84 void Close() {
85 rom_data_.clear();
86 palette_groups_.clear();
87 size_ = 0;
88 }
89
90 absl::StatusOr<uint8_t> ReadByte(int offset);
91 absl::StatusOr<uint16_t> ReadWord(int offset);
92 absl::StatusOr<uint32_t> ReadLong(int offset);
93 absl::StatusOr<std::vector<uint8_t>> ReadByteVector(uint32_t offset,
94 uint32_t length) const;
95 absl::StatusOr<gfx::Tile16> ReadTile16(uint32_t tile16_id);
96
97 absl::Status WriteTile16(int tile16_id, const gfx::Tile16& tile);
98 absl::Status WriteByte(int addr, uint8_t value);
99 absl::Status WriteWord(int addr, uint16_t value);
100 absl::Status WriteShort(int addr, uint16_t value);
101 absl::Status WriteLong(uint32_t addr, uint32_t value);
102 absl::Status WriteVector(int addr, std::vector<uint8_t> data);
103 absl::Status WriteColor(uint32_t address, const gfx::SnesColor& color);
104
105 template <typename... Args>
106 absl::Status WriteTransaction(Args... args) {
107 absl::Status status;
108 // Fold expression to apply the Write function on each argument
109 ((status = WriteHelper(args)), ...);
110 return status;
111 }
112
113 template <typename T, typename... Args>
114 absl::Status ReadTransaction(T& var, int address, Args&&... args) {
115 absl::Status status = ReadHelper<T>(var, address);
116 if (!status.ok()) {
117 return status;
118 }
119 if constexpr (sizeof...(args) > 0) {
120 status = ReadTransaction(std::forward<Args>(args)...);
121 }
122 return status;
123 }
124
125 struct WriteAction {
126 using ValueType =
127 std::variant<int, uint8_t, uint16_t, short, std::vector<uint8_t>,
128 gfx::SnesColor, std::vector<gfx::SnesColor>>;
131 };
132
133 virtual absl::Status WriteHelper(const WriteAction& action) {
134 if (std::holds_alternative<uint8_t>(action.value)) {
135 return WriteByte(action.address, std::get<uint8_t>(action.value));
136 } else if (std::holds_alternative<uint16_t>(action.value) ||
137 std::holds_alternative<short>(action.value)) {
138 return WriteShort(action.address, std::get<uint16_t>(action.value));
139 } else if (std::holds_alternative<std::vector<uint8_t>>(action.value)) {
140 return WriteVector(action.address,
141 std::get<std::vector<uint8_t>>(action.value));
142 } else if (std::holds_alternative<gfx::SnesColor>(action.value)) {
143 return WriteColor(action.address, std::get<gfx::SnesColor>(action.value));
144 } else if (std::holds_alternative<std::vector<gfx::SnesColor>>(
145 action.value)) {
146 return absl::UnimplementedError(
147 "WriteHelper: std::vector<gfx::SnesColor>");
148 }
149 auto error_message = absl::StrFormat("Invalid write argument type: %s",
150 typeid(action.value).name());
151 return absl::InvalidArgumentError(error_message);
152 }
153
154 template <typename T>
155 absl::Status ReadHelper(T& var, int address) {
156 if constexpr (std::is_same_v<T, uint8_t>) {
157 ASSIGN_OR_RETURN(auto result, ReadByte(address));
158 var = result;
159 } else if constexpr (std::is_same_v<T, uint16_t>) {
160 ASSIGN_OR_RETURN(auto result, ReadWord(address));
161 var = result;
162 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
163 ASSIGN_OR_RETURN(auto result, ReadByteVector(address, var.size()));
164 var = result;
165 }
166 return absl::OkStatus();
167 }
168
169 uint8_t& operator[](unsigned long i) {
170 if (i >= size_) throw std::out_of_range("Rom index out of range");
171 return rom_data_[i];
172 }
173
174 bool is_loaded() const { return !rom_data_.empty(); }
175 auto title() const { return title_; }
176 auto size() const { return size_; }
177 auto data() const { return rom_data_.data(); }
178 auto mutable_data() { return rom_data_.data(); }
179 auto begin() { return rom_data_.begin(); }
180 auto end() { return rom_data_.end(); }
181 auto vector() const { return rom_data_; }
182 auto filename() const { return filename_; }
183 auto set_filename(std::string_view name) { filename_ = name; }
184 auto short_name() const { return short_name_; }
185 auto graphics_buffer() const { return graphics_buffer_; }
187 auto palette_group() const { return palette_groups_; }
189 auto dungeon_palette(int i) { return palette_groups_.dungeon_main[i]; }
191 return palette_groups_.dungeon_main.mutable_palette(i);
192 }
193
196 return kVersionConstantsMap.at(version_);
197 }
198
199 std::array<std::array<uint8_t, 8>, kNumMainBlocksets> main_blockset_ids;
200 std::array<std::array<uint8_t, 4>, kNumRoomBlocksets> room_blockset_ids;
201 std::array<std::array<uint8_t, 4>, kNumSpritesets> spriteset_ids;
202 std::array<std::array<uint8_t, 4>, kNumPalettesets> paletteset_ids;
203
204 private:
205 // Size of the ROM data.
206 unsigned long size_ = 0;
207
208 // Title of the ROM loaded from the header
209 std::string title_ = "ROM not loaded";
210
211 // Filename of the ROM
212 std::string filename_ = "";
213
214 // Short name of the ROM
215 std::string short_name_ = "";
216
217 // Full contiguous rom space
218 std::vector<uint8_t> rom_data_;
219
220 // Full contiguous graphics space
221 std::vector<uint8_t> graphics_buffer_;
222
223 // Label manager for unique resource names.
225
226 // All palette groups in the game
228
229 // Version of the game
231};
232
251absl::StatusOr<std::array<gfx::Bitmap, kNumGfxSheets>> LoadAllGraphicsData(
252 Rom& rom, bool defer_render = false);
253
254absl::Status SaveAllGraphicsData(
255 Rom& rom, std::array<gfx::Bitmap, kNumGfxSheets>& gfx_sheets);
256
265absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom);
266
270absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
271 const Rom& rom);
272
273absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom);
274
279 public:
280 SharedRom() = default;
281 virtual ~SharedRom() = default;
282
283 std::shared_ptr<Rom> shared_rom() {
284 if (!shared_rom_) {
285 shared_rom_ = std::make_shared<Rom>();
286 }
287 return shared_rom_;
288 }
289
290 auto rom() {
291 if (!shared_rom_) {
292 shared_rom_ = std::make_shared<Rom>();
293 }
294 Rom* rom = shared_rom_.get();
295 return rom;
296 }
297
298 static void set_rom(Rom* rom) {
299 if (!shared_rom_) {
300 shared_rom_ = std::make_shared<Rom>();
301 }
302 shared_rom_ = std::shared_ptr<Rom>(rom);
303 }
304
305 // private:
306 static std::shared_ptr<Rom> shared_rom_;
307};
308
309} // namespace yaze
310
311#endif
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:58
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length) const
Definition rom.cc:539
zelda3_version version_
Definition rom.h:230
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
Definition rom.cc:231
auto mutable_graphics_buffer()
Definition rom.h:186
absl::Status ReadTransaction(T &var, int address, Args &&... args)
Definition rom.h:114
auto begin()
Definition rom.h:179
std::vector< uint8_t > rom_data_
Definition rom.h:218
gfx::PaletteGroupMap palette_groups_
Definition rom.h:227
auto palette_group() const
Definition rom.h:187
absl::StatusOr< gfx::Tile16 > ReadTile16(uint32_t tile16_id)
Definition rom.cc:551
absl::Status WriteColor(uint32_t address, const gfx::SnesColor &color)
Definition rom.cc:643
auto filename() const
Definition rom.h:182
auto mutable_palette_group()
Definition rom.h:188
absl::Status LoadFromData(const std::vector< uint8_t > &data, bool z3_load=true)
Definition rom.cc:271
auto end()
Definition rom.h:180
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:582
auto vector() const
Definition rom.h:181
auto mutable_data()
Definition rom.h:178
absl::Status LoadZelda3()
Definition rom.cc:284
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
Definition rom.h:201
ResourceLabelManager * resource_label()
Definition rom.h:194
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
Definition rom.h:202
auto mutable_dungeon_palette(int i)
Definition rom.h:190
absl::StatusOr< uint16_t > ReadWord(int offset)
Definition rom.cc:522
absl::Status WriteVector(int addr, std::vector< uint8_t > data)
Definition rom.cc:630
std::string title_
Definition rom.h:209
absl::Status WriteTile16(int tile16_id, const gfx::Tile16 &tile)
Definition rom.cc:569
void Expand(int size)
Definition rom.h:79
absl::Status WriteTransaction(Args... args)
Definition rom.h:106
absl::Status SaveToFile(const SaveSettings &settings)
Definition rom.cc:386
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
Definition rom.h:200
virtual absl::Status WriteHelper(const WriteAction &action)
Definition rom.h:133
absl::StatusOr< uint32_t > ReadLong(int offset)
Definition rom.cc:530
auto data() const
Definition rom.h:177
auto size() const
Definition rom.h:176
std::vector< uint8_t > graphics_buffer_
Definition rom.h:221
zelda3_version_pointers version_constants() const
Definition rom.h:195
absl::Status SaveGfxGroups()
Definition rom.cc:353
ResourceLabelManager resource_label_manager_
Definition rom.h:224
absl::Status LoadGfxGroups()
Definition rom.cc:320
auto short_name() const
Definition rom.h:184
absl::Status ReadHelper(T &var, int address)
Definition rom.h:155
std::string filename_
Definition rom.h:212
unsigned long size_
Definition rom.h:206
absl::Status SavePalette(int index, const std::string &group_name, gfx::SnesPalette &palette)
Definition rom.cc:488
absl::StatusOr< uint8_t > ReadByte(int offset)
Definition rom.cc:515
absl::Status WriteShort(int addr, uint16_t value)
Definition rom.cc:605
auto dungeon_palette(int i)
Definition rom.h:189
void Close()
Definition rom.h:84
uint8_t & operator[](unsigned long i)
Definition rom.h:169
auto set_filename(std::string_view name)
Definition rom.h:183
std::string short_name_
Definition rom.h:215
bool is_loaded() const
Definition rom.h:174
absl::Status WriteWord(int addr, uint16_t value)
Definition rom.cc:593
absl::Status WriteLong(uint32_t addr, uint32_t value)
Definition rom.cc:617
auto title() const
Definition rom.h:175
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
Definition rom.h:199
auto graphics_buffer() const
Definition rom.h:185
absl::Status SaveAllPalettes()
Definition rom.cc:502
virtual ~SharedRom()=default
static std::shared_ptr< Rom > shared_rom_
Definition rom.h:306
auto rom()
Definition rom.h:290
static void set_rom(Rom *rom)
Definition rom.h:298
std::shared_ptr< Rom > shared_rom()
Definition rom.h:283
SharedRom()=default
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
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:59
Main namespace for the application.
Definition controller.cc:18
constexpr uint32_t kMaxGraphics
Definition rom.h:42
constexpr uint32_t kGfxGroupsPointer
Definition rom.h:35
constexpr uint32_t kUncompressedSheetSize
Definition rom.h:36
absl::StatusOr< std::vector< uint8_t > > Load2BppGraphics(const Rom &rom)
Loads 2bpp graphics from Rom data.
Definition rom.cc:40
absl::StatusOr< std::array< gfx::Bitmap, kNumLinkSheets > > LoadLinkGraphics(const Rom &rom)
Loads the players 4bpp graphics sheet from Rom data.
Definition rom.cc:58
constexpr uint32_t kNumLinkSheets
Definition rom.h:30
constexpr uint32_t kNormalGfxSpaceStart
Definition rom.h:32
constexpr uint32_t kEntranceGfxGroup
Definition rom.h:41
constexpr uint32_t kFontSpriteLocation
Definition rom.h:34
constexpr uint32_t kNumSpritesets
Definition rom.h:39
constexpr uint32_t kTile16Ptr
Definition rom.h:31
constexpr uint32_t kNumMainBlocksets
Definition rom.h:37
constexpr uint32_t kNumRoomBlocksets
Definition rom.h:38
absl::StatusOr< gfx::Bitmap > LoadFontGraphics(const Rom &rom)
Definition rom.cc:77
constexpr uint32_t kNumGfxSheets
Definition rom.h:29
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:135
constexpr uint32_t kNumPalettesets
Definition rom.h:40
constexpr uint32_t kNormalGfxSpaceEnd
Definition rom.h:33
absl::Status SaveAllGraphicsData(Rom &rom, std::array< gfx::Bitmap, kNumGfxSheets > &gfx_sheets)
Definition rom.cc:194
std::string filename
Definition rom.h:64
std::variant< int, uint8_t, uint16_t, short, std::vector< uint8_t >, gfx::SnesColor, std::vector< gfx::SnesColor > > ValueType
Definition rom.h:126
ValueType value
Definition rom.h:130
Represents a mapping of palette groups.
Pointers for each version of the game.
Definition zelda.h:24
zelda3_version
Different versions of the game supported by yaze.
Definition zelda.h:14
@ US
Definition zelda.h:15
@ SD
Definition zelda.h:17
@ RANDO
Definition zelda.h:18
@ JP
Definition zelda.h:16