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"
14#include "app/gfx/snes_color.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 void AddPalette(SnesPalette pal) { palettes.emplace_back(pal); }
215
216 void AddColor(SnesColor color) {
217 if (palettes.empty()) {
218 palettes.emplace_back();
219 }
220 palettes[0].AddColor(color);
221 }
222
223 void clear() { palettes.clear(); }
224 void resize(size_t new_size) { palettes.resize(new_size); }
225 auto name() const { return name_; }
226 auto size() const { return palettes.size(); }
227 auto palette(int i) const { return palettes[i]; }
228 auto mutable_palette(int i) { return &palettes[i]; }
229
231 if (i > palettes.size()) {
232 std::cout << "PaletteGroup: Index out of bounds" << std::endl;
233 return palettes[0];
234 }
235 return palettes[i];
236 }
237
238 const SnesPalette& operator[](int i) const {
239 if (i > palettes.size()) {
240 std::cout << "PaletteGroup: Index out of bounds" << std::endl;
241 return palettes[0];
242 }
243 return palettes[i];
244 }
245
246 private:
247 std::string name_;
248 std::vector<SnesPalette> palettes;
249};
250
274
275 auto get_group(const std::string& group_name) {
276 if (group_name == "ow_main") {
277 return &overworld_main;
278 } else if (group_name == "ow_aux") {
279 return &overworld_aux;
280 } else if (group_name == "ow_animated") {
281 return &overworld_animated;
282 } else if (group_name == "hud") {
283 return &hud;
284 } else if (group_name == "global_sprites") {
285 return &global_sprites;
286 } else if (group_name == "armors") {
287 return &armors;
288 } else if (group_name == "swords") {
289 return &swords;
290 } else if (group_name == "shields") {
291 return &shields;
292 } else if (group_name == "sprites_aux1") {
293 return &sprites_aux1;
294 } else if (group_name == "sprites_aux2") {
295 return &sprites_aux2;
296 } else if (group_name == "sprites_aux3") {
297 return &sprites_aux3;
298 } else if (group_name == "dungeon_main") {
299 return &dungeon_main;
300 } else if (group_name == "grass") {
301 return &grass;
302 } else if (group_name == "3d_object") {
303 return &object_3d;
304 } else if (group_name == "ow_mini_map") {
305 return &overworld_mini_map;
306 } else {
307 throw std::out_of_range("PaletteGroupMap: Group not found");
308 }
309 }
310
311 template <typename Func>
312 absl::Status for_each(Func&& func) {
315 RETURN_IF_ERROR(func(hud));
317 RETURN_IF_ERROR(func(armors));
318 RETURN_IF_ERROR(func(swords));
324 RETURN_IF_ERROR(func(grass));
327 return absl::OkStatus();
328 }
329
347
348 bool empty() {
349 return overworld_main.size() == 0 && overworld_aux.size() == 0 &&
350 overworld_animated.size() == 0 && hud.size() == 0 &&
351 global_sprites.size() == 0 && armors.size() == 0 &&
352 swords.size() == 0 && shields.size() == 0 &&
353 sprites_aux1.size() == 0 && sprites_aux2.size() == 0 &&
354 sprites_aux3.size() == 0 && dungeon_main.size() == 0 &&
355 grass.size() == 0 && object_3d.size() == 0 &&
357 }
358};
359
360absl::StatusOr<PaletteGroup> CreatePaletteGroupFromColFile(
361 std::vector<SnesColor>& colors);
362
366absl::StatusOr<PaletteGroup> CreatePaletteGroupFromLargePalette(
367 SnesPalette& palette, int num_colors = 8);
368
378absl::Status LoadAllPalettes(const std::vector<uint8_t>& rom_data,
379 PaletteGroupMap& groups);
380
427
432 protected:
433 // Palettesets for the tile16 individual tiles
434 static std::unordered_map<uint8_t, gfx::Paletteset> palettesets_;
435};
436
437} // namespace gfx
438} // namespace yaze
439
440#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:38
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)
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 > CreatePaletteGroupFromLargePalette(SnesPalette &palette, int num_colors)
Take a SNESPalette, divide it into palettes of 8 colors.
absl::StatusOr< PaletteGroup > CreatePaletteGroupFromColFile(std::vector< SnesColor > &palette_rows)
constexpr int GlobalSpritePalettesMax
Main namespace for the application.
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
auto palette(int i) const
void AddColor(SnesColor color)
void resize(size_t new_size)
const SnesPalette & operator[](int i) const
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.