yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
snes_palette.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GFX_PALETTE_H
2#define YAZE_APP_GFX_PALETTE_H
3
4#include <array>
5#include <cstdint>
6#include <cstdlib>
7#include <cstring>
8#include <iostream>
9#include <string>
10#include <vector>
11
12#include "absl/status/status.h"
13#include "absl/status/statusor.h"
15#include "imgui/imgui.h"
16#include "snes_color.h"
17#include "util/macro.h"
18
19namespace yaze {
20namespace gfx {
21
22constexpr int kNumPalettes = 14;
23
40
41static constexpr absl::string_view kPaletteCategoryNames[] = {
42 "Sword", "Shield", "Clothes", "World Colors",
43 "Area Colors", "Global Sprites", "Sprites Aux1", "Sprites Aux2",
44 "Sprites Aux3", "Dungeons", "World Map", "Dungeon Map",
45 "Triforce", "Crystal"};
46
47static constexpr absl::string_view kPaletteGroupNames[] = {
48 "swords", "shields", "armors", "ow_main",
49 "ow_aux", "global_sprites", "sprites_aux1", "sprites_aux2",
50 "sprites_aux3", "dungeon_main", "ow_mini_map", "ow_mini_map",
51 "3d_object", "3d_object"};
52
53constexpr const char* kPaletteGroupAddressesKeys[] = {
54 "ow_main", "ow_aux", "ow_animated", "hud",
55 "global_sprites", "armors", "swords", "shields",
56 "sprites_aux1", "sprites_aux2", "sprites_aux3", "dungeon_main",
57 "grass", "3d_object", "ow_mini_map",
58};
59
60constexpr int kOverworldPaletteMain = 0xDE6C8;
61constexpr int kOverworldPaletteAux = 0xDE86C;
62constexpr int kOverworldPaletteAnimated = 0xDE604;
63constexpr int kGlobalSpritesLW = 0xDD218;
64constexpr int kGlobalSpritePalettesDW = 0xDD290;
65
67constexpr int kArmorPalettes = 0xDD308;
68constexpr int kSpritesPalettesAux1 = 0xDD39E; // 7 colors each
69constexpr int kSpritesPalettesAux2 = 0xDD446; // 7 colors each
70constexpr int kSpritesPalettesAux3 = 0xDD4E0; // 7 colors each
71constexpr int kSwordPalettes = 0xDD630; // 3 colors each - 4 entries
72constexpr int kShieldPalettes = 0xDD648; // 4 colors each - 3 entries
73constexpr int kHudPalettes = 0xDD660;
74constexpr int kDungeonMapPalettes = 0xDD70A; // 21 colors
75
76// (15*6) colors each - 20 entries
77constexpr int kDungeonMainPalettes = 0xDD734;
78constexpr int kDungeonMapBgPalettes = 0xDE544; // 16*6
79
80// Mirrored Value at 0x75645 : 0x75625
81constexpr int kHardcodedGrassLW = 0x5FEA9;
82constexpr int kHardcodedGrassDW = 0x05FEB3; // 0x7564F
83constexpr int kHardcodedGrassSpecial = 0x75640;
84constexpr int kOverworldMiniMapPalettes = 0x55B27;
85constexpr int kTriforcePalette = 0x64425;
86constexpr int kCrystalPalette = 0xF4CD3;
87
89constexpr int CustomAreaSpecificBGPalette = 0x140000;
90constexpr int CustomAreaSpecificBGASM = 0x140150;
91
92// 1 byte, not 0 if enabled
93constexpr int kCustomAreaSpecificBGEnabled = 0x140140;
94
95constexpr int HudPalettesMax = 2;
96constexpr int OverworldMainPalettesMax = 6;
97constexpr int OverworldAuxPalettesMax = 20;
99constexpr int GlobalSpritePalettesMax = 2;
100constexpr int ArmorPalettesMax = 5;
101constexpr int SwordsPalettesMax = 4;
102constexpr int SpritesAux1PalettesMax = 12;
103constexpr int SpritesAux2PalettesMax = 11;
104constexpr int SpritesAux3PalettesMax = 24;
105constexpr int ShieldsPalettesMax = 3;
106constexpr int DungeonsMainPalettesMax = 20;
109constexpr int Object3DPalettesMax = 2;
111
112uint32_t GetPaletteAddress(const std::string& group_name, size_t palette_index,
113 size_t color_index);
114
128 public:
129 static constexpr size_t kMaxColors = 256;
130 using ColorArray = std::array<SnesColor, kMaxColors>;
131
133 SnesPalette(char* data);
134 SnesPalette(const unsigned char* snes_pal);
135 SnesPalette(const char* data, size_t length);
136 SnesPalette(const std::vector<uint16_t>& colors);
137 SnesPalette(const std::vector<SnesColor>& colors);
138 SnesPalette(const std::vector<ImVec4>& colors);
139
140 const SnesColor& operator[](size_t index) const { return colors_[index]; }
141 SnesColor& operator[](size_t index) { return colors_[index]; }
142
143 void set_size(size_t size) { size_ = size; }
144 size_t size() const { return size_; }
145 bool empty() const { return size_ == 0; }
146
147 // Resize
148 void Resize(size_t size) { size_ = size; }
149
150 auto begin() { return colors_.begin(); }
151 auto end() { return colors_.begin() + size_; }
152 auto begin() const { return colors_.begin(); }
153 auto end() const { return colors_.begin() + size_; }
154
155 void AddColor(const SnesColor& color) {
156 if (size_ < kMaxColors) {
157 colors_[size_++] = color;
158 }
159 }
160
161 void UpdateColor(size_t index, const SnesColor& color) {
162 if (index < size_) {
163 colors_[index] = color;
164 }
165 }
166
167 void clear() { size_ = 0; }
168
169 SnesPalette sub_palette(size_t start, size_t length) const {
170 SnesPalette result;
171 if (start >= size_) {
172 return result;
173 }
174 length = std::min(length, size_ - start);
175 for (size_t i = 0; i < length; ++i) {
176 result.AddColor(colors_[start + i]);
177 }
178 return result;
179 }
180
181 bool operator==(const SnesPalette& other) const {
182 if (size_ != other.size_) {
183 return false;
184 }
185 for (size_t i = 0; i < size_; ++i) {
186 if (colors_[i].snes() != other.colors_[i].snes()) {
187 return false;
188 }
189 }
190 return true;
191 }
192
193 bool operator!=(const SnesPalette& other) const { return !(*this == other); }
194
195 private:
197 size_t size_;
198};
199
200SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t* rom);
201
202std::array<float, 4> ToFloatArray(const SnesColor& color);
203
211 PaletteGroup() = default;
212 PaletteGroup(const std::string& name) : name_(name) {}
213
214 // ========== Basic Operations ==========
215
216 void AddPalette(SnesPalette pal) { palettes.emplace_back(pal); }
217
218 void AddColor(SnesColor color) {
219 if (palettes.empty()) {
220 palettes.emplace_back();
221 }
222 palettes[0].AddColor(color);
223 }
224
225 void clear() { palettes.clear(); }
226 void resize(size_t new_size) { palettes.resize(new_size); }
227
228 // ========== Accessors ==========
229
230 auto name() const { return name_; }
231 auto size() const { return palettes.size(); }
232 bool empty() const { return palettes.empty(); }
233
234 // Const access
235 auto palette(int i) const { return palettes[i]; }
236 const SnesPalette& palette_ref(int i) const { return palettes[i]; }
237
238 // Mutable access
239 auto mutable_palette(int i) { return &palettes[i]; }
240 SnesPalette& palette_ref(int i) { return palettes[i]; }
241
242 // ========== Color Operations ==========
243
250 SnesColor GetColor(int palette_index, int color_index) const {
251 if (palette_index >= 0 && palette_index < palettes.size()) {
252 const auto& pal = palettes[palette_index];
253 if (color_index >= 0 && color_index < pal.size()) {
254 return pal[color_index];
255 }
256 }
257 return SnesColor();
258 }
259
267 bool SetColor(int palette_index, int color_index, const SnesColor& color) {
268 if (palette_index >= 0 && palette_index < palettes.size()) {
269 auto& pal = palettes[palette_index];
270 if (color_index >= 0 && color_index < pal.size()) {
271 pal[color_index] = color;
272 return true;
273 }
274 }
275 return false;
276 }
277
278 // ========== Operator Overloads ==========
279
281 if (i >= palettes.size()) {
282 std::cout << "PaletteGroup: Index " << i << " out of bounds (size: "
283 << palettes.size() << ")" << std::endl;
284 return SnesPalette();
285 }
286 return palettes[i];
287 }
288
289 const SnesPalette& operator[](int i) const {
290 if (i >= palettes.size()) {
291 std::cout << "PaletteGroup: Index " << i << " out of bounds (size: "
292 << palettes.size() << ")" << std::endl;
293 static const SnesPalette empty_palette;
294 return empty_palette;
295 }
296 return palettes[i];
297 }
298
299 private:
300 std::string name_;
301 std::vector<SnesPalette> palettes;
302};
303
327
328 auto get_group(const std::string& group_name) {
329 if (group_name == "ow_main") {
330 return &overworld_main;
331 } else if (group_name == "ow_aux") {
332 return &overworld_aux;
333 } else if (group_name == "ow_animated") {
334 return &overworld_animated;
335 } else if (group_name == "hud") {
336 return &hud;
337 } else if (group_name == "global_sprites") {
338 return &global_sprites;
339 } else if (group_name == "armors") {
340 return &armors;
341 } else if (group_name == "swords") {
342 return &swords;
343 } else if (group_name == "shields") {
344 return &shields;
345 } else if (group_name == "sprites_aux1") {
346 return &sprites_aux1;
347 } else if (group_name == "sprites_aux2") {
348 return &sprites_aux2;
349 } else if (group_name == "sprites_aux3") {
350 return &sprites_aux3;
351 } else if (group_name == "dungeon_main") {
352 return &dungeon_main;
353 } else if (group_name == "grass") {
354 return &grass;
355 } else if (group_name == "3d_object") {
356 return &object_3d;
357 } else if (group_name == "ow_mini_map") {
358 return &overworld_mini_map;
359 } else {
360 throw std::out_of_range("PaletteGroupMap: Group not found");
361 }
362 }
363
364 template <typename Func>
365 absl::Status for_each(Func&& func) {
368 RETURN_IF_ERROR(func(hud));
370 RETURN_IF_ERROR(func(armors));
371 RETURN_IF_ERROR(func(swords));
377 RETURN_IF_ERROR(func(grass));
380 return absl::OkStatus();
381 }
382
400
401 bool empty() {
402 return overworld_main.size() == 0 && overworld_aux.size() == 0 &&
403 overworld_animated.size() == 0 && hud.size() == 0 &&
404 global_sprites.size() == 0 && armors.size() == 0 &&
405 swords.size() == 0 && shields.size() == 0 &&
406 sprites_aux1.size() == 0 && sprites_aux2.size() == 0 &&
407 sprites_aux3.size() == 0 && dungeon_main.size() == 0 &&
408 grass.size() == 0 && object_3d.size() == 0 &&
410 }
411};
412
413absl::StatusOr<PaletteGroup> CreatePaletteGroupFromColFile(
414 std::vector<SnesColor>& colors);
415
419absl::StatusOr<PaletteGroup> CreatePaletteGroupFromLargePalette(
420 SnesPalette& palette, int num_colors = 8);
421
431absl::Status LoadAllPalettes(const std::vector<uint8_t>& rom_data,
432 PaletteGroupMap& groups);
433
480
485 protected:
486 // Palettesets for the tile16 individual tiles
487 static std::unordered_map<uint8_t, gfx::Paletteset> palettesets_;
488};
489
490} // namespace gfx
491} // namespace yaze
492
493#endif // YAZE_APP_GFX_PALETTE_H
Shared graphical context across editors.
static std::unordered_map< uint8_t, gfx::Paletteset > palettesets_
SNES Color container.
Definition snes_color.h:109
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
void Resize(size_t size)
void AddColor(const SnesColor &color)
static constexpr size_t kMaxColors
std::array< SnesColor, kMaxColors > ColorArray
SnesPalette sub_palette(size_t start, size_t length) const
void set_size(size_t size)
SnesColor & operator[](size_t index)
bool operator!=(const SnesPalette &other) const
void UpdateColor(size_t index, const SnesColor &color)
const SnesColor & operator[](size_t index) const
bool operator==(const SnesPalette &other) const
#define RETURN_IF_ERROR(expression)
Definition macro.h:53
constexpr int kHardcodedGrassSpecial
constexpr int kHudPalettes
constexpr int kOverworldPaletteAux
constexpr int Object3DPalettesMax
SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t *rom)
Read a palette from ROM data.
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromLargePalette(SnesPalette &palette, int num_colors)
Create a PaletteGroup by dividing a large palette into sub-palettes.
constexpr int kHardcodedGrassLW
constexpr int kArmorPalettes
constexpr int kCrystalPalette
constexpr int HudPalettesMax
constexpr int OverworldAnimatedPalettesMax
constexpr int SpritesAux3PalettesMax
constexpr int SpritesAux1PalettesMax
constexpr int DungeonsMainPalettesMax
constexpr int OverworldGrassPalettesMax
constexpr int OverworldMiniMapPalettesMax
constexpr int SpritesAux2PalettesMax
constexpr const char * kPaletteGroupAddressesKeys[]
constexpr int kShieldPalettes
constexpr int kSpritesPalettesAux2
constexpr int kOverworldPaletteAnimated
constexpr int CustomAreaSpecificBGPalette
constexpr int kOverworldMiniMapPalettes
constexpr int kOverworldPaletteMain
constexpr int kDungeonMapPalettes
constexpr int kSwordPalettes
constexpr int kHardcodedGrassDW
constexpr int ShieldsPalettesMax
constexpr int ArmorPalettesMax
constexpr int kGlobalSpritesLW
constexpr int kSpritesPalettesAux1
constexpr int OverworldAuxPalettesMax
std::array< float, 4 > ToFloatArray(const SnesColor &color)
constexpr int kNumPalettes
constexpr int kCustomAreaSpecificBGEnabled
constexpr int kGlobalSpritePalettesDW
constexpr int kSpritesPalettesAux3
constexpr int kDungeonMainPalettes
uint32_t GetPaletteAddress(const std::string &group_name, size_t palette_index, size_t color_index)
constexpr int kDungeonMapBgPalettes
constexpr int kTriforcePalette
absl::Status LoadAllPalettes(const std::vector< uint8_t > &rom_data, PaletteGroupMap &groups)
Loads all the palettes for the game.
constexpr int SwordsPalettesMax
constexpr int OverworldBackgroundPaletteMax
constexpr int CustomAreaSpecificBGASM
constexpr int OverworldMainPalettesMax
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromColFile(std::vector< SnesColor > &palette_rows)
constexpr int GlobalSpritePalettesMax
Main namespace for the application.
Definition controller.cc:20
Represents a mapping of palette groups.
absl::Status for_each(Func &&func)
auto get_group(const std::string &group_name)
Represents a group of palettes.
std::vector< SnesPalette > palettes
bool SetColor(int palette_index, int color_index, const SnesColor &color)
Set a specific color in a palette.
auto palette(int i) const
SnesPalette & palette_ref(int i)
void AddColor(SnesColor color)
void resize(size_t new_size)
const SnesPalette & palette_ref(int i) const
const SnesPalette & operator[](int i) const
SnesColor GetColor(int palette_index, int color_index) const
Get a specific color from a palette.
SnesPalette operator[](int i)
void AddPalette(SnesPalette pal)
PaletteGroup(const std::string &name)
Represents a set of palettes used in a SNES graphics system.
gfx::SnesPalette spr
gfx::SnesPalette main_
Paletteset(const gfx::SnesPalette &main, const gfx::SnesPalette &animated, const gfx::SnesPalette &aux1, const gfx::SnesPalette &aux2, const gfx::SnesColor &background, const gfx::SnesPalette &hud, const gfx::SnesPalette &spr, const gfx::SnesPalette &spr2, const gfx::SnesPalette &comp)
Constructor for Paletteset.
gfx::SnesPalette animated
gfx::SnesPalette composite
gfx::SnesPalette hud
gfx::SnesPalette aux1
gfx::SnesPalette spr2
gfx::SnesColor background
gfx::SnesPalette aux2
Paletteset()=default
Default constructor for Paletteset.