yaze 0.2.0
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 <cstdint>
5#include <cstdlib>
6#include <cstring>
7#include <iostream>
8#include <vector>
9
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
12#include "app/core/constants.h"
13#include "app/gfx/snes_color.h"
14#include "imgui/imgui.h"
15#include "snes_color.h"
16
17namespace yaze {
18namespace app {
19namespace gfx {
20
21constexpr int kNumPalettes = 14;
22
39
40static constexpr absl::string_view kPaletteCategoryNames[] = {
41 "Sword", "Shield", "Clothes", "World Colors",
42 "Area Colors", "Global Sprites", "Sprites Aux1", "Sprites Aux2",
43 "Sprites Aux3", "Dungeons", "World Map", "Dungeon Map",
44 "Triforce", "Crystal"};
45
46static constexpr absl::string_view kPaletteGroupNames[] = {
47 "swords", "shields", "armors", "ow_main",
48 "ow_aux", "global_sprites", "sprites_aux1", "sprites_aux2",
49 "sprites_aux3", "dungeon_main", "ow_mini_map", "ow_mini_map",
50 "3d_object", "3d_object"};
51
52constexpr const char *kPaletteGroupAddressesKeys[] = {
53 "ow_main", "ow_aux", "ow_animated", "hud",
54 "global_sprites", "armors", "swords", "shields",
55 "sprites_aux1", "sprites_aux2", "sprites_aux3", "dungeon_main",
56 "grass", "3d_object", "ow_mini_map",
57};
58
59constexpr int kOverworldPaletteMain = 0xDE6C8;
60constexpr int kOverworldPaletteAux = 0xDE86C;
61constexpr int kOverworldPaletteAnimated = 0xDE604;
62constexpr int kGlobalSpritesLW = 0xDD218;
63constexpr int kGlobalSpritePalettesDW = 0xDD290;
64constexpr int kArmorPalettes =
65 0xDD308;
66constexpr int kSpritesPalettesAux1 = 0xDD39E; // 7 colors each
67constexpr int kSpritesPalettesAux2 = 0xDD446; // 7 colors each
68constexpr int kSpritesPalettesAux3 = 0xDD4E0; // 7 colors each
69constexpr int kSwordPalettes = 0xDD630; // 3 colors each - 4 entries
70constexpr int kShieldPalettes = 0xDD648; // 4 colors each - 3 entries
71constexpr int kHudPalettes = 0xDD660;
72constexpr int kDungeonMapPalettes = 0xDD70A; // 21 colors
73constexpr int kDungeonMainPalettes =
74 0xDD734; // (15*6) colors each - 20 entries
75constexpr int kDungeonMapBgPalettes = 0xDE544; // 16*6
76
77// Mirrored Value at 0x75645 : 0x75625
78constexpr int kHardcodedGrassLW = 0x5FEA9;
79constexpr int kHardcodedGrassDW = 0x05FEB3; // 0x7564F
80constexpr int kHardcodedGrassSpecial = 0x75640;
81constexpr int kOverworldMiniMapPalettes = 0x55B27;
82constexpr int kTriforcePalette = 0x64425;
83constexpr int kCrystalPalette = 0xF4CD3;
85 0x140000;
87constexpr int CustomAreaSpecificBGASM = 0x140150;
88
89// 1 byte, not 0 if enabled
90constexpr int kCustomAreaSpecificBGEnabled = 0x140140;
91
92uint32_t GetPaletteAddress(const std::string &group_name, size_t palette_index,
93 size_t color_index);
94
108 public:
109 template <typename T>
110 explicit SnesPalette(const std::vector<T> &data) {
111 for (const auto &item : data) {
112 colors.emplace_back(SnesColor(item));
113 }
114 }
115
116 SnesPalette() = default;
117 explicit SnesPalette(char *snesPal);
118 explicit SnesPalette(const unsigned char *snes_pal);
119 explicit SnesPalette(const std::vector<ImVec4> &);
120 explicit SnesPalette(const std::vector<snes_color> &);
121 explicit SnesPalette(const std::vector<SnesColor> &);
122
123 void Create(const std::vector<SnesColor> &cols) {
124 for (const auto &each : cols) {
125 colors.emplace_back(each);
126 }
127 }
128
129 void AddColor(const SnesColor &color) { colors.emplace_back(color); }
130 void AddColor(const snes_color &color) { colors.emplace_back(color); }
131 void AddColor(uint16_t color) { colors.emplace_back(color); }
132
133 absl::StatusOr<SnesColor> GetColor(int i) const {
134 if (i > colors.size()) {
135 return absl::InvalidArgumentError("SnesPalette: Index out of bounds");
136 }
137 return colors[i];
138 }
139
140 auto mutable_color(int i) { return &colors[i]; }
141
142 void clear() { colors.clear(); }
143 auto size() const { return colors.size(); }
144 auto empty() const { return colors.empty(); }
145
147 if (i > colors.size()) {
148 std::cout << "SNESPalette: Index out of bounds" << std::endl;
149 return colors[0];
150 }
151 return colors[i];
152 }
153
154 void operator()(int i, const SnesColor &color) {
155 if (i >= colors.size()) {
156 std::cout << "SNESPalette: Index out of bounds" << std::endl;
157 }
158 colors[i] = color;
159 }
160
161 void operator()(int i, const ImVec4 &color) {
162 if (i >= colors.size()) {
163 std::cout << "SNESPalette: Index out of bounds" << std::endl;
164 return;
165 }
166 colors[i].set_rgb(color);
167 colors[i].set_modified(true);
168 }
169
170 SnesPalette sub_palette(int start, int end) const {
171 SnesPalette pal;
172 for (int i = start; i < end; i++) {
173 pal.AddColor(colors[i]);
174 }
175 return pal;
176 }
177
178 private:
179 std::vector<SnesColor> colors;
180};
181
182SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t *rom);
183
184std::array<float, 4> ToFloatArray(const SnesColor &color);
185
193 PaletteGroup() = default;
194
195 void AddPalette(SnesPalette pal) { palettes.emplace_back(pal); }
196
197 void AddColor(SnesColor color) {
198 if (palettes.empty()) {
199 palettes.emplace_back();
200 }
201 palettes[0].AddColor(color);
202 }
203
204 void clear() { palettes.clear(); }
205 void SetName(const std::string &name) { name_ = name; }
206 auto name() const { return name_; }
207 auto size() const { return palettes.size(); }
208 auto mutable_palette(int i) { return &palettes[i]; }
209 auto palette(int i) const { return palettes[i]; }
210
212 if (i > palettes.size()) {
213 std::cout << "PaletteGroup: Index out of bounds" << std::endl;
214 return palettes[0];
215 }
216 return palettes[i];
217 }
218
219 const SnesPalette &operator[](int i) const {
220 if (i > palettes.size()) {
221 std::cout << "PaletteGroup: Index out of bounds" << std::endl;
222 return palettes[0];
223 }
224 return palettes[i];
225 }
226
227 private:
228 std::string name_;
229 std::vector<SnesPalette> palettes;
230};
231
255
256 auto get_group(const std::string &group_name) {
257 if (group_name == "ow_main") {
258 return &overworld_main;
259 } else if (group_name == "ow_aux") {
260 return &overworld_aux;
261 } else if (group_name == "ow_animated") {
262 return &overworld_animated;
263 } else if (group_name == "hud") {
264 return &hud;
265 } else if (group_name == "global_sprites") {
266 return &global_sprites;
267 } else if (group_name == "armors") {
268 return &armors;
269 } else if (group_name == "swords") {
270 return &swords;
271 } else if (group_name == "shields") {
272 return &shields;
273 } else if (group_name == "sprites_aux1") {
274 return &sprites_aux1;
275 } else if (group_name == "sprites_aux2") {
276 return &sprites_aux2;
277 } else if (group_name == "sprites_aux3") {
278 return &sprites_aux3;
279 } else if (group_name == "dungeon_main") {
280 return &dungeon_main;
281 } else if (group_name == "grass") {
282 return &grass;
283 } else if (group_name == "3d_object") {
284 return &object_3d;
285 } else if (group_name == "ow_mini_map") {
286 return &overworld_mini_map;
287 } else {
288 throw std::out_of_range("PaletteGroupMap: Group not found");
289 }
290 }
291
292 template <typename Func>
293 absl::Status for_each(Func &&func) {
296 RETURN_IF_ERROR(func(hud));
298 RETURN_IF_ERROR(func(armors));
299 RETURN_IF_ERROR(func(swords));
305 RETURN_IF_ERROR(func(grass));
308 return absl::OkStatus();
309 }
310
328
329 bool empty() {
330 return overworld_main.size() == 0 && overworld_aux.size() == 0 &&
331 overworld_animated.size() == 0 && hud.size() == 0 &&
332 global_sprites.size() == 0 && armors.size() == 0 &&
333 swords.size() == 0 && shields.size() == 0 &&
334 sprites_aux1.size() == 0 && sprites_aux2.size() == 0 &&
335 sprites_aux3.size() == 0 && dungeon_main.size() == 0 &&
336 grass.size() == 0 && object_3d.size() == 0 &&
338 }
339};
340
341absl::StatusOr<PaletteGroup> CreatePaletteGroupFromColFile(
342 std::vector<SnesColor> &colors);
343
347absl::StatusOr<PaletteGroup> CreatePaletteGroupFromLargePalette(
348 SnesPalette &palette, int num_colors = 8);
349
359absl::Status LoadAllPalettes(const std::vector<uint8_t> &rom_data,
360 PaletteGroupMap &groups);
361
407
408} // namespace gfx
413protected:
414 // Palettesets for the tile16 individual tiles
415 static std::unordered_map<uint8_t, gfx::Paletteset> palettesets_;
416};
417
418
419} // namespace app
420} // namespace yaze
421
422#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:39
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
SnesPalette sub_palette(int start, int end) const
void AddColor(uint16_t color)
void AddColor(const SnesColor &color)
void operator()(int i, const ImVec4 &color)
void AddColor(const snes_color &color)
SnesColor & operator[](int i)
std::vector< SnesColor > colors
absl::StatusOr< SnesColor > GetColor(int i) const
SnesPalette(const std::vector< T > &data)
void Create(const std::vector< SnesColor > &cols)
void operator()(int i, const SnesColor &color)
#define RETURN_IF_ERROR(expression)
Definition constants.h:62
uint32_t GetPaletteAddress(const std::string &group_name, size_t palette_index, size_t color_index)
constexpr int CustomAreaSpecificBGASM
constexpr int kSwordPalettes
constexpr int kDungeonMapPalettes
constexpr int kOverworldMiniMapPalettes
constexpr int CustomAreaSpecificBGPalette
constexpr int kShieldPalettes
constexpr int kDungeonMapBgPalettes
constexpr int kHudPalettes
constexpr int kSpritesPalettesAux3
std::array< float, 4 > ToFloatArray(const SnesColor &color)
SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t *rom)
constexpr int kArmorPalettes
constexpr int kOverworldPaletteAnimated
absl::Status LoadAllPalettes(const std::vector< uint8_t > &rom_data, PaletteGroupMap &groups)
Loads all the palettes for the game.
constexpr int kHardcodedGrassDW
constexpr int kSpritesPalettesAux1
constexpr int kGlobalSpritePalettesDW
constexpr int kCrystalPalette
constexpr int kNumPalettes
constexpr int kTriforcePalette
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromColFile(std::vector< SnesColor > &palette_rows)
constexpr int kHardcodedGrassLW
constexpr int kOverworldPaletteMain
constexpr int kCustomAreaSpecificBGEnabled
constexpr int kOverworldPaletteAux
constexpr int kSpritesPalettesAux2
constexpr int kHardcodedGrassSpecial
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromLargePalette(SnesPalette &palette, int num_colors)
Take a SNESPalette, divide it into palettes of 8 colors.
constexpr int kGlobalSpritesLW
constexpr int kDungeonMainPalettes
Definition common.cc:22
Primitive of 16-bit RGB SNES color.
Definition snes_color.h:13
Represents a mapping of palette groups.
auto get_group(const std::string &group_name)
absl::Status for_each(Func &&func)
Represents a group of palettes.
std::vector< SnesPalette > palettes
const SnesPalette & operator[](int i) const
void AddPalette(SnesPalette pal)
void AddColor(SnesColor color)
void SetName(const std::string &name)
SnesPalette operator[](int i)
Represents a set of palettes used in a SNES graphics system.
Paletteset()=default
Default constructor for Paletteset.
gfx::SnesPalette animated
Paletteset(gfx::SnesPalette main, gfx::SnesPalette animated, gfx::SnesPalette aux1, gfx::SnesPalette aux2, gfx::SnesColor background, gfx::SnesPalette hud, gfx::SnesPalette spr, gfx::SnesPalette spr2, gfx::SnesPalette comp)
Constructor for Paletteset.
gfx::SnesPalette composite