feat: Add INI and JSON format support for project files and update resource label handling
This commit is contained in:
65
assets/zelda3.yaze
Normal file
65
assets/zelda3.yaze
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
# Default Zelda3 Project File
|
||||||
|
# All resource names are embedded and always available to AI agents
|
||||||
|
# This project uses embedded labels - no external labels file required
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = The Legend of Zelda: A Link to the Past
|
||||||
|
description = Default Zelda3 project with all embedded resource labels
|
||||||
|
author = Nintendo
|
||||||
|
version = 1.0.0
|
||||||
|
created_date = 2025-10-04
|
||||||
|
last_modified = 2025-10-04
|
||||||
|
yaze_version = 0.1.0
|
||||||
|
tags = zelda3, reference, default
|
||||||
|
|
||||||
|
[files]
|
||||||
|
rom_filename = zelda3.sfc
|
||||||
|
code_folder =
|
||||||
|
assets_folder = assets
|
||||||
|
patches_folder = patches
|
||||||
|
labels_filename =
|
||||||
|
symbols_filename =
|
||||||
|
output_folder = build
|
||||||
|
rom_backup_folder = backups
|
||||||
|
|
||||||
|
[feature_flags]
|
||||||
|
log_instructions = false
|
||||||
|
save_dungeon_maps = false
|
||||||
|
save_graphics_sheet = false
|
||||||
|
load_custom_overworld = false
|
||||||
|
apply_zs_custom_overworld_asm = false
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
font_global_scale = 1.0
|
||||||
|
dark_mode = true
|
||||||
|
ui_theme = default
|
||||||
|
autosave_enabled = true
|
||||||
|
autosave_interval_secs = 300
|
||||||
|
backup_on_save = true
|
||||||
|
show_grid = true
|
||||||
|
show_collision = false
|
||||||
|
last_layout_preset = default
|
||||||
|
|
||||||
|
[build]
|
||||||
|
build_script =
|
||||||
|
output_folder = build
|
||||||
|
git_repository =
|
||||||
|
track_changes = true
|
||||||
|
build_configurations = debug, release
|
||||||
|
|
||||||
|
# Embedded Labels Information
|
||||||
|
# This project includes the following embedded resource names:
|
||||||
|
# - 296 room names (dungeons, bosses, treasure rooms)
|
||||||
|
# - 133 entrance names (dungeons, caves, houses, shops)
|
||||||
|
# - 256 sprite names (enemies, NPCs, bosses, items)
|
||||||
|
# - 26 overlord names (factories, traps, special objects)
|
||||||
|
# - 160 overworld map names (Light World, Dark World, Special Areas)
|
||||||
|
# - 100 item names (swords, shields, medallions, bottles)
|
||||||
|
# - 48 music track names
|
||||||
|
# - 32 graphics sheet names
|
||||||
|
# - 8 room effect names
|
||||||
|
# - 13 room tag names
|
||||||
|
# - 60 tile type names (collision, slopes, water, ice, stairs)
|
||||||
|
#
|
||||||
|
# Use InitializeEmbeddedLabels() to load all default labels
|
||||||
|
# Custom labels can be added in [labels_<type>] sections
|
||||||
@@ -15,6 +15,11 @@
|
|||||||
#include "imgui/imgui.h"
|
#include "imgui/imgui.h"
|
||||||
#include "yaze_config.h"
|
#include "yaze_config.h"
|
||||||
|
|
||||||
|
#ifdef YAZE_ENABLE_JSON_PROJECT_FORMAT
|
||||||
|
#include "nlohmann/json.hpp"
|
||||||
|
using json = nlohmann::json;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace core {
|
namespace core {
|
||||||
|
|
||||||
@@ -111,7 +116,27 @@ absl::Status YazeProject::Open(const std::string& project_path) {
|
|||||||
// Determine format and load accordingly
|
// Determine format and load accordingly
|
||||||
if (project_path.ends_with(".yaze")) {
|
if (project_path.ends_with(".yaze")) {
|
||||||
format = ProjectFormat::kYazeNative;
|
format = ProjectFormat::kYazeNative;
|
||||||
return LoadFromYazeFormat(project_path);
|
|
||||||
|
// Try to detect if it's JSON format by peeking at first character
|
||||||
|
std::ifstream file(project_path);
|
||||||
|
if (file.is_open()) {
|
||||||
|
char first_char;
|
||||||
|
file.get(first_char);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
#ifdef YAZE_ENABLE_JSON_PROJECT_FORMAT
|
||||||
|
if (first_char == '{') {
|
||||||
|
std::cout << "📄 Detected JSON format project file\n";
|
||||||
|
return LoadFromJsonFormat(project_path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Default to INI format
|
||||||
|
return LoadFromYazeFormat(project_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::InvalidArgumentError(
|
||||||
|
absl::StrFormat("Cannot open project file: %s", project_path));
|
||||||
} else if (project_path.ends_with(".zsproj")) {
|
} else if (project_path.ends_with(".zsproj")) {
|
||||||
format = ProjectFormat::kZScreamCompat;
|
format = ProjectFormat::kZScreamCompat;
|
||||||
return ImportFromZScreamFormat(project_path);
|
return ImportFromZScreamFormat(project_path);
|
||||||
@@ -868,5 +893,131 @@ std::string YazeProject::GetLabel(const std::string& resource_type, int id,
|
|||||||
: default_value;
|
: default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// JSON Format Support (Optional)
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#ifdef YAZE_ENABLE_JSON_PROJECT_FORMAT
|
||||||
|
|
||||||
|
absl::Status YazeProject::LoadFromJsonFormat(const std::string& project_path) {
|
||||||
|
std::ifstream file(project_path);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
return absl::InvalidArgumentError(
|
||||||
|
absl::StrFormat("Cannot open JSON project file: %s", project_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
json j;
|
||||||
|
file >> j;
|
||||||
|
|
||||||
|
// Parse project metadata
|
||||||
|
if (j.contains("yaze_project")) {
|
||||||
|
auto& proj = j["yaze_project"];
|
||||||
|
|
||||||
|
if (proj.contains("name")) name = proj["name"].get<std::string>();
|
||||||
|
if (proj.contains("description")) metadata.description = proj["description"].get<std::string>();
|
||||||
|
if (proj.contains("author")) metadata.author = proj["author"].get<std::string>();
|
||||||
|
if (proj.contains("version")) metadata.version = proj["version"].get<std::string>();
|
||||||
|
if (proj.contains("created")) metadata.created_date = proj["created"].get<std::string>();
|
||||||
|
if (proj.contains("modified")) metadata.last_modified = proj["modified"].get<std::string>();
|
||||||
|
|
||||||
|
// Files
|
||||||
|
if (proj.contains("rom_filename")) rom_filename = proj["rom_filename"].get<std::string>();
|
||||||
|
if (proj.contains("code_folder")) code_folder = proj["code_folder"].get<std::string>();
|
||||||
|
if (proj.contains("assets_folder")) assets_folder = proj["assets_folder"].get<std::string>();
|
||||||
|
if (proj.contains("patches_folder")) patches_folder = proj["patches_folder"].get<std::string>();
|
||||||
|
if (proj.contains("labels_filename")) labels_filename = proj["labels_filename"].get<std::string>();
|
||||||
|
if (proj.contains("symbols_filename")) symbols_filename = proj["symbols_filename"].get<std::string>();
|
||||||
|
|
||||||
|
// Embedded labels flag
|
||||||
|
if (proj.contains("use_embedded_labels")) {
|
||||||
|
use_embedded_labels = proj["use_embedded_labels"].get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feature flags
|
||||||
|
if (proj.contains("feature_flags")) {
|
||||||
|
auto& flags = proj["feature_flags"];
|
||||||
|
if (flags.contains("kLogInstructions"))
|
||||||
|
feature_flags.kLogInstructions = flags["kLogInstructions"].get<bool>();
|
||||||
|
if (flags.contains("kSaveDungeonMaps"))
|
||||||
|
feature_flags.kSaveDungeonMaps = flags["kSaveDungeonMaps"].get<bool>();
|
||||||
|
if (flags.contains("kSaveGraphicsSheet"))
|
||||||
|
feature_flags.kSaveGraphicsSheet = flags["kSaveGraphicsSheet"].get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Workspace settings
|
||||||
|
if (proj.contains("workspace_settings")) {
|
||||||
|
auto& ws = proj["workspace_settings"];
|
||||||
|
if (ws.contains("auto_save_enabled"))
|
||||||
|
workspace_settings.autosave_enabled = ws["auto_save_enabled"].get<bool>();
|
||||||
|
if (ws.contains("auto_save_interval"))
|
||||||
|
workspace_settings.autosave_interval_secs = ws["auto_save_interval"].get<float>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build settings
|
||||||
|
if (proj.contains("build_script")) build_script = proj["build_script"].get<std::string>();
|
||||||
|
if (proj.contains("output_folder")) output_folder = proj["output_folder"].get<std::string>();
|
||||||
|
if (proj.contains("git_repository")) git_repository = proj["git_repository"].get<std::string>();
|
||||||
|
if (proj.contains("track_changes")) track_changes = proj["track_changes"].get<bool>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
} catch (const json::exception& e) {
|
||||||
|
return absl::InvalidArgumentError(
|
||||||
|
absl::StrFormat("JSON parse error: %s", e.what()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status YazeProject::SaveToJsonFormat() {
|
||||||
|
json j;
|
||||||
|
auto& proj = j["yaze_project"];
|
||||||
|
|
||||||
|
// Metadata
|
||||||
|
proj["version"] = metadata.version;
|
||||||
|
proj["name"] = name;
|
||||||
|
proj["author"] = metadata.author;
|
||||||
|
proj["description"] = metadata.description;
|
||||||
|
proj["created"] = metadata.created_date;
|
||||||
|
proj["modified"] = metadata.last_modified;
|
||||||
|
|
||||||
|
// Files
|
||||||
|
proj["rom_filename"] = rom_filename;
|
||||||
|
proj["code_folder"] = code_folder;
|
||||||
|
proj["assets_folder"] = assets_folder;
|
||||||
|
proj["patches_folder"] = patches_folder;
|
||||||
|
proj["labels_filename"] = labels_filename;
|
||||||
|
proj["symbols_filename"] = symbols_filename;
|
||||||
|
proj["output_folder"] = output_folder;
|
||||||
|
|
||||||
|
// Embedded labels
|
||||||
|
proj["use_embedded_labels"] = use_embedded_labels;
|
||||||
|
|
||||||
|
// Feature flags
|
||||||
|
proj["feature_flags"]["kLogInstructions"] = feature_flags.kLogInstructions;
|
||||||
|
proj["feature_flags"]["kSaveDungeonMaps"] = feature_flags.kSaveDungeonMaps;
|
||||||
|
proj["feature_flags"]["kSaveGraphicsSheet"] = feature_flags.kSaveGraphicsSheet;
|
||||||
|
|
||||||
|
// Workspace settings
|
||||||
|
proj["workspace_settings"]["auto_save_enabled"] = workspace_settings.autosave_enabled;
|
||||||
|
proj["workspace_settings"]["auto_save_interval"] = workspace_settings.autosave_interval_secs;
|
||||||
|
|
||||||
|
// Build settings
|
||||||
|
proj["build_script"] = build_script;
|
||||||
|
proj["git_repository"] = git_repository;
|
||||||
|
proj["track_changes"] = track_changes;
|
||||||
|
|
||||||
|
// Write to file
|
||||||
|
std::ofstream file(filepath);
|
||||||
|
if (!file.is_open()) {
|
||||||
|
return absl::InvalidArgumentError(
|
||||||
|
absl::StrFormat("Cannot write JSON project file: %s", filepath));
|
||||||
|
}
|
||||||
|
|
||||||
|
file << j.dump(2); // Pretty print with 2-space indent
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // YAZE_ENABLE_JSON_PROJECT_FORMAT
|
||||||
|
|
||||||
} // namespace core
|
} // namespace core
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -154,6 +154,11 @@ private:
|
|||||||
absl::Status SaveToYazeFormat();
|
absl::Status SaveToYazeFormat();
|
||||||
absl::Status ImportFromZScreamFormat(const std::string& project_path);
|
absl::Status ImportFromZScreamFormat(const std::string& project_path);
|
||||||
|
|
||||||
|
#ifdef YAZE_ENABLE_JSON_PROJECT_FORMAT
|
||||||
|
absl::Status LoadFromJsonFormat(const std::string& project_path);
|
||||||
|
absl::Status SaveToJsonFormat();
|
||||||
|
#endif
|
||||||
|
|
||||||
void InitializeDefaults();
|
void InitializeDefaults();
|
||||||
std::string GenerateProjectId() const;
|
std::string GenerateProjectId() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -284,20 +284,35 @@ void Room::CopyRoomGraphicsToBuffer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Room::RenderRoomGraphics() {
|
void Room::RenderRoomGraphics() {
|
||||||
|
std::printf("\n=== RenderRoomGraphics Room %d ===\n", room_id_);
|
||||||
|
|
||||||
CopyRoomGraphicsToBuffer();
|
CopyRoomGraphicsToBuffer();
|
||||||
|
std::printf("1. Graphics buffer copied\n");
|
||||||
|
|
||||||
gfx::Arena::Get().bg1().DrawFloor(rom()->vector(), tile_address,
|
gfx::Arena::Get().bg1().DrawFloor(rom()->vector(), tile_address,
|
||||||
tile_address_floor, floor1_graphics_);
|
tile_address_floor, floor1_graphics_);
|
||||||
gfx::Arena::Get().bg2().DrawFloor(rom()->vector(), tile_address,
|
gfx::Arena::Get().bg2().DrawFloor(rom()->vector(), tile_address,
|
||||||
tile_address_floor, floor2_graphics_);
|
tile_address_floor, floor2_graphics_);
|
||||||
|
std::printf("2. Floor pattern drawn\n");
|
||||||
|
|
||||||
|
// Render layout and object tiles to background buffers
|
||||||
|
RenderObjectsToBackground();
|
||||||
|
std::printf("3. Objects rendered to buffer\n");
|
||||||
|
|
||||||
gfx::Arena::Get().bg1().DrawBackground(std::span<uint8_t>(current_gfx16_));
|
gfx::Arena::Get().bg1().DrawBackground(std::span<uint8_t>(current_gfx16_));
|
||||||
gfx::Arena::Get().bg2().DrawBackground(std::span<uint8_t>(current_gfx16_));
|
gfx::Arena::Get().bg2().DrawBackground(std::span<uint8_t>(current_gfx16_));
|
||||||
|
std::printf("4. Background drawn from buffer\n");
|
||||||
|
|
||||||
|
auto& bg1_bmp = gfx::Arena::Get().bg1().bitmap();
|
||||||
|
auto& bg2_bmp = gfx::Arena::Get().bg2().bitmap();
|
||||||
|
std::printf("5. BG1 bitmap: active=%d, size=%dx%d, data_size=%zu\n",
|
||||||
|
bg1_bmp.is_active(), bg1_bmp.width(), bg1_bmp.height(), bg1_bmp.vector().size());
|
||||||
|
|
||||||
auto bg1_palette =
|
auto bg1_palette =
|
||||||
rom()->mutable_palette_group()->get_group("dungeon_main")[0].palette(0);
|
rom()->mutable_palette_group()->get_group("dungeon_main")[0].palette(0);
|
||||||
|
|
||||||
if (!gfx::Arena::Get().bg1().bitmap().is_active()) {
|
if (!gfx::Arena::Get().bg1().bitmap().is_active()) {
|
||||||
|
std::printf("6a. Creating new bitmap textures\n");
|
||||||
core::Renderer::Get().CreateAndRenderBitmap(
|
core::Renderer::Get().CreateAndRenderBitmap(
|
||||||
0x200, 0x200, 0x200, gfx::Arena::Get().bg1().bitmap().vector(),
|
0x200, 0x200, 0x200, gfx::Arena::Get().bg1().bitmap().vector(),
|
||||||
gfx::Arena::Get().bg1().bitmap(), bg1_palette);
|
gfx::Arena::Get().bg1().bitmap(), bg1_palette);
|
||||||
@@ -305,10 +320,96 @@ void Room::RenderRoomGraphics() {
|
|||||||
0x200, 0x200, 0x200, gfx::Arena::Get().bg2().bitmap().vector(),
|
0x200, 0x200, 0x200, gfx::Arena::Get().bg2().bitmap().vector(),
|
||||||
gfx::Arena::Get().bg2().bitmap(), bg1_palette);
|
gfx::Arena::Get().bg2().bitmap(), bg1_palette);
|
||||||
} else {
|
} else {
|
||||||
|
std::printf("6b. Updating existing bitmap textures\n");
|
||||||
// Update the bitmap
|
// Update the bitmap
|
||||||
core::Renderer::Get().UpdateBitmap(&gfx::Arena::Get().bg1().bitmap());
|
core::Renderer::Get().UpdateBitmap(&gfx::Arena::Get().bg1().bitmap());
|
||||||
core::Renderer::Get().UpdateBitmap(&gfx::Arena::Get().bg2().bitmap());
|
core::Renderer::Get().UpdateBitmap(&gfx::Arena::Get().bg2().bitmap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::printf("7. BG1 has texture: %d\n", bg1_bmp.texture() != nullptr);
|
||||||
|
std::printf("=== RenderRoomGraphics Complete ===\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Room::RenderObjectsToBackground() {
|
||||||
|
if (!rom_ || !rom_->is_loaded()) {
|
||||||
|
std::printf("RenderObjectsToBackground: ROM not loaded\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::printf("RenderObjectsToBackground: Room %d has %zu objects\n", room_id_, tile_objects_.size());
|
||||||
|
|
||||||
|
// Get references to the background buffers
|
||||||
|
auto& bg1 = gfx::Arena::Get().bg1();
|
||||||
|
auto& bg2 = gfx::Arena::Get().bg2();
|
||||||
|
|
||||||
|
// Render tile objects to their respective layers
|
||||||
|
int rendered_count = 0;
|
||||||
|
for (const auto& obj : tile_objects_) {
|
||||||
|
// Ensure object has tiles loaded
|
||||||
|
auto mutable_obj = const_cast<RoomObject&>(obj);
|
||||||
|
mutable_obj.EnsureTilesLoaded();
|
||||||
|
|
||||||
|
// Get tiles with error handling
|
||||||
|
auto tiles_result = obj.GetTiles();
|
||||||
|
if (!tiles_result.ok()) {
|
||||||
|
std::printf(" Object at (%d,%d) failed to load tiles: %s\n",
|
||||||
|
obj.x_, obj.y_, tiles_result.status().ToString().c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tiles_result->empty()) {
|
||||||
|
std::printf(" Object at (%d,%d) has no tiles\n", obj.x_, obj.y_);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& tiles = *tiles_result;
|
||||||
|
std::printf(" Object at (%d,%d) has %zu tiles\n", obj.x_, obj.y_, tiles.size());
|
||||||
|
|
||||||
|
// Calculate object position in tile coordinates (each position is an 8x8 tile)
|
||||||
|
int obj_x = obj.x_; // X position in 8x8 tile units
|
||||||
|
int obj_y = obj.y_; // Y position in 8x8 tile units
|
||||||
|
|
||||||
|
// Determine which layer this object belongs to
|
||||||
|
bool is_bg2 = (obj.layer_ == RoomObject::LayerType::BG2);
|
||||||
|
auto& target_buffer = is_bg2 ? bg2 : bg1;
|
||||||
|
|
||||||
|
// Draw each Tile16 from the object
|
||||||
|
// Each Tile16 is a 16x16 tile made of 4 TileInfo (8x8) tiles
|
||||||
|
for (size_t i = 0; i < tiles.size(); i++) {
|
||||||
|
const auto& tile16 = tiles[i];
|
||||||
|
|
||||||
|
// Calculate tile16 position (in 16x16 units, so multiply by 2 for 8x8 units)
|
||||||
|
int base_x = obj_x + ((i % 4) * 2); // Assume 4-tile16 width for now
|
||||||
|
int base_y = obj_y + ((i / 4) * 2);
|
||||||
|
|
||||||
|
// Each Tile16 contains 4 TileInfo objects arranged as:
|
||||||
|
// [0][1] (top-left, top-right)
|
||||||
|
// [2][3] (bottom-left, bottom-right)
|
||||||
|
const auto& tile_infos = tile16.tiles_info;
|
||||||
|
|
||||||
|
// Draw the 4 sub-tiles of this Tile16
|
||||||
|
for (int sub_tile = 0; sub_tile < 4; sub_tile++) {
|
||||||
|
int tile_x = base_x + (sub_tile % 2);
|
||||||
|
int tile_y = base_y + (sub_tile / 2);
|
||||||
|
|
||||||
|
// Bounds check
|
||||||
|
if (tile_x < 0 || tile_x >= 64 || tile_y < 0 || tile_y >= 64) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert TileInfo to word format: (vflip<<15) | (hflip<<14) | (over<<13) | (palette<<10) | tile_id
|
||||||
|
uint16_t tile_word = gfx::TileInfoToWord(tile_infos[sub_tile]);
|
||||||
|
|
||||||
|
// Set the tile in the buffer
|
||||||
|
target_buffer.SetTileAt(tile_x, tile_y, tile_word);
|
||||||
|
rendered_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::printf("RenderObjectsToBackground: Rendered %d tiles total\n", rendered_count);
|
||||||
|
|
||||||
|
// Note: Layout objects rendering would go here if needed
|
||||||
|
// For now, focusing on regular tile objects which is what ZScream primarily renders
|
||||||
}
|
}
|
||||||
|
|
||||||
void Room::LoadAnimatedGraphics() {
|
void Room::LoadAnimatedGraphics() {
|
||||||
|
|||||||
@@ -273,9 +273,9 @@ const std::vector<std::string>& Zelda3Labels::GetTileTypeNames() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert all labels to structured map for project embedding
|
// Convert all labels to structured map for project embedding
|
||||||
std::map<std::string, std::map<std::string, std::string>>
|
std::unordered_map<std::string, std::unordered_map<std::string, std::string>>
|
||||||
Zelda3Labels::ToResourceLabels() {
|
Zelda3Labels::ToResourceLabels() {
|
||||||
std::map<std::string, std::map<std::string, std::string>> labels;
|
std::unordered_map<std::string, std::unordered_map<std::string, std::string>> labels;
|
||||||
|
|
||||||
// Rooms
|
// Rooms
|
||||||
const auto& rooms = GetRoomNames();
|
const auto& rooms = GetRoomNames();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
@@ -59,7 +60,7 @@ struct Zelda3Labels {
|
|||||||
* @brief Convert all labels to a structured map for project embedding
|
* @brief Convert all labels to a structured map for project embedding
|
||||||
* @return Map of resource type -> (id -> name) for all resources
|
* @return Map of resource type -> (id -> name) for all resources
|
||||||
*/
|
*/
|
||||||
static std::map<std::string, std::map<std::string, std::string>> ToResourceLabels();
|
static std::unordered_map<std::string, std::unordered_map<std::string, std::string>> ToResourceLabels();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a label by resource type and ID
|
* @brief Get a label by resource type and ID
|
||||||
|
|||||||
Reference in New Issue
Block a user