backend-infra-engineer: Release v0.3.2 snapshot
This commit is contained in:
554
src/zelda3/zelda3_labels.cc
Normal file
554
src/zelda3/zelda3_labels.cc
Normal file
@@ -0,0 +1,554 @@
|
||||
#include "zelda3/zelda3_labels.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "zelda3/common.h"
|
||||
#include "zelda3/dungeon/room.h"
|
||||
#include "zelda3/sprite/overlord.h"
|
||||
#include "zelda3/sprite/sprite.h"
|
||||
|
||||
namespace yaze::zelda3 {
|
||||
|
||||
// Room names - reuse existing kRoomNames array
|
||||
const std::vector<std::string>& Zelda3Labels::GetRoomNames() {
|
||||
static std::vector<std::string> room_names;
|
||||
if (room_names.empty()) {
|
||||
for (const auto& name : kRoomNames) {
|
||||
room_names.emplace_back(name);
|
||||
}
|
||||
}
|
||||
return room_names;
|
||||
}
|
||||
|
||||
// Entrance names - reuse existing kEntranceNames array
|
||||
const std::vector<std::string>& Zelda3Labels::GetEntranceNames() {
|
||||
static std::vector<std::string> entrance_names;
|
||||
if (entrance_names.empty()) {
|
||||
for (const auto& name : kEntranceNames) {
|
||||
entrance_names.emplace_back(name);
|
||||
}
|
||||
}
|
||||
return entrance_names;
|
||||
}
|
||||
|
||||
// Sprite names - reuse existing kSpriteDefaultNames array
|
||||
const std::vector<std::string>& Zelda3Labels::GetSpriteNames() {
|
||||
static std::vector<std::string> sprite_names;
|
||||
if (sprite_names.empty()) {
|
||||
for (const auto& name : kSpriteDefaultNames) {
|
||||
sprite_names.push_back(name);
|
||||
}
|
||||
}
|
||||
return sprite_names;
|
||||
}
|
||||
|
||||
// Overlord names - reuse existing kOverlordNames array
|
||||
const std::vector<std::string>& Zelda3Labels::GetOverlordNames() {
|
||||
static std::vector<std::string> overlord_names;
|
||||
if (overlord_names.empty()) {
|
||||
for (const auto& name : kOverlordNames) {
|
||||
overlord_names.push_back(name);
|
||||
}
|
||||
}
|
||||
return overlord_names;
|
||||
}
|
||||
|
||||
// Overworld map names (64 Light World + 64 Dark World + 32 Special Areas)
|
||||
const std::vector<std::string>& Zelda3Labels::GetOverworldMapNames() {
|
||||
static const std::vector<std::string> map_names = {
|
||||
// Light World (0x00-0x3F)
|
||||
"Lost Woods", "Master Sword Pedestal", "Castle Courtyard", "Link's House",
|
||||
"Eastern Palace", "Desert Palace", "Hyrule Castle", "Witch's Hut",
|
||||
"Kakariko Village", "Death Mountain", "Tower of Hera", "Spectacle Rock",
|
||||
"Graveyard", "Sanctuary", "Lake Hylia", "Desert of Mystery",
|
||||
"Eastern Ruins", "Zora's Domain", "Catfish", "Dam", "Potion Shop",
|
||||
"Kakariko Well", "Blacksmith", "Sick Kid", "Library", "Mushroom",
|
||||
"Magic Bat", "Fairy Fountain", "Fortune Teller", "Lake Shop", "Bomb Shop",
|
||||
"Cave 45", "Checkerboard Cave", "Mini Moldorm Cave", "Ice Rod Cave",
|
||||
"Bonk Rocks", "Bottle Merchant", "Sahasrahla's Hut", "Chicken House",
|
||||
"Aginah's Cave", "Dam Exterior", "Mimic Cave Exterior", "Waterfall Fairy",
|
||||
"Pyramid", "Fat Fairy", "Spike Cave", "Hookshot Cave", "Graveyard Ledge",
|
||||
"Dark Lumberjacks", "Bumper Cave", "Skull Woods 1", "Skull Woods 2",
|
||||
"Skull Woods 3", "Skull Woods 4", "Skull Woods 5", "Skull Woods 6",
|
||||
"Skull Woods 7", "Skull Woods 8", "Ice Palace Exterior",
|
||||
"Misery Mire Exterior", "Palace of Darkness Exterior",
|
||||
"Swamp Palace Exterior", "Turtle Rock Exterior", "Thieves' Town Exterior",
|
||||
|
||||
// Dark World (0x40-0x7F)
|
||||
"Dark Woods", "Dark Chapel", "Dark Castle", "Dark Shields", "Dark Palace",
|
||||
"Dark Desert", "Dark Castle Gate", "Dark Witch", "Dark Village",
|
||||
"Dark Mountain", "Dark Tower", "Dark Rocks", "Dark Graveyard",
|
||||
"Dark Sanctuary", "Dark Lake", "Dark Desert South", "Dark Eastern",
|
||||
"Dark Zora", "Dark Catfish", "Dark Dam", "Dark Shop", "Dark Well",
|
||||
"Dark Blacksmith", "Dark Sick Kid", "Dark Library", "Dark Mushroom",
|
||||
"Dark Bat", "Dark Fountain", "Dark Fortune", "Dark Lake Shop",
|
||||
"Dark Bomb Shop", "Dark Cave 45", "Dark Checker", "Dark Mini Moldorm",
|
||||
"Dark Ice Rod", "Dark Bonk", "Dark Bottle", "Dark Sahasrahla",
|
||||
"Dark Chicken", "Dark Aginah", "Dark Dam Exit", "Dark Mimic Exit",
|
||||
"Dark Waterfall", "Pyramid Top", "Dark Fat Fairy", "Dark Spike Cave",
|
||||
"Dark Hookshot", "Dark Graveyard Ledge", "Lumberjack House",
|
||||
"Dark Bumper", "Skull Woods A", "Skull Woods B", "Skull Woods C",
|
||||
"Skull Woods D", "Skull Woods E", "Skull Woods F", "Skull Woods G",
|
||||
"Skull Woods H", "Ice Palace Entry", "Misery Mire Entry",
|
||||
"Palace of Darkness Entry", "Swamp Palace Entry", "Turtle Rock Entry",
|
||||
"Thieves' Town Entry",
|
||||
|
||||
// Special Areas (0x80-0x9F)
|
||||
"Special Area 1", "Special Area 2", "Special Area 3", "Special Area 4",
|
||||
"Special Area 5", "Special Area 6", "Special Area 7", "Special Area 8",
|
||||
"Special Area 9", "Special Area 10", "Special Area 11", "Special Area 12",
|
||||
"Special Area 13", "Special Area 14", "Special Area 15",
|
||||
"Special Area 16", "Special Area 17", "Special Area 18",
|
||||
"Special Area 19", "Special Area 20", "Special Area 21",
|
||||
"Special Area 22", "Special Area 23", "Special Area 24",
|
||||
"Special Area 25", "Special Area 26", "Special Area 27",
|
||||
"Special Area 28", "Special Area 29", "Special Area 30",
|
||||
"Special Area 31", "Special Area 32"};
|
||||
return map_names;
|
||||
}
|
||||
|
||||
// Item names (complete item list)
|
||||
const std::vector<std::string>& Zelda3Labels::GetItemNames() {
|
||||
static const std::vector<std::string> item_names = {
|
||||
"None",
|
||||
"Fighter Sword",
|
||||
"Master Sword",
|
||||
"Tempered Sword",
|
||||
"Golden Sword",
|
||||
"Fighter Shield",
|
||||
"Fire Shield",
|
||||
"Mirror Shield",
|
||||
"Fire Rod",
|
||||
"Ice Rod",
|
||||
"Hammer",
|
||||
"Hookshot",
|
||||
"Bow",
|
||||
"Boomerang",
|
||||
"Powder",
|
||||
"Bee Badge",
|
||||
"Bombos Medallion",
|
||||
"Ether Medallion",
|
||||
"Quake Medallion",
|
||||
"Lamp",
|
||||
"Shovel",
|
||||
"Flute",
|
||||
"Somaria Cane",
|
||||
"Bottle",
|
||||
"Heart Piece",
|
||||
"Byrna Cane",
|
||||
"Cape",
|
||||
"Mirror",
|
||||
"Power Glove",
|
||||
"Titan Mitt",
|
||||
"Book of Mudora",
|
||||
"Zora Flippers",
|
||||
"Moon Pearl",
|
||||
"Crystal",
|
||||
"Bug Net",
|
||||
"Blue Mail",
|
||||
"Red Mail",
|
||||
"Key",
|
||||
"Compass",
|
||||
"Heart Container",
|
||||
"Bomb",
|
||||
"3 Bombs",
|
||||
"Mushroom",
|
||||
"Red Boomerang",
|
||||
"Red Potion",
|
||||
"Green Potion",
|
||||
"Blue Potion",
|
||||
"Red Potion (Refill)",
|
||||
"Green Potion (Refill)",
|
||||
"Blue Potion (Refill)",
|
||||
"10 Bombs",
|
||||
"Big Key",
|
||||
"Map",
|
||||
"1 Rupee",
|
||||
"5 Rupees",
|
||||
"20 Rupees",
|
||||
"Pendant of Courage",
|
||||
"Pendant of Wisdom",
|
||||
"Pendant of Power",
|
||||
"Bow and Arrows",
|
||||
"Silver Arrows Upgrade",
|
||||
"Bee",
|
||||
"Fairy",
|
||||
"Heart Container (Boss)",
|
||||
"Heart",
|
||||
"1 Arrow",
|
||||
"10 Arrows",
|
||||
"Magic",
|
||||
"Small Magic",
|
||||
"300 Rupees",
|
||||
"20 Rupees (Green)",
|
||||
"100 Rupees",
|
||||
"50 Rupees",
|
||||
"Heart Container (Sanctuary)",
|
||||
"Arrow Refill (5)",
|
||||
"Arrow Refill (10)",
|
||||
"Bomb Refill (1)",
|
||||
"Bomb Refill (4)",
|
||||
"Bomb Refill (8)",
|
||||
"Blue Shield (Refill)",
|
||||
"Magic Upgrade (1/2)",
|
||||
"Magic Upgrade (1/4)",
|
||||
"Programmable Item 1",
|
||||
"Programmable Item 2",
|
||||
"Programmable Item 3",
|
||||
"Silvers",
|
||||
"Rupoor",
|
||||
"Null Item",
|
||||
"Red Clock",
|
||||
"Blue Clock",
|
||||
"Green Clock",
|
||||
"Progressive Sword",
|
||||
"Progressive Shield",
|
||||
"Progressive Armor",
|
||||
"Progressive Lifting Glove",
|
||||
"RNG Item (Single)",
|
||||
"RNG Item (Multi)",
|
||||
"Progressive Bow",
|
||||
"Progressive Bow (Alt)",
|
||||
"Aga Pendant",
|
||||
"Pendant (Green)",
|
||||
"Blue Pendant",
|
||||
"Good Bee",
|
||||
"Tossed Key"};
|
||||
return item_names;
|
||||
}
|
||||
|
||||
// Music track names
|
||||
const std::vector<std::string>& Zelda3Labels::GetMusicTrackNames() {
|
||||
static const std::vector<std::string> music_names = {
|
||||
"Nothing",
|
||||
"Light World",
|
||||
"Beginning",
|
||||
"Rabbit",
|
||||
"Forest",
|
||||
"Intro",
|
||||
"Town",
|
||||
"Warp",
|
||||
"Dark World",
|
||||
"Master Sword",
|
||||
"File Select",
|
||||
"Soldier",
|
||||
"Boss",
|
||||
"Dark World Death Mountain",
|
||||
"Minigame",
|
||||
"Skull Woods",
|
||||
"Indoor",
|
||||
"Cave 1",
|
||||
"Zelda's Rescue",
|
||||
"Crystal",
|
||||
"Shop",
|
||||
"Cave 2",
|
||||
"Game Over",
|
||||
"Boss Victory",
|
||||
"Sanctuary",
|
||||
"Boss Victory (Short)",
|
||||
"Dark World Woods",
|
||||
"Pendant",
|
||||
"Ganon's Message",
|
||||
"Hyrule Castle",
|
||||
"Light World Death Mountain",
|
||||
"Eastern Palace",
|
||||
"Desert Palace",
|
||||
"Agahnim's Theme",
|
||||
"Damp Dungeon",
|
||||
"Ganon Reveals",
|
||||
"Confrontation",
|
||||
"Ganon's Theme",
|
||||
"Triforce",
|
||||
"Credits",
|
||||
"Unused",
|
||||
"Unused",
|
||||
"Unused",
|
||||
"Unused",
|
||||
"Unused",
|
||||
"Unused",
|
||||
"Unused",
|
||||
"Unused"};
|
||||
return music_names;
|
||||
}
|
||||
|
||||
// Graphics sheet names
|
||||
const std::vector<std::string>& Zelda3Labels::GetGraphicsSheetNames() {
|
||||
static const std::vector<std::string> gfx_names = {"Sprite Sheet 0",
|
||||
"Sprite Sheet 1",
|
||||
"Sprite Sheet 2",
|
||||
"Sprite Sheet 3",
|
||||
"Sprite Sheet 4",
|
||||
"Sprite Sheet 5",
|
||||
"Sprite Sheet 6",
|
||||
"Sprite Sheet 7",
|
||||
"Sprite Sheet 8",
|
||||
"Sprite Sheet 9",
|
||||
"Sprite Sheet A",
|
||||
"Sprite Sheet B",
|
||||
"Sprite Sheet C",
|
||||
"Sprite Sheet D",
|
||||
"Sprite Sheet E",
|
||||
"Sprite Sheet F",
|
||||
"Link's Sprites",
|
||||
"Sword Sprites",
|
||||
"Shield Sprites",
|
||||
"Common Sprites",
|
||||
"Boss Sprites",
|
||||
"NPC Sprites",
|
||||
"Enemy Sprites 1",
|
||||
"Enemy Sprites 2",
|
||||
"Item Sprites",
|
||||
"Dungeon Objects",
|
||||
"Overworld Objects",
|
||||
"Interface",
|
||||
"Font",
|
||||
"Credits",
|
||||
"Unused",
|
||||
"Unused"};
|
||||
return gfx_names;
|
||||
}
|
||||
|
||||
// Room object names - these are large, so we'll delegate to a helper
|
||||
namespace {
|
||||
std::vector<std::string> ConvertArrayToVector(const char** array, size_t size) {
|
||||
std::vector<std::string> result;
|
||||
result.reserve(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
result.emplace_back(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
const std::vector<std::string>& Zelda3Labels::GetType1RoomObjectNames() {
|
||||
static const std::vector<std::string> names = []() {
|
||||
std::vector<std::string> result;
|
||||
// Note: Type1RoomObjectNames is constexpr, we need to count its size
|
||||
// For now, we'll add known objects. In full implementation,
|
||||
// we'd import from room_object.h
|
||||
result = {
|
||||
"Ceiling ↔",
|
||||
"Wall (top, north) ↔",
|
||||
"Wall (top, south) ↔",
|
||||
"Wall (bottom, north) ↔",
|
||||
"Wall (bottom, south) ↔",
|
||||
"Wall columns (north) ↔",
|
||||
"Wall columns (south) ↔",
|
||||
"Deep wall (north) ↔",
|
||||
"Deep wall (south) ↔",
|
||||
"Diagonal wall A ◤ (top) ↔",
|
||||
"Diagonal wall A ◣ (top) ↔",
|
||||
"Diagonal wall A ◥ (top) ↔",
|
||||
"Diagonal wall A ◢ (top) ↔",
|
||||
// ... Add all Type1 objects here
|
||||
};
|
||||
return result;
|
||||
}();
|
||||
return names;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Zelda3Labels::GetType2RoomObjectNames() {
|
||||
static const std::vector<std::string> names = []() {
|
||||
std::vector<std::string> result;
|
||||
// Add Type2 room objects
|
||||
result = {"Type2 Object 1", "Type2 Object 2" /* ... */};
|
||||
return result;
|
||||
}();
|
||||
return names;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Zelda3Labels::GetType3RoomObjectNames() {
|
||||
static const std::vector<std::string> names = []() {
|
||||
std::vector<std::string> result;
|
||||
// Add Type3 room objects
|
||||
result = {"Type3 Object 1", "Type3 Object 2" /* ... */};
|
||||
return result;
|
||||
}();
|
||||
return names;
|
||||
}
|
||||
|
||||
// Room effect names - reuse existing RoomEffect array
|
||||
const std::vector<std::string>& Zelda3Labels::GetRoomEffectNames() {
|
||||
static std::vector<std::string> effect_names;
|
||||
if (effect_names.empty()) {
|
||||
for (const auto& name : RoomEffect) {
|
||||
effect_names.push_back(name);
|
||||
}
|
||||
}
|
||||
return effect_names;
|
||||
}
|
||||
|
||||
// Room tag names
|
||||
const std::vector<std::string>& Zelda3Labels::GetRoomTagNames() {
|
||||
static const std::vector<std::string> tag_names = {
|
||||
"No Tag", "NW", "NE", "SW", "SE", "West", "East",
|
||||
"North", "South", "Entrance", "Treasure", "Boss", "Dark"};
|
||||
return tag_names;
|
||||
}
|
||||
|
||||
// Tile type names
|
||||
const std::vector<std::string>& Zelda3Labels::GetTileTypeNames() {
|
||||
static const std::vector<std::string> tile_names = {
|
||||
"Nothing (standard floor)",
|
||||
"Nothing (unused?)",
|
||||
"Collision",
|
||||
"Collision (unknown types)",
|
||||
"Collision",
|
||||
"Collision (unused?)",
|
||||
"Collision",
|
||||
"Collision",
|
||||
"Deep water",
|
||||
"Shallow water",
|
||||
"Unknown (near water/pit edges)",
|
||||
"Collision (water/pit edges)",
|
||||
"Overlay mask",
|
||||
"Spike floor",
|
||||
"GT ice",
|
||||
"Ice palace ice",
|
||||
"Slope ◤",
|
||||
"Slope ◥",
|
||||
"Slope ◣",
|
||||
"Slope ◢",
|
||||
"Nothing (unused?)",
|
||||
"Nothing (unused?)",
|
||||
"Nothing (unused?)",
|
||||
"Slope ◤",
|
||||
"Slope ◥",
|
||||
"Slope ◣",
|
||||
"Slope ◢",
|
||||
"Layer swap",
|
||||
"Pit",
|
||||
"Manual stairs",
|
||||
"Pot switch",
|
||||
"Pressure switch",
|
||||
"Blocks switch (chest, PoD, walls)",
|
||||
"Layer toggle",
|
||||
"Layer 2 overlay",
|
||||
"North single-layer auto stairs",
|
||||
"North layer swap auto stairs",
|
||||
"South single-layer auto stairs",
|
||||
"South layer swap auto stairs",
|
||||
"North/south layer swap auto stairs",
|
||||
"North/south single-layer auto stairs",
|
||||
"West single-layer auto stairs",
|
||||
"West layer swap auto stairs",
|
||||
"East single-layer auto stairs",
|
||||
"East layer swap auto stairs",
|
||||
"East/west layer swap auto stairs",
|
||||
"East/west single-layer auto stairs",
|
||||
"Nothing (stairs edge)",
|
||||
"Straight inter-room stairs south/up",
|
||||
"Straight inter-room stairs north/down",
|
||||
"Straight inter-room stairs south/down 2",
|
||||
"Straight inter-room stairs north/up 2",
|
||||
"Star tile (inactive on GBA)",
|
||||
"Collision (near stairs)",
|
||||
"Warp tile",
|
||||
"Square corners ⌜⌝⌞⌟",
|
||||
"Thick corner ⌜",
|
||||
"Thick corner ⌝",
|
||||
"Thick corner ⌞",
|
||||
"Thick corner ⌟",
|
||||
"Roof/grass tiles?",
|
||||
"Spike floor"};
|
||||
return tile_names;
|
||||
}
|
||||
|
||||
// Convert all labels to structured map for project embedding
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, std::string>>
|
||||
Zelda3Labels::ToResourceLabels() {
|
||||
std::unordered_map<std::string, std::unordered_map<std::string, std::string>>
|
||||
labels;
|
||||
|
||||
// Rooms
|
||||
const auto& rooms = GetRoomNames();
|
||||
for (size_t i = 0; i < rooms.size(); ++i) {
|
||||
labels["room"][std::to_string(i)] = rooms[i];
|
||||
}
|
||||
|
||||
// Entrances
|
||||
const auto& entrances = GetEntranceNames();
|
||||
for (size_t i = 0; i < entrances.size(); ++i) {
|
||||
labels["entrance"][std::to_string(i)] = entrances[i];
|
||||
}
|
||||
|
||||
// Sprites
|
||||
const auto& sprites = GetSpriteNames();
|
||||
for (size_t i = 0; i < sprites.size(); ++i) {
|
||||
labels["sprite"][std::to_string(i)] = sprites[i];
|
||||
}
|
||||
|
||||
// Overlords
|
||||
const auto& overlords = GetOverlordNames();
|
||||
for (size_t i = 0; i < overlords.size(); ++i) {
|
||||
labels["overlord"][std::to_string(i)] = overlords[i];
|
||||
}
|
||||
|
||||
// Overworld maps
|
||||
const auto& maps = GetOverworldMapNames();
|
||||
for (size_t i = 0; i < maps.size(); ++i) {
|
||||
labels["overworld_map"][std::to_string(i)] = maps[i];
|
||||
}
|
||||
|
||||
// Items
|
||||
const auto& items = GetItemNames();
|
||||
for (size_t i = 0; i < items.size(); ++i) {
|
||||
labels["item"][std::to_string(i)] = items[i];
|
||||
}
|
||||
|
||||
// Music tracks
|
||||
const auto& music = GetMusicTrackNames();
|
||||
for (size_t i = 0; i < music.size(); ++i) {
|
||||
labels["music"][std::to_string(i)] = music[i];
|
||||
}
|
||||
|
||||
// Graphics sheets
|
||||
const auto& gfx = GetGraphicsSheetNames();
|
||||
for (size_t i = 0; i < gfx.size(); ++i) {
|
||||
labels["graphics"][std::to_string(i)] = gfx[i];
|
||||
}
|
||||
|
||||
// Room effects
|
||||
const auto& effects = GetRoomEffectNames();
|
||||
for (size_t i = 0; i < effects.size(); ++i) {
|
||||
labels["room_effect"][std::to_string(i)] = effects[i];
|
||||
}
|
||||
|
||||
// Room tags
|
||||
const auto& tags = GetRoomTagNames();
|
||||
for (size_t i = 0; i < tags.size(); ++i) {
|
||||
labels["room_tag"][std::to_string(i)] = tags[i];
|
||||
}
|
||||
|
||||
// Tile types
|
||||
const auto& tiles = GetTileTypeNames();
|
||||
for (size_t i = 0; i < tiles.size(); ++i) {
|
||||
labels["tile_type"][std::to_string(i)] = tiles[i];
|
||||
}
|
||||
|
||||
return labels;
|
||||
}
|
||||
|
||||
// Get a label by resource type and ID
|
||||
std::string Zelda3Labels::GetLabel(const std::string& resource_type, int id,
|
||||
const std::string& default_value) {
|
||||
static auto labels = ToResourceLabels();
|
||||
|
||||
auto type_it = labels.find(resource_type);
|
||||
if (type_it == labels.end()) {
|
||||
return default_value.empty() ? resource_type + "_" + std::to_string(id)
|
||||
: default_value;
|
||||
}
|
||||
|
||||
auto label_it = type_it->second.find(std::to_string(id));
|
||||
if (label_it == type_it->second.end()) {
|
||||
return default_value.empty() ? resource_type + "_" + std::to_string(id)
|
||||
: default_value;
|
||||
}
|
||||
|
||||
return label_it->second;
|
||||
}
|
||||
|
||||
} // namespace yaze::zelda3
|
||||
Reference in New Issue
Block a user