yaze 0.2.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 auto begin() { return colors_.begin(); }
148 auto end() { return colors_.begin() + size_; }
149 auto begin() const { return colors_.begin(); }
150 auto end() const { return colors_.begin() + size_; }
151
152 void AddColor(const SnesColor& color) {
153 if (size_ < kMaxColors) {
154 colors_[size_++] = color;
155 }
156 }
157
158 void UpdateColor(size_t index, const SnesColor& color) {
159 if (index < size_) {
160 colors_[index] = color;
161 }
162 }
163
164 void clear() { size_ = 0; }
165
166 SnesPalette sub_palette(size_t start, size_t length) const {
167 SnesPalette result;
168 if (start >= size_) {
169 return result;
170 }
171 length = std::min(length, size_ - start);
172 for (size_t i = 0; i < length; ++i) {
173 result.AddColor(colors_[start + i]);
174 }
175 return result;
176 }
177
178 bool operator==(const SnesPalette& other) const {
179 if (size_ != other.size_) {
180 return false;
181 }
182 for (size_t i = 0; i < size_; ++i) {
183 if (colors_[i].snes() != other.colors_[i].snes()) {
184 return false;
185 }
186 }
187 return true;
188 }
189
190 bool operator!=(const SnesPalette& other) const { return !(*this == other); }
191
192 private:
194 size_t size_;
195};
196
197SnesPalette ReadPaletteFromRom(int offset, int num_colors, const uint8_t* rom);
198
199std::array<float, 4> ToFloatArray(const SnesColor& color);
200
208 PaletteGroup() = default;
209 PaletteGroup(const std::string& name) : name_(name) {}
210
211 void AddPalette(SnesPalette pal) { palettes.emplace_back(pal); }
212
213 void AddColor(SnesColor color) {
214 if (palettes.empty()) {
215 palettes.emplace_back();
216 }
217 palettes[0].AddColor(color);
218 }
219
220 void clear() { palettes.clear(); }
221 auto name() const { return name_; }
222 auto size() const { return palettes.size(); }
223 auto palette(int i) const { return palettes[i]; }
224 auto mutable_palette(int i) { return &palettes[i]; }
225
227 if (i > palettes.size()) {
228 std::cout << "PaletteGroup: Index out of bounds" << std::endl;
229 return palettes[0];
230 }
231 return palettes[i];
232 }
233
234 const SnesPalette& operator[](int i) const {
235 if (i > palettes.size()) {
236 std::cout << "PaletteGroup: Index out of bounds" << std::endl;
237 return palettes[0];
238 }
239 return palettes[i];
240 }
241
242 private:
243 std::string name_;
244 std::vector<SnesPalette> palettes;
245};
246
270
271 auto get_group(const std::string& group_name) {
272 if (group_name == "ow_main") {
273 return &overworld_main;
274 } else if (group_name == "ow_aux") {
275 return &overworld_aux;
276 } else if (group_name == "ow_animated") {
277 return &overworld_animated;
278 } else if (group_name == "hud") {
279 return &hud;
280 } else if (group_name == "global_sprites") {
281 return &global_sprites;
282 } else if (group_name == "armors") {
283 return &armors;
284 } else if (group_name == "swords") {
285 return &swords;
286 } else if (group_name == "shields") {
287 return &shields;
288 } else if (group_name == "sprites_aux1") {
289 return &sprites_aux1;
290 } else if (group_name == "sprites_aux2") {
291 return &sprites_aux2;
292 } else if (group_name == "sprites_aux3") {
293 return &sprites_aux3;
294 } else if (group_name == "dungeon_main") {
295 return &dungeon_main;
296 } else if (group_name == "grass") {
297 return &grass;
298 } else if (group_name == "3d_object") {
299 return &object_3d;
300 } else if (group_name == "ow_mini_map") {
301 return &overworld_mini_map;
302 } else {
303 throw std::out_of_range("PaletteGroupMap: Group not found");
304 }
305 }
306
307 template <typename Func>
308 absl::Status for_each(Func&& func) {
311 RETURN_IF_ERROR(func(hud));
313 RETURN_IF_ERROR(func(armors));
314 RETURN_IF_ERROR(func(swords));
320 RETURN_IF_ERROR(func(grass));
323 return absl::OkStatus();
324 }
325
326 void clear() {
327 overworld_main.clear();
328 overworld_aux.clear();
329 overworld_animated.clear();
330 hud.clear();
331 global_sprites.clear();
332 armors.clear();
333 swords.clear();
334 shields.clear();
335 sprites_aux1.clear();
336 sprites_aux2.clear();
337 sprites_aux3.clear();
338 dungeon_main.clear();
339 grass.clear();
340 object_3d.clear();
341 overworld_mini_map.clear();
342 }
343
344 bool empty() {
345 return overworld_main.size() == 0 && overworld_aux.size() == 0 &&
346 overworld_animated.size() == 0 && hud.size() == 0 &&
347 global_sprites.size() == 0 && armors.size() == 0 &&
348 swords.size() == 0 && shields.size() == 0 &&
349 sprites_aux1.size() == 0 && sprites_aux2.size() == 0 &&
350 sprites_aux3.size() == 0 && dungeon_main.size() == 0 &&
351 grass.size() == 0 && object_3d.size() == 0 &&
352 overworld_mini_map.size() == 0;
353 }
354};
355
356absl::StatusOr<PaletteGroup> CreatePaletteGroupFromColFile(
357 std::vector<SnesColor>& colors);
358
362absl::StatusOr<PaletteGroup> CreatePaletteGroupFromLargePalette(
363 SnesPalette& palette, int num_colors = 8);
364
374absl::Status LoadAllPalettes(const std::vector<uint8_t>& rom_data,
375 PaletteGroupMap& groups);
376
422
427 protected:
428 // Palettesets for the tile16 individual tiles
429 static std::unordered_map<uint8_t, gfx::Paletteset> palettesets_;
430};
431
432} // namespace gfx
433} // namespace yaze
434
435#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 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
int main(int argc, char **argv)
Definition emu.cc:20
#define RETURN_IF_ERROR(expression)
Definition macro.h:51
Contains classes for handling graphical data.
Definition bitmap.cc:18
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.
Definition controller.cc:18
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)
const SnesPalette & operator[](int i) const
SnesPalette operator[](int i)
void AddPalette(SnesPalette pal)
PaletteGroup(const std::string &name)
gfx::SnesPalette spr
gfx::SnesPalette main_
gfx::SnesPalette animated
gfx::SnesPalette composite
gfx::SnesPalette hud
gfx::SnesPalette aux1
gfx::SnesPalette spr2
gfx::SnesColor background
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 aux2
Paletteset()=default
Default constructor for Paletteset.