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 <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
46static const std::map<zelda3_version, zelda3_version_pointers>
47 kVersionConstantsMap = {
48 {zelda3_version::US, zelda3_us_pointers},
49 {zelda3_version::JP, zelda3_jp_pointers},
52};
53
57class Rom {
58 public:
59 struct SaveSettings {
60 bool backup = false;
61 bool save_new = false;
62 bool z3_save = true;
63 std::string filename = "";
64 };
65
66 absl::Status LoadFromFile(const std::string& filename, bool z3_load = true);
67 absl::Status LoadFromData(const std::vector<uint8_t>& data,
68 bool z3_load = true);
69 absl::Status LoadZelda3();
70 absl::Status LoadGfxGroups();
71
72 absl::Status SaveGfxGroups();
73 absl::Status SaveToFile(const SaveSettings& settings);
74 absl::Status SavePalette(int index, const std::string& group_name,
75 gfx::SnesPalette& palette);
76 absl::Status SaveAllPalettes();
77
78 void Expand(int size) {
79 rom_data_.resize(size);
80 size_ = size;
81 }
82
83 void Close() {
84 rom_data_.clear();
85 palette_groups_.clear();
86 size_ = 0;
87 }
88
89 absl::StatusOr<uint8_t> ReadByte(int offset);
90 absl::StatusOr<uint16_t> ReadWord(int offset);
91 absl::StatusOr<uint32_t> ReadLong(int offset);
92 absl::StatusOr<std::vector<uint8_t>> ReadByteVector(uint32_t offset,
93 uint32_t length) const;
94 absl::StatusOr<gfx::Tile16> ReadTile16(uint32_t tile16_id);
95
96 absl::Status WriteTile16(int tile16_id, const gfx::Tile16& tile);
97 absl::Status WriteByte(int addr, uint8_t value);
98 absl::Status WriteWord(int addr, uint16_t value);
99 absl::Status WriteShort(int addr, uint16_t value);
100 absl::Status WriteLong(uint32_t addr, uint32_t value);
101 absl::Status WriteVector(int addr, std::vector<uint8_t> data);
102 absl::Status WriteColor(uint32_t address, const gfx::SnesColor& color);
103
104 template <typename... Args>
105 absl::Status WriteTransaction(Args... args) {
106 absl::Status status;
107 // Fold expression to apply the Write function on each argument
108 ((status = WriteHelper(args)), ...);
109 return status;
110 }
111
112 template <typename T, typename... Args>
113 absl::Status ReadTransaction(T& var, int address, Args&&... args) {
114 absl::Status status = ReadHelper<T>(var, address);
115 if (!status.ok()) {
116 return status;
117 }
118 if constexpr (sizeof...(args) > 0) {
119 status = ReadTransaction(std::forward<Args>(args)...);
120 }
121 return status;
122 }
123
124 struct WriteAction {
125 using ValueType =
126 std::variant<int, uint8_t, uint16_t, short, std::vector<uint8_t>,
127 gfx::SnesColor, std::vector<gfx::SnesColor>>;
130 };
131
132 virtual absl::Status WriteHelper(const WriteAction& action) {
133 if (std::holds_alternative<uint8_t>(action.value)) {
134 return WriteByte(action.address, std::get<uint8_t>(action.value));
135 } else if (std::holds_alternative<uint16_t>(action.value) ||
136 std::holds_alternative<short>(action.value)) {
137 return WriteShort(action.address, std::get<uint16_t>(action.value));
138 } else if (std::holds_alternative<std::vector<uint8_t>>(action.value)) {
139 return WriteVector(action.address,
140 std::get<std::vector<uint8_t>>(action.value));
141 } else if (std::holds_alternative<gfx::SnesColor>(action.value)) {
142 return WriteColor(action.address, std::get<gfx::SnesColor>(action.value));
143 } else if (std::holds_alternative<std::vector<gfx::SnesColor>>(
144 action.value)) {
145 return absl::UnimplementedError(
146 "WriteHelper: std::vector<gfx::SnesColor>");
147 }
148 auto error_message = absl::StrFormat("Invalid write argument type: %s",
149 typeid(action.value).name());
150 return absl::InvalidArgumentError(error_message);
151 }
152
153 template <typename T>
154 absl::Status ReadHelper(T& var, int address) {
155 if constexpr (std::is_same_v<T, uint8_t>) {
156 ASSIGN_OR_RETURN(auto result, ReadByte(address));
157 var = result;
158 } else if constexpr (std::is_same_v<T, uint16_t>) {
159 ASSIGN_OR_RETURN(auto result, ReadWord(address));
160 var = result;
161 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
162 ASSIGN_OR_RETURN(auto result, ReadByteVector(address, var.size()));
163 var = result;
164 }
165 return absl::OkStatus();
166 }
167
168 uint8_t& operator[](unsigned long i) {
169 if (i >= size_) throw std::out_of_range("Rom index out of range");
170 return rom_data_[i];
171 }
172
173 bool is_loaded() const { return !rom_data_.empty(); }
174 auto title() const { return title_; }
175 auto size() const { return size_; }
176 auto data() const { return rom_data_.data(); }
177 auto mutable_data() { return rom_data_.data(); }
178 auto begin() { return rom_data_.begin(); }
179 auto end() { return rom_data_.end(); }
180 auto vector() const { return rom_data_; }
181 auto filename() const { return filename_; }
182 auto set_filename(std::string_view name) { filename_ = name; }
183 auto short_name() const { return short_name_; }
184 auto graphics_buffer() const { return graphics_buffer_; }
186 auto palette_group() const { return palette_groups_; }
188 auto dungeon_palette(int i) { return palette_groups_.dungeon_main[i]; }
190 return palette_groups_.dungeon_main.mutable_palette(i);
191 }
192
195 return kVersionConstantsMap.at(version_);
196 }
197
198 std::array<std::array<uint8_t, 8>, kNumMainBlocksets> main_blockset_ids;
199 std::array<std::array<uint8_t, 4>, kNumRoomBlocksets> room_blockset_ids;
200 std::array<std::array<uint8_t, 4>, kNumSpritesets> spriteset_ids;
201 std::array<std::array<uint8_t, 4>, kNumPalettesets> paletteset_ids;
202
203 private:
204 // Size of the ROM data.
205 unsigned long size_ = 0;
206
207 // Title of the ROM loaded from the header
208 std::string title_ = "ROM not loaded";
209
210 // Filename of the ROM
211 std::string filename_ = "";
212
213 // Short name of the ROM
214 std::string short_name_ = "";
215
216 // Full contiguous rom space
217 std::vector<uint8_t> rom_data_;
218
219 // Full contiguous graphics space
220 std::vector<uint8_t> graphics_buffer_;
221
222 // Label manager for unique resource names.
224
225 // All palette groups in the game
227
228 // Version of the game
230};
231
250absl::StatusOr<std::array<gfx::Bitmap, kNumGfxSheets>> LoadAllGraphicsData(
251 Rom& rom, bool defer_render = false);
252
253absl::Status SaveAllGraphicsData(
254 Rom& rom, std::array<gfx::Bitmap, kNumGfxSheets>& gfx_sheets);
255
264absl::StatusOr<std::vector<uint8_t>> Load2BppGraphics(const Rom& rom);
265
269absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
270 const Rom& rom);
271
272absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom);
273
274} // namespace yaze
275
276#endif
The Rom class is used to load, save, and modify Rom data.
Definition rom.h:57
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length) const
Definition rom.cc:539
zelda3_version version_
Definition rom.h:229
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
Definition rom.cc:231
auto mutable_graphics_buffer()
Definition rom.h:185
absl::Status ReadTransaction(T &var, int address, Args &&... args)
Definition rom.h:113
auto begin()
Definition rom.h:178
std::vector< uint8_t > rom_data_
Definition rom.h:217
gfx::PaletteGroupMap palette_groups_
Definition rom.h:226
auto palette_group() const
Definition rom.h:186
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:181
auto mutable_palette_group()
Definition rom.h:187
absl::Status LoadFromData(const std::vector< uint8_t > &data, bool z3_load=true)
Definition rom.cc:271
auto end()
Definition rom.h:179
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:582
auto vector() const
Definition rom.h:180
auto mutable_data()
Definition rom.h:177
absl::Status LoadZelda3()
Definition rom.cc:284
std::array< std::array< uint8_t, 4 >, kNumSpritesets > spriteset_ids
Definition rom.h:200
ResourceLabelManager * resource_label()
Definition rom.h:193
std::array< std::array< uint8_t, 4 >, kNumPalettesets > paletteset_ids
Definition rom.h:201
auto mutable_dungeon_palette(int i)
Definition rom.h:189
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:208
absl::Status WriteTile16(int tile16_id, const gfx::Tile16 &tile)
Definition rom.cc:569
void Expand(int size)
Definition rom.h:78
absl::Status WriteTransaction(Args... args)
Definition rom.h:105
absl::Status SaveToFile(const SaveSettings &settings)
Definition rom.cc:386
std::array< std::array< uint8_t, 4 >, kNumRoomBlocksets > room_blockset_ids
Definition rom.h:199
virtual absl::Status WriteHelper(const WriteAction &action)
Definition rom.h:132
absl::StatusOr< uint32_t > ReadLong(int offset)
Definition rom.cc:530
auto data() const
Definition rom.h:176
auto size() const
Definition rom.h:175
std::vector< uint8_t > graphics_buffer_
Definition rom.h:220
zelda3_version_pointers version_constants() const
Definition rom.h:194
absl::Status SaveGfxGroups()
Definition rom.cc:353
ResourceLabelManager resource_label_manager_
Definition rom.h:223
absl::Status LoadGfxGroups()
Definition rom.cc:320
auto short_name() const
Definition rom.h:183
absl::Status ReadHelper(T &var, int address)
Definition rom.h:154
std::string filename_
Definition rom.h:211
unsigned long size_
Definition rom.h:205
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:188
void Close()
Definition rom.h:83
uint8_t & operator[](unsigned long i)
Definition rom.h:168
auto set_filename(std::string_view name)
Definition rom.h:182
std::string short_name_
Definition rom.h:214
bool is_loaded() const
Definition rom.h:173
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:174
std::array< std::array< uint8_t, 8 >, kNumMainBlocksets > main_blockset_ids
Definition rom.h:198
auto graphics_buffer() const
Definition rom.h:184
absl::Status SaveAllPalettes()
Definition rom.cc:502
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:12
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: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: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:77
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:135
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:194
std::string filename
Definition rom.h:63
std::variant< int, uint8_t, uint16_t, short, std::vector< uint8_t >, gfx::SnesColor, std::vector< gfx::SnesColor > > ValueType
Definition rom.h:125
ValueType value
Definition rom.h:129
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