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_ROM_ROM_H
2#define YAZE_ROM_ROM_H
3
4#include <cstddef>
5#include <cstdint>
6#include <map>
7#include <string>
8#include <variant>
9#include <vector>
10
11#include "absl/status/status.h"
12#include "absl/status/statusor.h"
15#include "core/project.h"
16#include "rom/rom_diagnostics.h"
17
18namespace yaze {
19
20namespace rom {
21class WriteFence;
22} // namespace rom
23
28class Rom {
29 public:
30 struct SaveSettings {
31 bool backup = false;
32 bool save_new = false;
33 std::string filename;
34 // Require a successful backup of an existing save target before replacing
35 // it. Unlike the legacy best-effort `backup` flag, backup failure aborts
36 // the save. A new target has no previous bytes to protect. This implies
37 // backup creation when `backup` is false.
38 bool require_backup = false;
39 };
40
41 struct LoadOptions {
42 bool strip_header = true;
44
45 static LoadOptions Defaults() { return LoadOptions{}; }
46 };
47
48 Rom() = default;
49 ~Rom() = default;
50
51 absl::Status LoadFromFile(
52 const std::string& filename,
53 const LoadOptions& options = LoadOptions::Defaults());
54 absl::Status LoadFromData(
55 const std::vector<uint8_t>& data,
56 const LoadOptions& options = LoadOptions::Defaults());
57
58 absl::Status SaveToFile(const SaveSettings& settings);
59
60 void Expand(int size) {
61 rom_data_.resize(size);
62 size_ = size;
63 }
64
65 void Close() {
66 rom_data_.clear();
67 size_ = 0;
68 }
69
70 // Raw access
71 absl::StatusOr<uint8_t> ReadByte(int offset) const;
72 absl::StatusOr<uint16_t> ReadWord(int offset) const;
73 absl::StatusOr<uint32_t> ReadLong(int offset) const;
74 absl::StatusOr<std::vector<uint8_t>> ReadByteVector(uint32_t offset,
75 uint32_t length) const;
76 absl::StatusOr<gfx::Tile16> ReadTile16(uint32_t tile16_id,
78
79 absl::Status WriteTile16(int tile16_id, uint32_t tile16_ptr,
80 const gfx::Tile16& tile);
81 absl::Status WriteByte(int addr, uint8_t value);
82 absl::Status WriteWord(int addr, uint16_t value);
83 absl::Status WriteShort(int addr, uint16_t value);
84 absl::Status WriteLong(uint32_t addr, uint32_t value);
85 absl::Status WriteVector(int addr, std::vector<uint8_t> data);
86 absl::Status WriteColor(uint32_t address, const gfx::SnesColor& color);
87
88 template <typename... Args>
89 absl::Status WriteTransaction(Args... args) {
90 absl::Status status;
91 ((status = WriteHelper(args)), ...);
92 return status;
93 }
94
95 template <typename T, typename... Args>
96 absl::Status ReadTransaction(T& var, int address, Args&&... args) {
97 absl::Status status = ReadHelper<T>(var, address);
98 if (!status.ok()) {
99 return status;
100 }
101 if constexpr (sizeof...(args) > 0) {
102 status = ReadTransaction(std::forward<Args>(args)...);
103 }
104 return status;
105 }
106
107 struct WriteAction {
108 using ValueType =
109 std::variant<int, uint8_t, uint16_t, short, std::vector<uint8_t>,
110 gfx::SnesColor, std::vector<gfx::SnesColor>>;
113 };
114
115 virtual absl::Status WriteHelper(const WriteAction& action);
116
117 template <typename T>
118 absl::Status ReadHelper(T& var, int address) {
119 if constexpr (std::is_same_v<T, uint8_t>) {
120 auto result = ReadByte(address);
121 if (!result.ok())
122 return result.status();
123 var = *result;
124 } else if constexpr (std::is_same_v<T, uint16_t>) {
125 auto result = ReadWord(address);
126 if (!result.ok())
127 return result.status();
128 var = *result;
129 } else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
130 auto result = ReadByteVector(address, var.size());
131 if (!result.ok())
132 return result.status();
133 var = *result;
134 }
135 return absl::OkStatus();
136 }
137
138 uint8_t& operator[](unsigned long i) {
139 if (i >= size_)
140 throw std::out_of_range("Rom index out of range");
141 return rom_data_[i];
142 }
143
144 bool is_loaded() const { return !rom_data_.empty(); }
145 bool dirty() const { return dirty_; }
146 void set_dirty(bool dirty) { dirty_ = dirty; }
147 void ClearDirty() { dirty_ = false; }
148
149 auto title() const { return title_; }
150 auto size() const { return size_; }
151 auto data() const { return rom_data_.data(); }
152 auto mutable_data() { return rom_data_.data(); }
153 auto begin() { return rom_data_.begin(); }
154 auto end() { return rom_data_.end(); }
155 const auto& vector() const { return rom_data_; }
156 auto& mutable_vector() { return rom_data_; }
157 auto filename() const { return filename_; }
158 auto set_filename(std::string_view name) { filename_ = name; }
159 auto short_name() const { return short_name_; }
160
161 // Resource labels are generic enough to keep here
165
166 // ROM write fence stack.
167 //
168 // When one or more fences are active, Rom::Write* calls must be allowed by
169 // every fence (logical AND). This is used for strict save-time guardrails so
170 // feature writers can't clobber reserved regions.
173 size_t write_fence_depth() const { return write_fence_stack_.size(); }
174
175 private:
176 // Size of the ROM data.
177 unsigned long size_ = 0;
178
179 // Title of the ROM loaded from the header
180 std::string title_ = "ROM not loaded";
181
182 // Filename of the ROM
183 std::string filename_;
184
185 // Short name of the ROM
186 std::string short_name_;
187
188 // Full contiguous rom space
189 std::vector<uint8_t> rom_data_;
190
191 // Label manager for unique resource names.
193
194 // True if there are unsaved changes
195 bool dirty_ = false;
196
197 // Active write fences (not owned).
198 std::vector<rom::WriteFence*> write_fence_stack_;
199};
200
201} // namespace yaze
202
203#endif // YAZE_ROM_ROM_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
absl::StatusOr< std::vector< uint8_t > > ReadByteVector(uint32_t offset, uint32_t length) const
Definition rom.cc:541
void PushWriteFence(rom::WriteFence *fence)
Definition rom.cc:490
~Rom()=default
project::ResourceLabelManager * resource_label()
Definition rom.h:162
absl::Status ReadTransaction(T &var, int address, Args &&... args)
Definition rom.h:96
absl::Status LoadFromFile(const std::string &filename, const LoadOptions &options=LoadOptions::Defaults())
Definition rom.cc:227
auto begin()
Definition rom.h:153
void ClearDirty()
Definition rom.h:147
absl::StatusOr< gfx::Tile16 > ReadTile16(uint32_t tile16_id, uint32_t tile16_ptr)
Definition rom.cc:554
absl::Status WriteColor(uint32_t address, const gfx::SnesColor &color)
Definition rom.cc:688
auto filename() const
Definition rom.h:157
void PopWriteFence(rom::WriteFence *fence)
Definition rom.cc:497
auto end()
Definition rom.h:154
absl::Status WriteByte(int addr, uint8_t value)
Definition rom.cc:586
absl::StatusOr< uint8_t > ReadByte(int offset) const
Definition rom.cc:518
absl::Status WriteTile16(int tile16_id, uint32_t tile16_ptr, const gfx::Tile16 &tile)
Definition rom.cc:573
void set_dirty(bool dirty)
Definition rom.h:146
auto mutable_data()
Definition rom.h:152
const auto & vector() const
Definition rom.h:155
absl::Status WriteVector(int addr, std::vector< uint8_t > data)
Definition rom.cc:658
std::string title_
Definition rom.h:180
void Expand(int size)
Definition rom.h:60
absl::Status WriteTransaction(Args... args)
Definition rom.h:89
absl::Status SaveToFile(const SaveSettings &settings)
Definition rom.cc:371
absl::StatusOr< uint16_t > ReadWord(int offset) const
Definition rom.cc:526
std::vector< uint8_t > rom_data_
Definition rom.h:189
Rom()=default
auto data() const
Definition rom.h:151
auto size() const
Definition rom.h:150
std::vector< rom::WriteFence * > write_fence_stack_
Definition rom.h:198
bool dirty() const
Definition rom.h:145
bool dirty_
Definition rom.h:195
auto & mutable_vector()
Definition rom.h:156
absl::Status LoadFromData(const std::vector< uint8_t > &data, const LoadOptions &options=LoadOptions::Defaults())
Definition rom.cc:335
auto short_name() const
Definition rom.h:159
absl::Status ReadHelper(T &var, int address)
Definition rom.h:118
std::string filename_
Definition rom.h:183
unsigned long size_
Definition rom.h:177
absl::Status WriteShort(int addr, uint16_t value)
Definition rom.cc:628
project::ResourceLabelManager resource_label_manager_
Definition rom.h:192
void Close()
Definition rom.h:65
uint8_t & operator[](unsigned long i)
Definition rom.h:138
auto set_filename(std::string_view name)
Definition rom.h:158
std::string short_name_
Definition rom.h:186
bool is_loaded() const
Definition rom.h:144
absl::Status WriteWord(int addr, uint16_t value)
Definition rom.cc:605
virtual absl::Status WriteHelper(const WriteAction &action)
Definition rom.cc:694
size_t write_fence_depth() const
Definition rom.h:173
absl::Status WriteLong(uint32_t addr, uint32_t value)
Definition rom.cc:632
auto title() const
Definition rom.h:149
absl::StatusOr< uint32_t > ReadLong(int offset) const
Definition rom.cc:533
SNES Color container.
Definition snes_color.h:110
Tile composition of four 8x8 tiles.
Definition snes_tile.h:142
Rom * rom()
Get the current ROM instance.
static LoadOptions Defaults()
Definition rom.h:45
bool load_resource_labels
Definition rom.h:43
std::string filename
Definition rom.h:33
std::variant< int, uint8_t, uint16_t, short, std::vector< uint8_t >, gfx::SnesColor, std::vector< gfx::SnesColor > > ValueType
Definition rom.h:108
ValueType value
Definition rom.h:112