feat(editor): enhance EditorManager with card-based editor functionality
- Introduced methods to determine if an editor is card-based and to retrieve its category. - Implemented a sidebar toggle shortcut (Ctrl+B) for managing card visibility. - Added functionality to hide current editor cards when switching editors. - Updated editor initialization to register global shortcuts for activating specific editors. - Enhanced the Update method to draw a sidebar for the current category editor. Benefits: - Improved user experience by organizing editor cards and providing quick access to editor categories. - Streamlined editor management, making it easier to switch between different editing contexts.
This commit is contained in:
76
src/zelda3/palette_constants.cc
Normal file
76
src/zelda3/palette_constants.cc
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "zelda3/palette_constants.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace zelda3 {
|
||||
|
||||
const PaletteGroupMetadata* GetPaletteGroupMetadata(const char* group_id) {
|
||||
std::string id_str(group_id);
|
||||
|
||||
if (id_str == PaletteGroupName::kOverworldMain) {
|
||||
return &PaletteMetadata::kOverworldMain;
|
||||
} else if (id_str == PaletteGroupName::kOverworldAux) {
|
||||
return &PaletteMetadata::kOverworldAux;
|
||||
} else if (id_str == PaletteGroupName::kOverworldAnimated) {
|
||||
return &PaletteMetadata::kOverworldAnimated;
|
||||
} else if (id_str == PaletteGroupName::kDungeonMain) {
|
||||
return &PaletteMetadata::kDungeonMain;
|
||||
} else if (id_str == PaletteGroupName::kGlobalSprites) {
|
||||
return &PaletteMetadata::kGlobalSprites;
|
||||
} else if (id_str == PaletteGroupName::kSpritesAux1) {
|
||||
return &PaletteMetadata::kSpritesAux1;
|
||||
} else if (id_str == PaletteGroupName::kSpritesAux2) {
|
||||
return &PaletteMetadata::kSpritesAux2;
|
||||
} else if (id_str == PaletteGroupName::kSpritesAux3) {
|
||||
return &PaletteMetadata::kSpritesAux3;
|
||||
} else if (id_str == PaletteGroupName::kArmor) {
|
||||
return &PaletteMetadata::kArmor;
|
||||
} else if (id_str == PaletteGroupName::kSwords) {
|
||||
return &PaletteMetadata::kSwords;
|
||||
} else if (id_str == PaletteGroupName::kShields) {
|
||||
return &PaletteMetadata::kShields;
|
||||
} else if (id_str == PaletteGroupName::kHud) {
|
||||
return &PaletteMetadata::kHud;
|
||||
} else if (id_str == PaletteGroupName::kGrass) {
|
||||
return &PaletteMetadata::kGrass;
|
||||
} else if (id_str == PaletteGroupName::k3DObject) {
|
||||
return &PaletteMetadata::k3DObject;
|
||||
} else if (id_str == PaletteGroupName::kOverworldMiniMap) {
|
||||
return &PaletteMetadata::kOverworldMiniMap;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<const PaletteGroupMetadata*> GetAllPaletteGroups() {
|
||||
return {
|
||||
// Overworld
|
||||
&PaletteMetadata::kOverworldMain,
|
||||
&PaletteMetadata::kOverworldAux,
|
||||
&PaletteMetadata::kOverworldAnimated,
|
||||
|
||||
// Dungeon
|
||||
&PaletteMetadata::kDungeonMain,
|
||||
|
||||
// Sprites
|
||||
&PaletteMetadata::kGlobalSprites,
|
||||
&PaletteMetadata::kSpritesAux1,
|
||||
&PaletteMetadata::kSpritesAux2,
|
||||
&PaletteMetadata::kSpritesAux3,
|
||||
|
||||
// Equipment
|
||||
&PaletteMetadata::kArmor,
|
||||
&PaletteMetadata::kSwords,
|
||||
&PaletteMetadata::kShields,
|
||||
|
||||
// Interface
|
||||
&PaletteMetadata::kHud,
|
||||
&PaletteMetadata::kOverworldMiniMap,
|
||||
|
||||
// Special
|
||||
&PaletteMetadata::kGrass,
|
||||
&PaletteMetadata::k3DObject
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace zelda3
|
||||
} // namespace yaze
|
||||
|
||||
310
src/zelda3/palette_constants.h
Normal file
310
src/zelda3/palette_constants.h
Normal file
@@ -0,0 +1,310 @@
|
||||
#ifndef YAZE_ZELDA3_PALETTE_CONSTANTS_H
|
||||
#define YAZE_ZELDA3_PALETTE_CONSTANTS_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace yaze {
|
||||
namespace zelda3 {
|
||||
|
||||
// ============================================================================
|
||||
// Palette Group Names
|
||||
// ============================================================================
|
||||
// These constants ensure consistent naming across the entire program
|
||||
|
||||
namespace PaletteGroupName {
|
||||
constexpr const char* kOverworldMain = "ow_main";
|
||||
constexpr const char* kOverworldAux = "ow_aux";
|
||||
constexpr const char* kOverworldAnimated = "ow_animated";
|
||||
constexpr const char* kHud = "hud";
|
||||
constexpr const char* kGlobalSprites = "global_sprites";
|
||||
constexpr const char* kArmor = "armor";
|
||||
constexpr const char* kSwords = "swords";
|
||||
constexpr const char* kShields = "shields";
|
||||
constexpr const char* kSpritesAux1 = "sprites_aux1";
|
||||
constexpr const char* kSpritesAux2 = "sprites_aux2";
|
||||
constexpr const char* kSpritesAux3 = "sprites_aux3";
|
||||
constexpr const char* kDungeonMain = "dungeon_main";
|
||||
constexpr const char* kGrass = "grass";
|
||||
constexpr const char* k3DObject = "3d_object";
|
||||
constexpr const char* kOverworldMiniMap = "ow_mini_map";
|
||||
} // namespace PaletteGroupName
|
||||
|
||||
// ============================================================================
|
||||
// ROM Addresses
|
||||
// ============================================================================
|
||||
|
||||
namespace PaletteAddress {
|
||||
constexpr uint32_t kOverworldMain = 0xDE6C8;
|
||||
constexpr uint32_t kOverworldAux = 0xDE86C;
|
||||
constexpr uint32_t kOverworldAnimated = 0xDE604;
|
||||
constexpr uint32_t kGlobalSpritesLW = 0xDD218;
|
||||
constexpr uint32_t kGlobalSpritesDW = 0xDD290;
|
||||
constexpr uint32_t kArmor = 0xDD308;
|
||||
constexpr uint32_t kSpritesAux1 = 0xDD39E;
|
||||
constexpr uint32_t kSpritesAux2 = 0xDD446;
|
||||
constexpr uint32_t kSpritesAux3 = 0xDD4E0;
|
||||
constexpr uint32_t kSwords = 0xDD630;
|
||||
constexpr uint32_t kShields = 0xDD648;
|
||||
constexpr uint32_t kHud = 0xDD660;
|
||||
constexpr uint32_t kDungeonMap = 0xDD70A;
|
||||
constexpr uint32_t kDungeonMain = 0xDD734;
|
||||
constexpr uint32_t kDungeonMapBg = 0xDE544;
|
||||
constexpr uint32_t kGrassLW = 0x5FEA9;
|
||||
constexpr uint32_t kGrassDW = 0x05FEB3;
|
||||
constexpr uint32_t kGrassSpecial = 0x75640;
|
||||
constexpr uint32_t kOverworldMiniMap = 0x55B27;
|
||||
constexpr uint32_t kTriforce = 0x64425;
|
||||
constexpr uint32_t kCrystal = 0xF4CD3;
|
||||
} // namespace PaletteAddress
|
||||
|
||||
// ============================================================================
|
||||
// Palette Counts
|
||||
// ============================================================================
|
||||
|
||||
namespace PaletteCount {
|
||||
constexpr int kHud = 2;
|
||||
constexpr int kOverworldMain = 60; // 20 LW, 20 DW, 20 Special
|
||||
constexpr int kOverworldAux = 20;
|
||||
constexpr int kOverworldAnimated = 14;
|
||||
constexpr int kGlobalSprites = 6;
|
||||
constexpr int kArmor = 5;
|
||||
constexpr int kSwords = 4;
|
||||
constexpr int kSpritesAux1 = 12;
|
||||
constexpr int kSpritesAux2 = 11;
|
||||
constexpr int kSpritesAux3 = 24;
|
||||
constexpr int kShields = 3;
|
||||
constexpr int kDungeonMain = 20;
|
||||
constexpr int kGrass = 3;
|
||||
constexpr int k3DObject = 2;
|
||||
constexpr int kOverworldMiniMap = 2;
|
||||
} // namespace PaletteCount
|
||||
|
||||
// ============================================================================
|
||||
// Palette Metadata
|
||||
// ============================================================================
|
||||
|
||||
struct PaletteGroupMetadata {
|
||||
const char* group_id; // Unique identifier (e.g., "ow_main")
|
||||
const char* display_name; // Human-readable name
|
||||
const char* category; // Category (e.g., "Overworld", "Dungeon")
|
||||
uint32_t base_address; // ROM address
|
||||
int palette_count; // Number of palettes
|
||||
int colors_per_palette; // Colors in each palette
|
||||
int colors_per_row; // How many colors per row in UI
|
||||
int bits_per_pixel; // Color depth (typically 4 for SNES)
|
||||
const char* description; // Usage description
|
||||
bool has_animations; // Whether palettes animate
|
||||
};
|
||||
|
||||
// Predefined metadata for all palette groups
|
||||
namespace PaletteMetadata {
|
||||
|
||||
constexpr PaletteGroupMetadata kOverworldMain = {
|
||||
.group_id = PaletteGroupName::kOverworldMain,
|
||||
.display_name = "Overworld Main",
|
||||
.category = "Overworld",
|
||||
.base_address = PaletteAddress::kOverworldMain,
|
||||
.palette_count = PaletteCount::kOverworldMain,
|
||||
.colors_per_palette = 35, // 35 colors: 2 full rows (0-15, 16-31) + 3 colors (32-34)
|
||||
.colors_per_row = 7, // Display in 16-color rows for proper SNES alignment
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Main overworld palettes: 35 colors per set (2 full rows + 3 colors)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kOverworldAnimated = {
|
||||
.group_id = PaletteGroupName::kOverworldAnimated,
|
||||
.display_name = "Overworld Animated",
|
||||
.category = "Overworld",
|
||||
.base_address = PaletteAddress::kOverworldAnimated,
|
||||
.palette_count = PaletteCount::kOverworldAnimated,
|
||||
.colors_per_palette = 7, // 7 colors (overlay palette, no transparent)
|
||||
.colors_per_row = 8, // Display in 8-color groups
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Animated overlay palettes: 7 colors per set (water, lava, etc.)",
|
||||
.has_animations = true
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kDungeonMain = {
|
||||
.group_id = PaletteGroupName::kDungeonMain,
|
||||
.display_name = "Dungeon Main",
|
||||
.category = "Dungeon",
|
||||
.base_address = PaletteAddress::kDungeonMain,
|
||||
.palette_count = PaletteCount::kDungeonMain,
|
||||
.colors_per_palette = 90, // 90 colors: 5 full rows (0-15, 16-31, 32-47, 48-63, 64-79) + 10 colors (80-89)
|
||||
.colors_per_row = 16, // Display in 16-color rows for proper SNES alignment
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Dungeon-specific palettes: 90 colors per set (5 full rows + 10 colors)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kGlobalSprites = {
|
||||
.group_id = PaletteGroupName::kGlobalSprites,
|
||||
.display_name = "Global Sprites",
|
||||
.category = "Sprites",
|
||||
.base_address = PaletteAddress::kGlobalSpritesLW,
|
||||
.palette_count = 2, // 2 sets (LW and DW), each with 60 colors
|
||||
.colors_per_palette = 60, // 60 colors: 4 rows (0-15, 16-31, 32-47, 48-59) with transparent at 0, 16, 32, 48
|
||||
.colors_per_row = 16, // Display in 16-color rows for proper SNES alignment
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Global sprite palettes: 60 colors per set (4 sprite sub-palettes of 15+transparent each)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kSpritesAux1 = {
|
||||
.group_id = PaletteGroupName::kSpritesAux1,
|
||||
.display_name = "Sprites Aux 1",
|
||||
.category = "Sprites",
|
||||
.base_address = PaletteAddress::kSpritesAux1,
|
||||
.palette_count = PaletteCount::kSpritesAux1,
|
||||
.colors_per_palette = 7, // 7 colors (ROM stores 7, transparent added in memory)
|
||||
.colors_per_row = 8, // Display as 8-color sub-palettes (with transparent)
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Auxiliary sprite palettes 1: 7 colors per palette (transparent added at runtime)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kSpritesAux2 = {
|
||||
.group_id = PaletteGroupName::kSpritesAux2,
|
||||
.display_name = "Sprites Aux 2",
|
||||
.category = "Sprites",
|
||||
.base_address = PaletteAddress::kSpritesAux2,
|
||||
.palette_count = PaletteCount::kSpritesAux2,
|
||||
.colors_per_palette = 7, // 7 colors (ROM stores 7, transparent added in memory)
|
||||
.colors_per_row = 8, // Display as 8-color sub-palettes (with transparent)
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Auxiliary sprite palettes 2: 7 colors per palette (transparent added at runtime)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kSpritesAux3 = {
|
||||
.group_id = PaletteGroupName::kSpritesAux3,
|
||||
.display_name = "Sprites Aux 3",
|
||||
.category = "Sprites",
|
||||
.base_address = PaletteAddress::kSpritesAux3,
|
||||
.palette_count = PaletteCount::kSpritesAux3,
|
||||
.colors_per_palette = 7, // 7 colors (ROM stores 7, transparent added in memory)
|
||||
.colors_per_row = 8, // Display as 8-color sub-palettes (with transparent)
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Auxiliary sprite palettes 3: 7 colors per palette (transparent added at runtime)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kArmor = {
|
||||
.group_id = PaletteGroupName::kArmor,
|
||||
.display_name = "Armor / Link",
|
||||
.category = "Equipment",
|
||||
.base_address = PaletteAddress::kArmor,
|
||||
.palette_count = PaletteCount::kArmor,
|
||||
.colors_per_palette = 15, // 15 colors (ROM stores 15, transparent added in memory for full row)
|
||||
.colors_per_row = 16, // Display as full 16-color rows (with transparent at index 0)
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Link's tunic colors: 15 colors per palette (Green, Blue, Red, Bunny, Electrocuted)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kSwords = {
|
||||
.group_id = PaletteGroupName::kSwords,
|
||||
.display_name = "Swords",
|
||||
.category = "Equipment",
|
||||
.base_address = PaletteAddress::kSwords,
|
||||
.palette_count = PaletteCount::kSwords,
|
||||
.colors_per_palette = 3, // 3 colors (overlay palette, no transparent)
|
||||
.colors_per_row = 4, // Display in compact groups
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Sword blade colors: 3 colors per palette (Fighter, Master, Tempered, Golden)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kShields = {
|
||||
.group_id = PaletteGroupName::kShields,
|
||||
.display_name = "Shields",
|
||||
.category = "Equipment",
|
||||
.base_address = PaletteAddress::kShields,
|
||||
.palette_count = PaletteCount::kShields,
|
||||
.colors_per_palette = 4, // 4 colors (overlay palette, no transparent)
|
||||
.colors_per_row = 4, // Display in compact groups
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Shield colors: 4 colors per palette (Fighter, Fire, Mirror)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kHud = {
|
||||
.group_id = PaletteGroupName::kHud,
|
||||
.display_name = "HUD",
|
||||
.category = "Interface",
|
||||
.base_address = PaletteAddress::kHud,
|
||||
.palette_count = PaletteCount::kHud,
|
||||
.colors_per_palette = 32, // 32 colors: 2 full rows (0-15, 16-31) with transparent at 0, 16
|
||||
.colors_per_row = 16, // Display in 16-color rows
|
||||
.bits_per_pixel = 2, // HUD palettes are 2bpp
|
||||
.description = "HUD/Interface palettes: 32 colors per set (2 full rows)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kOverworldAux = {
|
||||
.group_id = PaletteGroupName::kOverworldAux,
|
||||
.display_name = "Overworld Auxiliary",
|
||||
.category = "Overworld",
|
||||
.base_address = PaletteAddress::kOverworldAux,
|
||||
.palette_count = PaletteCount::kOverworldAux,
|
||||
.colors_per_palette = 21, // 21 colors: 1 full row (0-15) + 5 colors (16-20)
|
||||
.colors_per_row = 16, // Display in 16-color rows
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Overworld auxiliary palettes: 21 colors per set (1 full row + 5 colors)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kGrass = {
|
||||
.group_id = PaletteGroupName::kGrass,
|
||||
.display_name = "Grass",
|
||||
.category = "Overworld",
|
||||
.base_address = PaletteAddress::kGrassLW,
|
||||
.palette_count = PaletteCount::kGrass,
|
||||
.colors_per_palette = 1, // Single color per entry
|
||||
.colors_per_row = 3, // Display all 3 in one row
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Hardcoded grass colors: 3 individual colors (LW, DW, Special)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata k3DObject = {
|
||||
.group_id = PaletteGroupName::k3DObject,
|
||||
.display_name = "3D Objects",
|
||||
.category = "Special",
|
||||
.base_address = PaletteAddress::kTriforce,
|
||||
.palette_count = PaletteCount::k3DObject,
|
||||
.colors_per_palette = 8, // 8 colors per palette (7 + transparent)
|
||||
.colors_per_row = 8, // Display in 8-color groups
|
||||
.bits_per_pixel = 4,
|
||||
.description = "3D object palettes: 8 colors per palette (Triforce, Crystal)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
constexpr PaletteGroupMetadata kOverworldMiniMap = {
|
||||
.group_id = PaletteGroupName::kOverworldMiniMap,
|
||||
.display_name = "Overworld Mini Map",
|
||||
.category = "Interface",
|
||||
.base_address = PaletteAddress::kOverworldMiniMap,
|
||||
.palette_count = PaletteCount::kOverworldMiniMap,
|
||||
.colors_per_palette = 128, // 128 colors: 8 full rows (0-127) with transparent at 0, 16, 32, 48, 64, 80, 96, 112
|
||||
.colors_per_row = 16, // Display in 16-color rows
|
||||
.bits_per_pixel = 4,
|
||||
.description = "Overworld mini-map palettes: 128 colors per set (8 full rows)",
|
||||
.has_animations = false
|
||||
};
|
||||
|
||||
} // namespace PaletteMetadata
|
||||
|
||||
// Helper to get metadata by group name
|
||||
const PaletteGroupMetadata* GetPaletteGroupMetadata(const char* group_id);
|
||||
|
||||
// Get all available palette groups
|
||||
std::vector<const PaletteGroupMetadata*> GetAllPaletteGroups();
|
||||
|
||||
} // namespace zelda3
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_ZELDA3_PALETTE_CONSTANTS_H
|
||||
|
||||
142
src/zelda3/palette_structure.md
Normal file
142
src/zelda3/palette_structure.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# SNES Palette Structure for ALTTP
|
||||
|
||||
## SNES Palette Memory Layout
|
||||
|
||||
The SNES has 256 color palette entries organized as:
|
||||
- **16 palette rows** of **16 colors each**
|
||||
- Each row starts with color index 0, which is **transparent**
|
||||
- Palettes must be aligned to 16-color boundaries
|
||||
|
||||
### Example Layout
|
||||
```
|
||||
Row 0: Colors 0-15 (Color 0 = transparent)
|
||||
Row 1: Colors 16-31 (Color 16 = transparent)
|
||||
Row 2: Colors 32-47 (Color 32 = transparent)
|
||||
...
|
||||
```
|
||||
|
||||
## ALTTP Palette Groups - Corrected Structure
|
||||
|
||||
### Background Palettes (BG)
|
||||
|
||||
#### Overworld Main (35 colors per set)
|
||||
- **Structure**: 2 full rows + 3 colors
|
||||
- Row 0: Colors 0-15 (transparent + 15 colors)
|
||||
- Row 1: Colors 16-31 (transparent + 15 colors)
|
||||
- Row 2: Colors 32-34 (3 colors)
|
||||
- **ROM**: 0xDE6C8
|
||||
- **Sets**: 60 (20 LW, 20 DW, 20 Special)
|
||||
|
||||
#### Overworld Auxiliary (21 colors per set)
|
||||
- **Structure**: 1 full row + 5 colors
|
||||
- Row 0: Colors 0-15 (transparent + 15 colors)
|
||||
- Row 1: Colors 16-20 (5 colors)
|
||||
- **ROM**: 0xDE86C
|
||||
- **Sets**: 20
|
||||
|
||||
#### Overworld Animated (7 colors per set)
|
||||
- **Structure**: Half-row without transparent
|
||||
- Colors 0-6 (7 colors, no transparent marker as these overlay existing)
|
||||
- **ROM**: 0xDE604
|
||||
- **Sets**: 14
|
||||
|
||||
#### Dungeon Main (90 colors per set)
|
||||
- **Structure**: 5 full rows + 10 colors
|
||||
- Row 0: Colors 0-15 (transparent + 15 colors)
|
||||
- Row 1: Colors 16-31 (transparent + 15 colors)
|
||||
- Row 2: Colors 32-47 (transparent + 15 colors)
|
||||
- Row 3: Colors 48-63 (transparent + 15 colors)
|
||||
- Row 4: Colors 64-79 (transparent + 15 colors)
|
||||
- Row 5: Colors 80-89 (10 colors)
|
||||
- **ROM**: 0xDD734
|
||||
- **Sets**: 20 (one per dungeon)
|
||||
|
||||
### Sprite Palettes (OAM)
|
||||
|
||||
Sprite palettes use rows 8-15 (colors 128-255).
|
||||
|
||||
#### Global Sprites (60 colors total)
|
||||
- **Structure**: 4 rows (each with 15 actual colors + transparent)
|
||||
- Row 8: Colors 128-143 (Sprite Palette 0: transparent + 15 colors)
|
||||
- Row 9: Colors 144-159 (Sprite Palette 1: transparent + 15 colors)
|
||||
- Row 10: Colors 160-175 (Sprite Palette 2: transparent + 15 colors)
|
||||
- Row 11: Colors 176-191 (Sprite Palette 3: transparent + 15 colors)
|
||||
- **ROM LW**: 0xDD218
|
||||
- **ROM DW**: 0xDD290
|
||||
- **Total**: 2 sets (LW and DW)
|
||||
|
||||
#### Sprites Auxiliary 1 (7 colors per palette)
|
||||
- **Structure**: 12 palettes, each occupying half a row
|
||||
- Palette 0: 7 colors (indices 1-7 of first half-row)
|
||||
- Palette 1: 7 colors (indices 9-15 of second half-row)
|
||||
- ...and so on
|
||||
- **ROM**: 0xDD39E
|
||||
- **Palettes**: 12
|
||||
|
||||
#### Sprites Auxiliary 2 (7 colors per palette)
|
||||
- **Structure**: 11 palettes, each occupying half a row
|
||||
- **ROM**: 0xDD446
|
||||
- **Palettes**: 11
|
||||
|
||||
#### Sprites Auxiliary 3 (7 colors per palette)
|
||||
- **Structure**: 24 palettes, each occupying half a row
|
||||
- **ROM**: 0xDD4E0
|
||||
- **Palettes**: 24
|
||||
|
||||
### Equipment/Link Palettes
|
||||
|
||||
#### Armor/Link (15 colors per palette)
|
||||
- **Structure**: Full row minus transparent
|
||||
- Each palette: transparent + 15 colors
|
||||
- **ROM**: 0xDD308
|
||||
- **Palettes**: 5 (Green Mail, Blue Mail, Red Mail, Bunny, Electrocuted)
|
||||
|
||||
#### Swords (3 colors per palette)
|
||||
- **Structure**: 3 colors within row (no transparent needed as overlay)
|
||||
- **ROM**: 0xDD630
|
||||
- **Palettes**: 4 (Fighter, Master, Tempered, Golden)
|
||||
|
||||
#### Shields (4 colors per palette)
|
||||
- **Structure**: 4 colors within row (no transparent needed as overlay)
|
||||
- **ROM**: 0xDD648
|
||||
- **Palettes**: 3 (Fighter, Fire, Mirror)
|
||||
|
||||
### HUD Palettes
|
||||
|
||||
#### HUD (32 colors per set)
|
||||
- **Structure**: 2 full rows
|
||||
- Row 0: Colors 0-15 (transparent + 15 colors)
|
||||
- Row 1: Colors 16-31 (transparent + 15 colors)
|
||||
- **ROM**: 0xDD660
|
||||
- **Sets**: 2
|
||||
|
||||
### Special Colors
|
||||
|
||||
#### Grass (3 individual colors)
|
||||
- LW: 0x5FEA9
|
||||
- DW: 0x5FEB3
|
||||
- Special: 0x75640
|
||||
|
||||
#### 3D Objects (8 colors per palette)
|
||||
- **Triforce**: 0x64425
|
||||
- **Crystal**: 0xF4CD3
|
||||
|
||||
#### Overworld Mini Map (128 colors per set)
|
||||
- **Structure**: 8 full rows
|
||||
- **ROM**: 0x55B27
|
||||
- **Sets**: 2
|
||||
|
||||
## Key Principles
|
||||
|
||||
1. **Transparent Color**: Always at indices 0, 16, 32, 48, 64, etc. (multiples of 16)
|
||||
2. **Row Alignment**: Palettes should respect 16-color row boundaries
|
||||
3. **Overlay Palettes**: Some palettes (like animated, swords, shields) overlay existing colors and don't have their own transparent
|
||||
4. **Sub-Palettes**: Multiple small palettes can share a row if they're 8 colors or less
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
When loading palettes, we must:
|
||||
1. Mark color index 0 of each 16-color row as transparent
|
||||
2. For palettes < 16 colors, understand if they're standalone (need transparent) or overlays (don't need transparent)
|
||||
3. Display palettes in UI with proper row alignment for clarity
|
||||
|
||||
Reference in New Issue
Block a user