From 56ef3150287ee944a99a2b1ee520c4af6d3f15d8 Mon Sep 17 00:00:00 2001 From: Justin Scofield <47263509+scawful@users.noreply.github.com> Date: Mon, 12 Sep 2022 21:17:41 -0500 Subject: [PATCH] bitmap optimization, sprites, inventory, tiles --- src/CMakeLists.txt | 4 +- src/app/core/constants.h | 296 ++++++ src/app/editor/overworld_editor.cc | 76 +- src/app/editor/overworld_editor.h | 5 +- src/app/editor/palette_editor.cc | 4 +- src/app/editor/palette_editor.h | 2 +- src/app/editor/screen_editor.cc | 93 +- src/app/editor/screen_editor.h | 15 +- src/app/gfx/bitmap.cc | 7 +- src/app/gfx/bitmap.h | 1 + src/app/rom.cc | 40 +- src/app/zelda3/inventory.cc | 84 ++ src/app/zelda3/inventory.h | 45 + src/app/zelda3/overworld.cc | 113 ++- src/app/zelda3/overworld.h | 21 +- src/app/zelda3/sprite.cc | 921 ++++++++++++++++++ src/app/zelda3/sprite.h | 68 ++ src/app/zelda3/{screen.cc => title_screen.cc} | 19 +- src/app/zelda3/{screen.h => title_screen.h} | 6 +- src/gui/canvas.cc | 23 +- src/gui/canvas.h | 4 +- 21 files changed, 1692 insertions(+), 155 deletions(-) create mode 100644 src/app/zelda3/inventory.cc create mode 100644 src/app/zelda3/inventory.h create mode 100644 src/app/zelda3/sprite.cc create mode 100644 src/app/zelda3/sprite.h rename src/app/zelda3/{screen.cc => title_screen.cc} (85%) rename src/app/zelda3/{screen.h => title_screen.h} (94%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index afe40a3d..9d47e203 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,9 +68,11 @@ set( set( YAZE_APP_ZELDA3_SRC + app/zelda3/inventory.cc app/zelda3/overworld_map.cc app/zelda3/overworld.cc - app/zelda3/screen.cc + app/zelda3/title_screen.cc + app/zelda3/sprite.cc ) set( diff --git a/src/app/core/constants.h b/src/app/core/constants.h index 5a55c95d..aeff07c7 100644 --- a/src/app/core/constants.h +++ b/src/app/core/constants.h @@ -25,6 +25,14 @@ #define MENU_ITEM(w) if (ImGui::MenuItem(w)) #define MENU_ITEM2(w, v) if (ImGui::MenuItem(w, v)) +#define BUTTON_COLUMN(w) \ + ImGui::TableNextColumn(); \ + ImGui::Button(w); + +#define TEXT_COLUMN(w) \ + ImGui::TableNextColumn(); \ + ImGui::Text(w); + #define PRINT_IF_ERROR(expression) \ { \ auto error = expression; \ @@ -1301,6 +1309,294 @@ static const absl::string_view TileTypeNames[] = { "$FE Door X top? (unused?)", "$FF Door X top? (unused?)"}; +static const absl::string_view kSpriteDefaultNames[]{ + "00 Raven", + "01 Vulture", + "02 Flying Stalfos Head", + "03 No Pointer (Empty", + "04 Pull Switch (good", + "05 Pull Switch (unused", + "06 Pull Switch (bad", + "07 Pull Switch (unused", + "08 Octorock (one way", + "09 Moldorm (Boss", + "0A Octorock (four way", + "0B Chicken", + "0C Octorock (?", + "0D Buzzblock", + "0E Snapdragon", + "0F Octoballoon", + "10 Octoballon Hatchlings", + "11 Hinox", + "12 Moblin", + "13 Mini Helmasaure", + "14 Gargoyle's Domain Gate", + "15 Antifairy", + "16 Sahasrahla / Aginah", + "17 Bush Hoarder", + "18 Mini Moldorm", + "19 Poe", + "1A Dwarves", + "1B Arrow in wall", + "1C Statue", + "1D Weathervane", + "1E Crystal Switch", + "1F Bug-Catching Kid", + "20 Sluggula", + "21 Push Switch", + "22 Ropa", + "23 Red Bari", + "24 Blue Bari", + "25 Talking Tree", + "26 Hardhat Beetle", + "27 Deadrock", + "28 Storytellers", + "29 Blind Hideout attendant", + "2A Sweeping Lady", + "2B Storytellers", + "2C Lumberjacks", + "2D Telepathic Stones", + "2E Multipurpose Sprite", + "2F Race Npc", + "30 Person?", + "31 Fortune Teller", + "32 Angry Brothers", + "33 Pull for items", + "34 Scared Girl", + "35 Innkeeper", + "36 Witch", + "37 Waterfall", + "38 Arrow Target", + "39 Average Middle", + "3A Half Magic Bat", + "3B Dash Item", + "3C Village Kid", + "3D Signs? Chicken lady also showed up / Scared ladies outside houses.", + "3E Rock Hoarder", + "3F Tutorial Soldier", + "40 Lightning Lock", + "41 Blue Sword Soldier / Used by guards to detect player", + "42 Green Sword Soldier", + "43 Red Spear Soldier", + "44 Assault Sword Soldier", + "45 Green Spear Soldier", + "46 Blue Archer", + "47 Green Archer", + "48 Red Javelin Soldier", + "49 Red Javelin Soldier 2", + "4A Red Bomb Soldiers", + "4B Green Soldier Recruits", + "4C Geldman", + "4D Rabbit", + "4E Popo", + "4F Popo 2", + "50 Cannon Balls", + "51 Armos", + "52 Giant Zora", + "53 Armos Knights (Boss", + "54 Lanmolas (Boss", + "55 Fireball Zora", + "56 Walking Zora", + "57 Desert Palace Barriers", + "58 Crab", + "59 Bird", + "5A Squirrel", + "5B Spark (Left to Right", + "5C Spark (Right to Left", + "5D Roller (vertical moving", + "5E Roller (vertical moving", + "5F Roller", + "60 Roller (horizontal moving", + "61 Beamos", + "62 Master Sword", + "63 Devalant (Non", + "64 Devalant (Shooter", + "65 Shooting Gallery Proprietor", + "66 Moving Cannon Ball Shooters (Right", + "67 Moving Cannon Ball Shooters (Left", + "68 Moving Cannon Ball Shooters (Down", + "69 Moving Cannon Ball Shooters (Up", + "6A Ball N' Chain Trooper", + "6B Cannon Soldier", + "6C Mirror Portal", + "6D Rat", + "6E Rope", + "6F Keese", + "70 Helmasaur King Fireball", + "71 Leever", + "72 Activator for the ponds (where you throw in items", + "73 Uncle / Priest", + "74 Running Man", + "75 Bottle Salesman", + "76 Princess Zelda", + "77 Antifairy (Alternate", + "78 Village Elder", + "79 Bee", + "7A Agahnim", + "7B Agahnim Energy Ball", + "7C Hyu", + "7D Big Spike Trap", + "7E Guruguru Bar (Clockwise", + "7F Guruguru Bar (Counter Clockwise", + "80 Winder", + "81 Water Tektite", + "82 Antifairy Circle", + "83 Green Eyegore", + "84 Red Eyegore", + "85 Yellow Stalfos", + "86 Kodongos", + "87 Flames", + "88 Mothula (Boss", + "89 Mothula's Beam", + "8A Spike Trap", + "8B Gibdo", + "8C Arrghus (Boss", + "8D Arrghus spawn", + "8E Terrorpin", + "8F Slime", + "90 Wallmaster", + "91 Stalfos Knight", + "92 Helmasaur King", + "93 Bumper", + "94 Swimmers", + "95 Eye Laser (Right", + "96 Eye Laser (Left", + "97 Eye Laser (Down", + "98 Eye Laser (Up", + "99 Pengator", + "9A Kyameron", + "9B Wizzrobe", + "9C Tadpoles", + "9D Tadpoles", + "9E Ostrich (Haunted Grove", + "9F Flute", + "A0 Birds (Haunted Grove", + "A1 Freezor", + "A2 Kholdstare (Boss", + "A3 Kholdstare's Shell", + "A4 Falling Ice", + "A5 Zazak Fireball", + "A6 Red Zazak", + "A7 Stalfos", + "A8 Bomber Flying Creatures from Darkworld", + "A9 Bomber Flying Creatures from Darkworld", + "AA Pikit", + "AB Maiden", + "AC Apple", + "AD Lost Old Man", + "AE Down Pipe", + "AF Up Pipe", + "B0 Right Pip", + "B1 Left Pipe", + "B2 Good bee again?", + "B3 Hylian Inscription", + "B4 Thief?s chest (not the one that follows you", + "B5 Bomb Salesman", + "B6 Kiki", + "B7 Maiden following you in Blind Dungeon", + "B8 Monologue Testing Sprite", + "B9 Feuding Friends on Death Mountain", + "BA Whirlpool", + "BB Salesman / chestgame guy / 300 rupee giver guy / Chest game thief", + "BC Drunk in the inn", + "BD Vitreous (Large Eyeball", + "BE Vitreous (Small Eyeball", + "BF Vitreous' Lightning", + "C0 Monster in Lake of Ill Omen / Quake Medallion", + "C1 Agahnim teleporting Zelda to dark world", + "C2 Boulders", + "C3 Gibo", + "C4 Thief", + "C5 Medusa", + "C6 Four Way Fireball Spitters (spit when you use your sword", + "C7 Hokku", + "C8 Big Fairy who heals you", + "C9 Tektite", + "CA Chain Chomp", + "CB Trinexx", + "CC Another part of trinexx", + "CD Yet another part of trinexx", + "CE Blind The Thief (Boss)", + "CF Swamola", + "D0 Lynel", + "D1 Bunny Beam", + "D2 Flopping fish", + "D3 Stal", + "D4 Landmine", + "D5 Digging Game Proprietor", + "D6 Ganon", + "D7 Copy of Ganon", + "D8 Heart", + "D9 Green Rupee", + "DA Blue Rupee", + "DB Red Rupee", + "DC Bomb Refill (1)", + "DD Bomb Refill (4)", + "DE Bomb Refill (8)", + "DF Small Magic Refill", + "E0 Full Magic Refill", + "E1 Arrow Refill (5)", + "E2 Arrow Refill (10)", + "E3 Fairy", + "E4 Key", + "E5 Big Key", + "E6 Shield", + "E7 Mushroom", + "E8 Fake Master Sword", + "E9 Magic Shop dude / His items", + "EA Heart Container", + "EB Heart Piece", + "EC Bushes", + "ED Cane Of Somaria Platform", + "EE Mantle", + "EF Cane of Somaria Platform (Unused)", + "F0 Cane of Somaria Platform (Unused)", + "F1 Cane of Somaria Platform (Unused)", + "F2 Medallion Tablet", + "F3", + "F4 Falling Rocks", + "F5", + "F6", + "F7", + "F8", + "F9", + "FA", + "FB", + "FC", + "FD", + "FE", + "FF", +}; + +static const absl::string_view overlordnames[] = { + "Overlord_SpritePositionTarget", + "Overlord_AllDirectionMetalBallFactory", + "Overlord_CascadeMetalBallFactory", + "Overlord_StalfosFactory", + "Overlord_StalfosTrap", + "Overlord_SnakeTrap", + "Overlord_MovingFloor", + "Overlord_ZolFactory", + "Overlord_WallMasterFactory", + "Overlord_CrumbleTilePath 1", + "Overlord_CrumbleTilePath 2", + "Overlord_CrumbleTilePath 3", + "Overlord_CrumbleTilePath 4", + "Overlord_CrumbleTilePath 5", + "Overlord_CrumbleTilePath 6", + "Overlord_PirogusuFactory 1", + "Overlord_PirogusuFactory 2", + "Overlord_PirogusuFactory 3", + "Overlord_PirogusuFactory 4", + "Overlord_FlyingTileFactory", + "Overlord_WizzrobeFactory", + "Overlord_ZoroFactory", + "Overlord_StalfosTrapTriggerWindow", + "Overlord_RedStalfosTrap", + "Overlord_ArmosCoordinator", + "Overlord_BombTrap", +}; + } // namespace core } // namespace app } // namespace yaze diff --git a/src/app/editor/overworld_editor.cc b/src/app/editor/overworld_editor.cc index c4244298..1477176e 100644 --- a/src/app/editor/overworld_editor.cc +++ b/src/app/editor/overworld_editor.cc @@ -101,46 +101,21 @@ absl::Status OverworldEditor::DrawToolset() { for (const auto &name : kToolsetColumnNames) ImGui::TableSetupColumn(name.data()); - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_UNDO); - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_REDO); - ImGui::TableNextColumn(); - ImGui::Text(ICON_MD_MORE_VERT); - - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_ZOOM_OUT); - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_ZOOM_IN); - ImGui::TableNextColumn(); - ImGui::Text(ICON_MD_MORE_VERT); - - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_DRAW); - // Entrances - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_DOOR_FRONT); - // Exits - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_DOOR_BACK); - // Items - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_GRASS); - // Sprites - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_PEST_CONTROL_RODENT); - // Transports - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_ADD_LOCATION); - // Music - ImGui::TableNextColumn(); - ImGui::Button(ICON_MD_MUSIC_NOTE); - - // Separator - ImGui::TableNextColumn(); - ImGui::Text(ICON_MD_MORE_VERT); - // Music - ImGui::TableNextColumn(); + BUTTON_COLUMN(ICON_MD_UNDO) // Undo + BUTTON_COLUMN(ICON_MD_REDO) // Redo + TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator + BUTTON_COLUMN(ICON_MD_ZOOM_OUT) // Zoom Out + BUTTON_COLUMN(ICON_MD_ZOOM_IN) // Zoom In + TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator + BUTTON_COLUMN(ICON_MD_DRAW); // Draw Tile + BUTTON_COLUMN(ICON_MD_DOOR_FRONT) // Entrances + BUTTON_COLUMN(ICON_MD_DOOR_BACK) // Exits + BUTTON_COLUMN(ICON_MD_GRASS) // Items + BUTTON_COLUMN(ICON_MD_PEST_CONTROL_RODENT) // Sprites + BUTTON_COLUMN(ICON_MD_ADD_LOCATION) // Transports + BUTTON_COLUMN(ICON_MD_MUSIC_NOTE) // Music + TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator + ImGui::TableNextColumn(); // Palette palette_editor_.DisplayPalette(palette_, overworld_.isLoaded()); ImGui::EndTable(); @@ -223,9 +198,10 @@ void OverworldEditor::DrawOverworldCanvas() { for (const auto &each : overworld_.Entrances()) { if (each.mapId_ < 64 + (current_world_ * 0x40) && each.mapId_ >= (current_world_ * 0x40)) { - overworld_map_canvas_.DrawOutline(each.x_, each.y_, 16, 16); + overworld_map_canvas_.DrawRect(each.x_, each.y_, 16, 16, + ImVec4(210, 24, 210, 150)); std::string str = absl::StrFormat("%#x", each.entranceId_); - overworld_map_canvas_.DrawText(str, each.x_ - 2, each.y_ - 14); + overworld_map_canvas_.DrawText(str, each.x_ - 4, each.y_ - 2); } } } @@ -271,9 +247,7 @@ void OverworldEditor::DrawTileSelector() { void OverworldEditor::DrawTile16Selector() { blockset_canvas_.DrawBackground(ImVec2(0x100 + 1, (8192 * 2) + 1)); blockset_canvas_.DrawContextMenu(); - if (map_blockset_loaded_) { - blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, 2); - } + blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, 2, map_blockset_loaded_); blockset_canvas_.DrawGrid(32.0f); blockset_canvas_.DrawOverlay(); } @@ -301,13 +275,11 @@ void OverworldEditor::DrawTile8Selector() { } void OverworldEditor::DrawAreaGraphics() { - if (overworld_.isLoaded()) { - current_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 16 * 64 + 1)); - current_gfx_canvas_.DrawContextMenu(); - current_gfx_canvas_.DrawBitmap(current_gfx_bmp_); - current_gfx_canvas_.DrawGrid(32.0f); - current_gfx_canvas_.DrawOverlay(); - } + current_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 16 * 64 + 1)); + current_gfx_canvas_.DrawContextMenu(); + current_gfx_canvas_.DrawBitmap(current_gfx_bmp_, 2, overworld_.isLoaded()); + current_gfx_canvas_.DrawGrid(32.0f); + current_gfx_canvas_.DrawOverlay(); } void OverworldEditor::LoadGraphics() { diff --git a/src/app/editor/overworld_editor.h b/src/app/editor/overworld_editor.h index ccbaf9b1..2b1cb868 100644 --- a/src/app/editor/overworld_editor.h +++ b/src/app/editor/overworld_editor.h @@ -84,20 +84,21 @@ class OverworldEditor { ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingStretchSame; + Bytes selected_tile_data_; std::unordered_map graphics_bin_; std::unordered_map current_graphics_set_; std::unordered_map maps_bmp_; + std::unordered_map sprite_previews_; ROM rom_; - zelda3::Overworld overworld_; PaletteEditor palette_editor_; + zelda3::Overworld overworld_; gfx::SNESPalette palette_; gfx::Bitmap tile16_blockset_bmp_; gfx::Bitmap current_gfx_bmp_; gfx::Bitmap all_gfx_bmp; gfx::Bitmap selected_tile_bmp_; - Bytes selected_tile_data_; gui::Canvas overworld_map_canvas_; gui::Canvas current_gfx_canvas_; diff --git a/src/app/editor/palette_editor.cc b/src/app/editor/palette_editor.cc index ca676fe3..00e6c381 100644 --- a/src/app/editor/palette_editor.cc +++ b/src/app/editor/palette_editor.cc @@ -41,8 +41,7 @@ absl::Status PaletteEditor::Update() { return absl::OkStatus(); } -absl::Status PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, - bool loaded) { +void PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, bool loaded) { static ImVec4 color = ImVec4(0, 0, 0, 255.f); ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_NoDragDrop | @@ -122,7 +121,6 @@ absl::Status PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, ImGui::EndGroup(); ImGui::EndPopup(); } - return absl::OkStatus(); } } // namespace editor diff --git a/src/app/editor/palette_editor.h b/src/app/editor/palette_editor.h index d27551b8..80ab485f 100644 --- a/src/app/editor/palette_editor.h +++ b/src/app/editor/palette_editor.h @@ -26,7 +26,7 @@ static constexpr absl::string_view kPaletteGroupNames[] = { class PaletteEditor { public: absl::Status Update(); - absl::Status DisplayPalette(gfx::SNESPalette& palette, bool loaded); + void DisplayPalette(gfx::SNESPalette& palette, bool loaded); auto SetupROM(ROM& rom) { rom_ = rom; } diff --git a/src/app/editor/screen_editor.cc b/src/app/editor/screen_editor.cc index 0ad889f2..793d660c 100644 --- a/src/app/editor/screen_editor.cc +++ b/src/app/editor/screen_editor.cc @@ -27,13 +27,12 @@ ScreenEditor::ScreenEditor() { screen_canvas_.SetCanvasSize(ImVec2(512, 512)); } void ScreenEditor::Update() { TAB_BAR("##TabBar") - DrawMosaicEditor(); + DrawInventoryMenuEditor(); DrawTitleScreenEditor(); DrawNamingScreenEditor(); DrawOverworldMapEditor(); DrawDungeonMapsEditor(); - DrawGameMenuEditor(); - DrawHUDEditor(); + DrawMosaicEditor(); END_TAB_BAR() } @@ -60,6 +59,61 @@ void ScreenEditor::DrawWorldGrid(int world, int h, int w) { } } +void ScreenEditor::DrawInventoryMenuEditor() { + TAB_ITEM("Inventory Menu") + + static bool create = false; + if (!create) { + PRINT_IF_ERROR(rom_.LoadAllGraphicsData()) + all_gfx_ = rom_.GetGraphicsBuffer(); + inventory_.Create(all_gfx_); + create = true; + } + + if (ImGui::BeginTable("InventoryScreen", 2, ImGuiTableFlags_Resizable)) { + ImGui::TableSetupColumn("Canvas"); + ImGui::TableSetupColumn("Tiles"); + ImGui::TableHeadersRow(); + + ImGui::TableNextColumn(); + screen_canvas_.DrawBackground(); + screen_canvas_.DrawContextMenu(); + screen_canvas_.DrawBitmap(inventory_.Bitmap(), 2, create); + screen_canvas_.DrawGrid(); + screen_canvas_.DrawOverlay(); + + ImGui::TableNextColumn(); + tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, 192 * 2 + 2)); + tilesheet_canvas_.DrawContextMenu(); + tilesheet_canvas_.DrawBitmap(inventory_.Tilesheet(), 2, create); + tilesheet_canvas_.DrawGrid(); + tilesheet_canvas_.DrawOverlay(); + + ImGui::EndTable(); + } + + ImGui::SameLine(); + + END_TAB_ITEM() +} + +void ScreenEditor::DrawTitleScreenEditor() { + TAB_ITEM("Title Screen") + END_TAB_ITEM() +} +void ScreenEditor::DrawNamingScreenEditor() { + TAB_ITEM("Naming Screen") + END_TAB_ITEM() +} +void ScreenEditor::DrawOverworldMapEditor() { + TAB_ITEM("Overworld Map") + END_TAB_ITEM() +} +void ScreenEditor::DrawDungeonMapsEditor() { + TAB_ITEM("Dungeon Maps") + END_TAB_ITEM() +} + void ScreenEditor::DrawMosaicEditor() { TAB_ITEM("Mosaic Transitions") @@ -94,39 +148,6 @@ void ScreenEditor::DrawMosaicEditor() { END_TAB_ITEM() } -void ScreenEditor::DrawTitleScreenEditor() { - TAB_ITEM("Title Screen") - END_TAB_ITEM() -} -void ScreenEditor::DrawNamingScreenEditor() { - TAB_ITEM("Naming Screen") - END_TAB_ITEM() -} -void ScreenEditor::DrawOverworldMapEditor() { - TAB_ITEM("Overworld Map") - END_TAB_ITEM() -} -void ScreenEditor::DrawDungeonMapsEditor() { - TAB_ITEM("Dungeon Maps") - END_TAB_ITEM() -} -void ScreenEditor::DrawGameMenuEditor() { - TAB_ITEM("Game Menu") - END_TAB_ITEM() -} -void ScreenEditor::DrawHUDEditor() { - TAB_ITEM("Heads-up Display") - END_TAB_ITEM() -} - -void ScreenEditor::DrawCanvas() { - screen_canvas_.DrawBackground(); - screen_canvas_.DrawContextMenu(); - - screen_canvas_.DrawGrid(); - screen_canvas_.DrawOverlay(); -} - void ScreenEditor::DrawToolset() { static bool show_bg1 = true; static bool show_bg2 = true; diff --git a/src/app/editor/screen_editor.h b/src/app/editor/screen_editor.h index a6a363e1..46b0fbfa 100644 --- a/src/app/editor/screen_editor.h +++ b/src/app/editor/screen_editor.h @@ -10,7 +10,7 @@ #include "app/gfx/bitmap.h" #include "app/gfx/snes_tile.h" #include "app/rom.h" -#include "app/zelda3/screen.h" +#include "app/zelda3/inventory.h" #include "gui/canvas.h" namespace yaze { @@ -24,7 +24,10 @@ static int overworldCustomMosaicArray = 0x1301F0; class ScreenEditor { public: ScreenEditor(); - void SetupROM(ROM &rom) { rom_ = rom; } + void SetupROM(ROM &rom) { + rom_ = rom; + inventory_.SetupROM(rom_); + } void Update(); private: @@ -33,19 +36,19 @@ class ScreenEditor { void DrawNamingScreenEditor(); void DrawOverworldMapEditor(); void DrawDungeonMapsEditor(); - void DrawGameMenuEditor(); - void DrawHUDEditor(); + void DrawInventoryMenuEditor(); - void DrawCanvas(); void DrawToolset(); void DrawWorldGrid(int world, int h = 8, int w = 8); char mosaic_tiles_[core::kNumOverworldMaps]; ROM rom_; + Bytes all_gfx_; + zelda3::Inventory inventory_; snes_asm::Script mosaic_script_; - zelda3::Screen current_screen_; gui::Canvas screen_canvas_; + gui::Canvas tilesheet_canvas_; }; } // namespace editor diff --git a/src/app/gfx/bitmap.cc b/src/app/gfx/bitmap.cc index 201e890b..6d27ee93 100644 --- a/src/app/gfx/bitmap.cc +++ b/src/app/gfx/bitmap.cc @@ -47,8 +47,8 @@ void Bitmap::Create(int width, int height, int depth, uchar *data) { SDL_CreateRGBSurfaceWithFormat(0, width_, height_, depth_, SDL_PIXELFORMAT_INDEX8), SDL_Surface_Deleter()); - GrayscalePalette(surface_->format->palette); surface_->pixels = pixel_data_; + GrayscalePalette(surface_->format->palette); } // Reserves data to later draw to surface via pointer @@ -57,13 +57,14 @@ void Bitmap::Create(int width, int height, int depth, int size) { height_ = height; depth_ = depth; data_size_ = size; + data_.reserve(size); + pixel_data_ = data_.data(); surface_ = std::unique_ptr( SDL_CreateRGBSurfaceWithFormat(0, width, height, depth, SDL_PIXELFORMAT_INDEX8), SDL_Surface_Deleter()); - GrayscalePalette(surface_->format->palette); - pixel_data_ = (uchar *)SDL_malloc(size); surface_->pixels = pixel_data_; + GrayscalePalette(surface_->format->palette); } // Pass raw pixel data directly to the surface diff --git a/src/app/gfx/bitmap.h b/src/app/gfx/bitmap.h index 84dfa5d0..ea03af47 100644 --- a/src/app/gfx/bitmap.h +++ b/src/app/gfx/bitmap.h @@ -53,6 +53,7 @@ class Bitmap { struct SDL_Surface_Deleter { void operator()(SDL_Surface *p) const { if (p != nullptr) { + p->pixels = nullptr; SDL_FreeSurface(p); p = nullptr; } diff --git a/src/app/rom.cc b/src/app/rom.cc index 91f8826d..cf8561b4 100644 --- a/src/app/rom.cc +++ b/src/app/rom.cc @@ -35,22 +35,28 @@ int GetGraphicsAddress(const uchar* data, uint8_t offset) { return core::SnesToPc(snes_addr); } -Bytes SNES3bppTo8bppSheet(Bytes sheet) { +Bytes SNES3bppTo8bppSheet(Bytes sheet, int bpp) { Bytes sheet_buffer_out(0x1000); int xx = 0; // positions where we are at on the sheet int yy = 0; int pos = 0; int ypos = 0; + if (bpp == 2) { + bpp = 16; + } else if (bpp == 3) { + bpp = 24; + } + // for each tiles, 16 per line for (int i = 0; i < 64; i++) { // for each line for (int y = 0; y < 8; y++) { //[0] + [1] + [16] for (int x = 0; x < 8; x++) { - auto b1 = ((sheet[(y * 2) + (24 * pos)] & (kGraphicsBitmap[x]))); - auto b2 = (sheet[((y * 2) + (24 * pos)) + 1] & (kGraphicsBitmap[x])); - auto b3 = (sheet[(16 + y) + (24 * pos)] & (kGraphicsBitmap[x])); + auto b1 = ((sheet[(y * 2) + (bpp * pos)] & (kGraphicsBitmap[x]))); + auto b2 = (sheet[((y * 2) + (bpp * pos)) + 1] & (kGraphicsBitmap[x])); + auto b3 = (sheet[(16 + y) + (bpp * pos)] & (kGraphicsBitmap[x])); unsigned char b = 0; if (b1 != 0) { b |= 1; @@ -58,7 +64,7 @@ Bytes SNES3bppTo8bppSheet(Bytes sheet) { if (b2 != 0) { b |= 2; } - if (b3 != 0) { + if (b3 != 0 && bpp != 16) { b |= 4; } sheet_buffer_out[x + (xx) + (y * 128) + (yy * 1024)] = b; @@ -590,7 +596,7 @@ absl::StatusOr ROM::DecompressOverworld(int pos, int size) { // 218-222 -> compressed 2bpp -> (decompressed each) 0x800 chars absl::Status ROM::LoadAllGraphicsData() { Bytes sheet; - bool convert = false; + bool bpp3 = false; for (int i = 0; i < core::NumberOfSheets; i++) { if (i >= 115 && i <= 126) { // uncompressed sheets @@ -599,17 +605,19 @@ absl::Status ROM::LoadAllGraphicsData() { for (int j = 0; j < core::Uncompressed3BPPSize; j++) { sheet[j] = rom_data_[j + offset]; } - convert = true; + bpp3 = true; } else if (i == 113 || i == 114 || i >= 218) { - convert = false; + auto offset = GetGraphicsAddress(rom_data_.data(), i); + ASSIGN_OR_RETURN(sheet, Decompress(offset, 0x800)) + bpp3 = false; } else { auto offset = GetGraphicsAddress(rom_data_.data(), i); ASSIGN_OR_RETURN(sheet, Decompress(offset)) - convert = true; + bpp3 = true; } - if (convert) { - auto converted_sheet = SNES3bppTo8bppSheet(sheet); + if (bpp3) { + auto converted_sheet = SNES3bppTo8bppSheet(sheet, 3); graphics_bin_[i] = gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight, core::kTilesheetDepth, converted_sheet.data(), 0x1000); @@ -619,8 +627,14 @@ absl::Status ROM::LoadAllGraphicsData() { graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j)); } } else { - for (int j = 0; j < 0x1000; ++j) { - graphics_buffer_.push_back(0xFF); + auto converted_sheet = SNES3bppTo8bppSheet(sheet, 2); + graphics_bin_[i] = + gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight, + core::kTilesheetDepth, converted_sheet.data(), 0x1000); + graphics_bin_.at(i).CreateTexture(renderer_); + + for (int j = 0; j < graphics_bin_.at(i).GetSize(); ++j) { + graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j)); } } } diff --git a/src/app/zelda3/inventory.cc b/src/app/zelda3/inventory.cc new file mode 100644 index 00000000..923054a1 --- /dev/null +++ b/src/app/zelda3/inventory.cc @@ -0,0 +1,84 @@ +#include "inventory.h" + +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" + +namespace yaze { +namespace app { +namespace zelda3 { +void Inventory::Create(Bytes& all_gfx) { + data_.reserve(256 * 256); + for (int i = 0; i < 256 * 256; i++) { + data_.push_back(0xFF); + } + BuildTileset(all_gfx); + tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos))); + const int offsets[] = {0x00, 0x08, 0x200, 0x208}; + auto xx = 0; + auto yy = 0; + + int i = 0; + for (const auto& tile : tiles_) { + int offset = offsets[i]; + for (auto y = 0; y < 0x08; ++y) { + for (auto x = 0; x < 0x08; ++x) { + int mx = x; + int my = y; + + if (tile.horizontal_mirror_ != 0) { + mx = 0x07 - x; + } + + if (tile.vertical_mirror_ != 0) { + my = 0x07 - y; + } + + int xpos = ((tile.id_ % 0x10) * 0x08); + int ypos = (((tile.id_ / 0x10)) * 0x200); + int source = ypos + xpos + (x + (y * 0x80)); + + auto destination = xx + yy + offset + (mx + (my * 0x100)); + data_[destination] = (tilesheets_[source] & 0x0F); + } + } + + xx += 0x10; + if (xx >= 0x80) { + yy += 0x800; + xx = 0; + } + + if (i == 4) { + i = 0; + } + i++; + } + bitmap_.Create(256, 256, 128, data_); + // bitmap_.ApplyPalette(rom_.GetPaletteGroup("hud")[0]); + rom_.RenderBitmap(&bitmap_); +} + +void Inventory::BuildTileset(Bytes& all_gfx) { + //const int offsets[] = {0xDC000, 0x6D900, 0x6EF00, 0x6F000, 0xD8000, 0xD9000}; + const int offsets[] = {0xDC000, 0x6D900, 0x6EF00, 0x6F000, 0xD8000, 0xD9000}; + tilesheets_.reserve(6 * 0x1000); + for (int i = 0; i < 6 * 0x1000; i++) { + tilesheets_.push_back(0xFF); + } + + for (int y = 0; y < 6; y++) { + int offset = offsets[y]; + for (int x = 0; x < 0x1000; x++) { + tilesheets_[x + (y * 0x1000)] = all_gfx[offset + x + (y * 0x1000)]; + } + } + + tilesheets_bmp_.Create(128, 192, 64, tilesheets_); + rom_.RenderBitmap(&tilesheets_bmp_); +} + +} // namespace zelda3 +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/zelda3/inventory.h b/src/app/zelda3/inventory.h new file mode 100644 index 00000000..3af04d26 --- /dev/null +++ b/src/app/zelda3/inventory.h @@ -0,0 +1,45 @@ +#ifndef YAZE_APP_ZELDA3_INVENTORY_H +#define YAZE_APP_ZELDA3_INVENTORY_H + +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" +#include "gui/canvas.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +constexpr int kMenuGfxStart = 0xE000; +constexpr int kLampItemPos = 0x6F6F0; +constexpr int kBowItemPos = 0x6F631; + +class Inventory { + public: + void SetupROM(ROM& rom) { rom_ = rom; } + auto Bitmap() const { return bitmap_; } + auto Tilesheet() const { return tilesheets_bmp_; } + + void Create(Bytes& all_gfx); + + private: + void BuildTileset(Bytes& all_gfx); + + + ROM rom_; + + Bytes data_; + gfx::Bitmap bitmap_; + + Bytes tilesheets_; + gfx::Bitmap tilesheets_bmp_; + + gui::Canvas canvas_; + std::vector tiles_; +}; + +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/zelda3/overworld.cc b/src/app/zelda3/overworld.cc index 2ae05a0c..e807be2f 100644 --- a/src/app/zelda3/overworld.cc +++ b/src/app/zelda3/overworld.cc @@ -39,6 +39,7 @@ absl::Status Overworld::Load(ROM &rom) { FetchLargeMaps(); LoadEntrances(); + LoadSprites(); auto size = tiles16.size(); for (int i = 0; i < core::kNumOverworldMaps; ++i) { @@ -265,10 +266,118 @@ void Overworld::LoadEntrances() { int p = (mapPos + 0x400) >> 1; int x = (p % 64); int y = (p >> 6); - all_holes_.emplace_back(EntranceOWEditor( + all_holes_.emplace_back( (x * 16) + (((mapId % 64) - (((mapId % 64) / 8) * 8)) * 512), (y * 16) + (((mapId % 64) / 8) * 512), entranceId, mapId, - (ushort)(mapPos + 0x400), true)); + (ushort)(mapPos + 0x400), true); + } +} + +void Overworld::LoadSprites() { + // LW[0] = RainState 0 to 63 there's no data for DW + // LW[1] = ZeldaState 0 to 128 ; Contains LW and DW <128 or 144 wtf + // LW[2] = AgahState 0 to ?? ;Contains data for LW and DW + + for (int i = 0; i < 3; i++) { + all_sprites_.emplace_back(std::vector()); + } + + // Console.WriteLine(((core::overworldSpritesBegining & 0xFFFF) + (09 << + // 16)).ToString("X6")); + for (int i = 0; i < 64; i++) { + if (map_parent_[i] == i) { + // Beginning Sprites + int ptrPos = core::overworldSpritesBegining + (i * 2); + int spriteAddress = core::SnesToPc((0x09 << 0x10) + rom_.toint16(ptrPos)); + while (true) { + uchar b1 = rom_[spriteAddress]; + uchar b2 = rom_[spriteAddress + 1]; + uchar b3 = rom_[spriteAddress + 2]; + if (b1 == 0xFF) { + break; + } + + int mapY = (i / 8); + int mapX = (i % 8); + + int realX = ((b2 & 0x3F) * 16) + mapX * 512; + int realY = ((b1 & 0x3F) * 16) + mapY * 512; + + all_sprites_[0].emplace_back(overworld_maps_[i].AreaGraphics(), + (uchar)i, b3, (uchar)(b2 & 0x3F), + (uchar)(b1 & 0x3F), realX, realY); + + spriteAddress += 3; + } + } + } + + for (int i = 0; i < 144; i++) { + if (map_parent_[i] == i) { + // Zelda Saved Sprites + int ptrPos = core::overworldSpritesZelda + (i * 2); + int spriteAddress = core::SnesToPc((0x09 << 0x10) + rom_.toint16(ptrPos)); + while (true) { + uchar b1 = rom_[spriteAddress]; + uchar b2 = rom_[spriteAddress + 1]; + uchar b3 = rom_[spriteAddress + 2]; + if (b1 == 0xFF) { + break; + } + + int editorMapIndex = i; + if (editorMapIndex >= 128) { + editorMapIndex = i - 128; + } else if (editorMapIndex >= 64) { + editorMapIndex = i - 64; + } + + int mapY = (editorMapIndex / 8); + int mapX = (editorMapIndex % 8); + + int realX = ((b2 & 0x3F) * 16) + mapX * 512; + int realY = ((b1 & 0x3F) * 16) + mapY * 512; + + all_sprites_[1].emplace_back(overworld_maps_[i].AreaGraphics(), + (uchar)i, b3, (uchar)(b2 & 0x3F), + (uchar)(b1 & 0x3F), realX, realY); + + spriteAddress += 3; + } + } + + // Agahnim Dead Sprites + if (map_parent_[i] == i) { + int ptrPos = core::overworldSpritesAgahnim + (i * 2); + int spriteAddress = core::SnesToPc((0x09 << 0x10) + rom_.toint16(ptrPos)); + while (true) { + uchar b1 = rom_[spriteAddress]; + uchar b2 = rom_[spriteAddress + 1]; + uchar b3 = rom_[spriteAddress + 2]; + if (b1 == 0xFF) { + break; + } + + int editorMapIndex = i; + if (editorMapIndex >= 128) { + editorMapIndex = i - 128; + } else if (editorMapIndex >= 64) { + editorMapIndex = i - 64; + } + + int mapY = (editorMapIndex / 8); + int mapX = (editorMapIndex % 8); + + int realX = ((b2 & 0x3F) * 16) + mapX * 512; + int realY = ((b1 & 0x3F) * 16) + mapY * 512; + + all_sprites_[2].emplace_back(overworld_maps_[i].AreaGraphics(), + (uchar)i, b3, (uchar)(b2 & 0x3F), + (uchar)(b1 & 0x3F), realX, realY); + + spriteAddress += 3; + } + } } } diff --git a/src/app/zelda3/overworld.h b/src/app/zelda3/overworld.h index 5e0cf007..ca2212d9 100644 --- a/src/app/zelda3/overworld.h +++ b/src/app/zelda3/overworld.h @@ -12,12 +12,13 @@ #include "app/gfx/snes_tile.h" #include "app/rom.h" #include "app/zelda3/overworld_map.h" +#include "app/zelda3/sprite.h" namespace yaze { namespace app { namespace zelda3 { -class EntranceOWEditor { +class OverworldEntrance { public: int x_; int y_; @@ -27,8 +28,8 @@ class EntranceOWEditor { bool isHole = false; bool deleted = false; - EntranceOWEditor(int x, int y, uchar entranceId, short mapId, ushort mapPos, - bool hole) { + OverworldEntrance(int x, int y, uchar entranceId, short mapId, ushort mapPos, + bool hole) { x_ = x; y_ = y; entranceId_ = entranceId; @@ -45,7 +46,7 @@ class EntranceOWEditor { } auto Copy() { - return new EntranceOWEditor(x_, y_, entranceId_, mapId_, mapPos, isHole); + return new OverworldEntrance(x_, y_, entranceId_, mapId_, mapPos, isHole); } void updateMapStuff(short mapId) { @@ -77,7 +78,7 @@ class Overworld { auto GetTiles16() const { return tiles16; } auto GetOverworldMap(uint index) { return overworld_maps_[index]; } auto GetOverworldMaps() const { return overworld_maps_; } - + auto Sprites() const { return all_sprites_[game_state_]; } auto AreaGraphics() const { return overworld_maps_[current_map_].AreaGraphics(); } @@ -89,7 +90,7 @@ class Overworld { auto Tile16Blockset() const { return overworld_maps_[current_map_].Tile16Blockset(); } - + auto GameState() const { return game_state_; } auto isLoaded() const { return is_loaded_; } void SetCurrentMap(int i) { current_map_ = i; } @@ -113,10 +114,11 @@ class Overworld { absl::Status DecompressAllMapTiles(); void FetchLargeMaps(); void LoadEntrances(); + void LoadSprites(); void LoadOverworldMap(); - int game_state_ = 1; + int game_state_ = 0; int current_map_ = 0; uchar map_parent_[160]; bool is_loaded_ = false; @@ -127,8 +129,9 @@ class Overworld { std::vector tiles16; std::vector tiles32; std::vector overworld_maps_; - std::vector all_entrances_; - std::vector all_holes_; + std::vector all_entrances_; + std::vector all_holes_; + std::vector> all_sprites_; }; } // namespace zelda3 diff --git a/src/app/zelda3/sprite.cc b/src/app/zelda3/sprite.cc new file mode 100644 index 00000000..52774d58 --- /dev/null +++ b/src/app/zelda3/sprite.cc @@ -0,0 +1,921 @@ +#include "sprite.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +Sprite::Sprite(Bytes src, uchar mapid, uchar id, uchar x, uchar y, int map_x, + int map_y) { + current_gfx_ = src; + overworld_ = true; + map_id_ = mapid; + id_ = id; + x_ = x; + y_ = y; + nx_ = x; + ny_ = y; + name_ = core::kSpriteDefaultNames[id]; + map_x_ = map_x; + map_y_ = map_y; + preview_gfx_.reserve(64 * 64); + for (int i = 0; i < 64 * 64; i++) { + preview_gfx_.push_back(0xFF); + } +} + +void Sprite::updateBBox() { + lowerX_ = 1; + lowerY_ = 1; + higherX_ = 15; + higherY_ = 15; +} + +void Sprite::Draw(bool picker) { + uchar x = nx_; + uchar y = ny_; + picker_ = picker; + + if (overlord_ == 0x07) { + if (id_ == 0x1A) { + DrawSpriteTile((x * 16), (y * 16), 14, 6, 11); // bomb + } else if (id_ == 0x05) { + DrawSpriteTile((x * 16), (y * 16) - 12, 12, 16, 12, false, true); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 12, false, true); + } else if (id_ == 0x06) { + DrawSpriteTile((x * 16), (y * 16), 10, 26, 14, true, true, 2, + 2); // snek + } else if (id_ == 0x09) { + DrawSpriteTile((x * 16), (y * 16), 6, 26, 14); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 8, 26, 14); + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 27, 14, false, false, 1, 1); + } else if (id_ == 0x14) { + DrawSpriteTile((x * 16), (y * 16) + 8, 12, 06, 12, false, false, 2, + 1); // shadow tile + DrawSpriteTile((x * 16), (y * 16) - 8, 3, 29, 8, false, false, 1, + 1); // tile + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 3, 29, 8, true, false, 1, + 1); // tile + DrawSpriteTile((x * 16), (y * 16), 3, 29, 8, false, true, 1, + 1); // tile + DrawSpriteTile((x * 16) + 8, (y * 16), 3, 29, 8, true, true, 1, + 1); // tile + } else { + DrawSpriteTile((x * 16), (y * 16), 4, 4, 5); + } + + if (nx_ != x || ny_ != y) { + bounding_box_.x = (lowerX_ + (nx_ * 16)); + bounding_box_.y = (lowerY_ + (ny_ * 16)); + bounding_box_.w = width_; + bounding_box_.h = height_; + } else { + bounding_box_.x = (lowerX_ + (x * 16)); + bounding_box_.y = (lowerY_ + (y * 16)); + bounding_box_.w = width_; + bounding_box_.h = height_; + } + + return; + } + + if (id_ == 0x00) { + DrawSpriteTile((x * 16), (y * 16), 4, 28, 10); + } else if (id_ == 0x01) { + DrawSpriteTile((x * 16) - 8, (y * 16), 6, 24, 12, false, false, 2, 2); + DrawSpriteTile((x * 16) + 8, (y * 16), 6, 24, 12, true, false, 2, 2); + } else if (id_ == 0x02) { + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0x04) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x05) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x06) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x07) { + uchar p = 3; + + DrawSpriteTile((x * 16), (y * 16), 14, 28, p); + DrawSpriteTile((x * 16), (y * 16), 14, 30, p); + } else if (id_ == 0x08) { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 6); + DrawSpriteTile((x * 16) + 4, (y * 16) + 6, 0, 24, 6, false, false, 1, 1); + } else if (id_ == 0x09) { + DrawSpriteTile((x * 16) - 22, (y * 16) - 24, 12, 24, 12, false, false, 2, + 2); // Moldorm tail + DrawSpriteTile((x * 16) - 16, (y * 16) - 20, 8, 24, 12, false, false, 2, + 2); // Moldorm b2 + DrawSpriteTile((x * 16) - 12, (y * 16) - 16, 4, 24, 12, false, false, 4, + 4); // Moldorm b + DrawSpriteTile((x * 16), (y * 16), 0, 24, 12, false, false, 4, + 4); // Moldorm head + + DrawSpriteTile((x * 16) + 20, (y * 16) + 12, 8, 26, 14, false, false, 2, + 2); // Moldorm eye + DrawSpriteTile((x * 16) + 12, (y * 16) + 20, 8, 26, 14, false, false, 2, + 2); // Moldorm eye + } else if (id_ == 0x0A) { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 8); + DrawSpriteTile((x * 16) + 4, (y * 16) + 6, 0, 24, 8, false, false, 1, 1); + } else if (id_ == 0x0B) { + DrawSpriteTile((x * 16), (y * 16), 10, 30, 10); + } else if (id_ == 0x0C) { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 8); + DrawSpriteTile((x * 16) + 4, (y * 16) + 6, 0, 24, 8, false, false, 1, 1); + } else if (id_ == 0x0D) { + DrawSpriteTile((x * 16), (y * 16), 14, 28, 12); + } else if (id_ == 0x0E) { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 10, false, false, 3, 2); + } else if (id_ == 0x0F) { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 8, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 30, 8, 8, true, false, 1, 3); + } else if (id_ == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 12, 31, 8, false, false, 1, 1); + } else if (id_ == 0x11) { + DrawSpriteTile((x * 16), (y * 16) + 16, 6, 16, 8, false, false, 2, + 2); // Feet + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 4, 18, 8, false, false, 2, + 2); // Body1 + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 4, 18, 8, true, false, 2, + 2); // Body2 + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8, false, false, 2, + 2); // Head + } else if (id_ == 0x12) { + DrawSpriteTile((x * 16), (y * 16) + 8, 8, 26, 8); + DrawSpriteTile((x * 16), (y * 16), 6, 24, 8); + } else if (id_ == 0x13) { + DrawSpriteTile((x * 16), (y * 16), 4, 22, 2); + } else if (id_ == 0x15) { + // Antifairy + DrawSpriteTile((x * 16) + 2, (y * 16) + 8, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 2, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 14, (y * 16) + 8, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 14, 3, 30, 5, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 1, 30, 5, false, false, 1, + 1); // Middle + } else if (id_ == 0x16) { + DrawSpriteTile((x * 16), (y * 16) + 8, 2, 26, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 26, 2); + } else if (id_ == 0x17) // Bush hoarder + { + DrawSpriteTile((x * 16), (y * 16), 8, 30, 10); + } else if (id_ == 0x18) // Mini moldorm + { + DrawSpriteTile((x * 16) + 13, (y * 16) + 17, 13, 21, 8, false, false, 1, + 1); // Tail + DrawSpriteTile((x * 16) + 5, (y * 16) + 8, 2, 22, 8); // Body + DrawSpriteTile((x * 16), (y * 16), 0, 22, 8); // Head + DrawSpriteTile((x * 16), (y * 16) - 4, 13, 20, 8, false, false, 1, + 1); // Eyes + DrawSpriteTile((x * 16) - 4, (y * 16), 13, 20, 8, false, false, 1, + 1); // Eyes + } else if (id_ == 0x19) // Poe - ghost + { + DrawSpriteTile((x * 16), (y * 16), 6, 31, 2); // + } else if (id_ == 0x1A) // Smith + { + // DrawSpriteTile((x*16), (y *16), 2, 4, 10,true); // Smitty + // DrawSpriteTile((x*16)+12, (y *16) - 7, 0, 6, 10); // Hammer + DrawSpriteTile((x * 16), (y * 16), 4, 22, 10); + } else if (id_ == 0x1C) // Statue + { + DrawSpriteTile((x * 16), (y * 16) + 8, 0, 28, 15); + DrawSpriteTile((x * 16), (y * 16), 2, 28, 15, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16), 2, 28, 15, true, false, 1, 1); + } else if (id_ == 0x1E) // Crystal switch + { + DrawSpriteTile((x * 16), (y * 16), 4, 30, 5); + } else if (id_ == 0x1F) // Sick kid + { + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 10, 16, 14); + DrawSpriteTile((x * 16) + 16 - 8, (y * 16) + 8, 10, 16, 14, true); + DrawSpriteTile((x * 16) - 8, (y * 16) + 16, 10, 16, 14, false, true, 2, 2); + DrawSpriteTile((x * 16) + 16 - 8, (y * 16) + 16, 10, 16, 14, true, true, 2, + 2); + DrawSpriteTile((x * 16), (y * 16) - 4, 14, 16, 10); + } else if (id_ == 0x20) { + DrawSpriteTile((x * 16), (y * 16), 2, 24, 7); + } else if (id_ == 0x21) // Push switch + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 20, 13, 29, 3, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) + 28, 12, 29, 3, false, false, 1, 1); + DrawSpriteTile((x * 16), (y * 16) + 8, 10, 28, 3); + } else if (id_ == 0x22) // Rope + { + DrawSpriteTile((x * 16), (y * 16), 8, 26, 5); + } else if (id_ == 0x23) // Red bari + { + DrawSpriteTile((x * 16), (y * 16), 2, 18, 4, false, false, 1, 2); + DrawSpriteTile((x * 16) + 8, (y * 16), 2, 18, 4, true, false, 1, 2); + } else if (id_ == 0x24) // Blue bari + { + DrawSpriteTile((x * 16), (y * 16), 2, 18, 6, false, false, 1, 2); + DrawSpriteTile((x * 16) + 8, (y * 16), 2, 18, 6, true, false, 1, 2); + } else if (id_ == 0x25) // Talking tree? + { + // TODO: Add something here? + } else if (id_ == 0x26) // Hardhat beetle + { + if ((x & 0x01) == 0x00) { + DrawSpriteTile((x * 16), (y * 16), 4, 20, 8); + DrawSpriteTile((x * 16), (y * 16) - 6, 0, 20, 8); + } else { + DrawSpriteTile((x * 16), (y * 16), 4, 20, 10); + DrawSpriteTile((x * 16), (y * 16) - 6, 0, 20, 10); + } + } else if (id_ == 0x27) // Deadrock + { + DrawSpriteTile((x * 16), (y * 16), 2, 30, 10); + } else if (id_ == 0x28) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x29) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2A) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2B) // ??? + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2C) // Lumberjack + { + DrawSpriteTile((x * 16) - 24, (y * 16) + 12, 6, 26, 12, true); // Body + DrawSpriteTile((x * 16) - 24, (y * 16), 8, 26, 12, true); // Head + + DrawSpriteTile((x * 16) - 14, (y * 16) + 12, 14, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) - 6, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 2, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 10, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 18, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 26, (y * 16) + 12, 15, 27, 10, false, false, 1, + 1); // Saw left edge + DrawSpriteTile((x * 16) + 34, (y * 16) + 12, 14, 27, 10, true, false, 1, + 1); // Saw left edge + + DrawSpriteTile((x * 16) + 40, (y * 16) + 12, 4, 26, 12); // Body + DrawSpriteTile((x * 16) + 40, (y * 16), 8, 26, 12); // Head + } else if (id_ == 0x2D) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2E) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x2F) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x30) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x31) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x32) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } + /* +else if (id_== 0x33) // Pull for rupees +{ + +} +*/ + else if (id_ == 0x34) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x35) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x36) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } + /* +else if (id_== 0x37) // Waterfall +{ +DrawSpriteTile((x*16), (y *16), 14, 6, 10); +} +*/ + else if (id_ == 0x38) // Arrowtarget + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x39) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3A) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3B) // Dash item + { + } else if (id_ == 0x3C) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3D) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3E) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x3F) // Npcs + { + DrawSpriteTile((x * 16), (y * 16), 14, 22, 10); + } else if (id_ == 0x40) // Lightning lock (agah tower) + { + DrawSpriteTile((x * 16) - 24, (y * 16), 10, 28, 2, false, false, 1, 2); + DrawSpriteTile((x * 16) - 16, (y * 16), 6, 30, 2); + DrawSpriteTile((x * 16), (y * 16), 8, 30, 2); + DrawSpriteTile((x * 16) + 16, (y * 16), 6, 30, 2); + DrawSpriteTile((x * 16) + 24, (y * 16), 10, 28, 2, false, false, 1, 2); + } else if (id_ == 0x41) // Blue soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 10); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 10, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 10); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 10, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 14, 22, 10, false, true, 1, + 2); // Sword + } else if (id_ == 0x42) // Green soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 12, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 12, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 14, 22, 12, false, true, 1, + 2); // Sword + } else if (id_ == 0x43) // Red spear soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 8, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 8); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 8, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 11, 22, 8, false, true, 1, + 2); // Spear + } else if (id_ == 0x44) // Sword blue holding up + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 10); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 10, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 14, 22, 10, false, true, 1, + 2); // Sword + } else if (id_ == 0x45) // Green spear soldier + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 12, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 13, 22, 12, false, false, 1, + 2); // Shield + DrawSpriteTile((x * 16) - 4, (y * 16) + 16, 11, 22, 12, false, true, 1, + 2); // Spear + } else if (id_ == 0x46) // Blue archer + { + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 10); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 6, 20, 10, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 10); // Head + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 16, 10, false, false, 1, + 1); // Bow1 + DrawSpriteTile((x * 16) + 8, (y * 16) + 16, 10, 16, 10, true, false, 1, + 1); // Bow2 + } else if (id_ == 0x47) // Green archer + { + DrawSpriteTile((x * 16), (y * 16) + 8, 14, 16, 12); + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 16, 12, false, false, 1, + 1); // Bow1 + DrawSpriteTile((x * 16) + 8, (y * 16) + 16, 10, 16, 12, true, false, 1, + 1); // Bow2 + } else if (id_ == 0x48) // Javelin soldier red + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 8); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 11, 22, 8, false, true, 1, + 2); // Sword + } else if (id_ == 0x49) // Javelin soldier red from bush + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 8); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 18, 8); // Head + DrawSpriteTile((x * 16), (y * 16) + 24, 0, 20, 2); + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 11, 22, 8, false, true, 1, + 2); // Sword + } else if (id_ == 0x4A) // Red bomb soldier + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 8); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 8, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8); // Head + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 14, 22, 11); // Bomb + } else if (id_ == 0x4B) // Green soldier recruit + { + // 0,4 + DrawSpriteTile((x * 16), (y * 16), 6, 24, 12); + DrawSpriteTile((x * 16), (y * 16) - 10, 0, 20, 12); + } else if (id_ == 0x4C) // Jazzhand + { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 14, false, false, 6, 2); + } else if (id_ == 0x4D) // Rabit?? + { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 12, false, false, 6, 2); + } else if (id_ == 0x4E) // Popo1 + { + DrawSpriteTile((x * 16), (y * 16), 0, 20, 10); + } else if (id_ == 0x4F) // Popo2 + { + DrawSpriteTile((x * 16), (y * 16), 2, 20, 10); + } else if (id_ == 0x50) // Canon ball + { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 10); + } else if (id_ == 0x51) // Armos + { + DrawSpriteTile((x * 16), (y * 16), 0, 28, 11, false, false, 2, 4); + } else if (id_ == 0x53) // Armos Knight + { + DrawSpriteTile((x * 16), (y * 16), 0, 28, 10, false, false, 4, 4); + } else if (id_ == 0x54) { + DrawSpriteTile((x * 16), (y * 16), 2, 28, 12); + DrawSpriteTile((x * 16) + 8, (y * 16) + 10, 6, 28, 12); + DrawSpriteTile((x * 16) + 16, (y * 16) + 18, 10, 28, 12); + } else if (id_ == 0x55) // Fireball Zora + { + DrawSpriteTile((x * 16), (y * 16), 4, 26, 11); + } else if (id_ == 0x56) // Zora + { + DrawSpriteTile((x * 16), (y * 16), 10, 20, 2); + DrawSpriteTile((x * 16), (y * 16) + 8, 8, 30, 2); + } else if (id_ == 0x57) // Desert Rocks + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 2, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16), 14, 24, 2, true, false, 2, 4); + } else if (id_ == 0x58) // Crab + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 12); + DrawSpriteTile((x * 16) + 16, (y * 16), 14, 24, 12, true); + } else if (id_ == 0x5B) // Spark + { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 4); + } else if (id_ == 0x5C) // Spark + { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 4, true); + } else if (id_ == 0x5D) // Roller vertical1 + { + // Subset3 + if (((y * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16) + 8 + (i * 16), (y * 16), 9, 24, 11); + } + + DrawSpriteTile((x * 16) + (16 * 7), (y * 16), 8, 24, 11, true); + } else { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 32, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 48, (y * 16), 8, 24, 11, true); + } + + } else if (id_ == 0x5E) // Roller vertical2 + { + // Subset3 + if (((y * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16) + 8 + (i * 16), (y * 16), 9, 24, 11); + } + + DrawSpriteTile((x * 16) + (16 * 7), (y * 16), 8, 24, 11, true); + } else { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 32, (y * 16), 9, 24, 11); + DrawSpriteTile((x * 16) + 48, (y * 16), 8, 24, 11, true); + } + } else if (id_ == 0x5F) // Roller horizontal + { + if (((x * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + 16, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 32, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 48, 14, 24, 11, false, true); + } else { + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16), (y * 16) + i * 16, 14, 25, 11); + } + + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + (7 * 16), 14, 24, 11, false, true); + } + } else if (id_ == 0x60) // Roller horizontal2 (right to left) + { + // Subset3 + if (((x * 16) & 0x10) == 0x10) { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + 16, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 32, 14, 25, 11); + DrawSpriteTile((x * 16), (y * 16) + 48, 14, 24, 11, false, true); + } else { + for (int i = 0; i < 7; i++) { + DrawSpriteTile((x * 16), (y * 16) + i * 16, 14, 25, 11); + } + + DrawSpriteTile((x * 16), (y * 16), 14, 24, 11); + DrawSpriteTile((x * 16), (y * 16) + (7 * 16), 14, 24, 11, false, true); + } + + } else if (id_ == 0x61) // Beamos + { + DrawSpriteTile((x * 16), (y * 16) - 16, 8, 20, 14, false, false, 2, 4); + DrawSpriteTile((x * 16) + 4, (y * 16) - 8, 10, 20, 14, false, false, 1, 1); + } else if (id_ == 0x63) // Devalant non-shooter + { + DrawSpriteTile((x * 16) - 8, (y * 16) - 8, 2, 16, 2); + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 2, 16, 2, true); + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 2, 16, 2, false, true); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 2, 16, 2, true, true); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0x64) // Devalant non-shooter + { + DrawSpriteTile((x * 16) - 8, (y * 16) - 8, 2, 16, 2); + DrawSpriteTile((x * 16) + 8, (y * 16) - 8, 2, 16, 2, true); + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 2, 16, 2, false, true); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 2, 16, 2, true, true); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 8); + } else if (id_ == 0x66) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 14, 16, 14, true); + } else if (id_ == 0x67) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 14, 16, 14); + } else if (id_ == 0x68) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 12, 16, 14); + } else if (id_ == 0x69) // Moving wall canon right + { + DrawSpriteTile((x * 16), (y * 16), 12, 16, 14, false, true); + } else if (id_ == 0x6A) // Chainball soldier + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 14); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 14, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 14); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) - 16, 10, 18, 14); // Ball + } else if (id_ == 0x6B) // Cannon soldier + { + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 6, 16, 14); + DrawSpriteTile((x * 16) - 4, (y * 16) + 8, 6, 20, 14, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 14); // Head + DrawSpriteTile((x * 16) + 12, (y * 16) + 8, 4, 18, 14); // Cannon + } else if (id_ == 0x6C) // Mirror portal + { + // Useless + } else if (id_ == 0x6D) // Rat + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 5); + } else if (id_ == 0x6E) // Rope + { + DrawSpriteTile((x * 16), (y * 16), 10, 26, 5); + } else if (id_ == 0x6F) { + DrawSpriteTile((x * 16), (y * 16), 4, 24, 10); + } else if (id_ == 0x70) // Helma fireball + { + DrawSpriteTile((x * 16), (y * 16), 10, 28, 4); + } else if (id_ == 0x71) // Leever + { + DrawSpriteTile((x * 16), (y * 16), 6, 16, 4); + } else if (id_ == 0x73) // Uncle priest + { + } else if (id_ == 0x79) // Bee + { + DrawSpriteTile((x * 16), (y * 16), 4, 14, 11, false, false, 1, 1); + } else if (id_ == 0x7A) { + DrawSpriteTile((x * 16), (y * 16) - 16, 2, 24, 12, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16) - 16, 2, 24, 12, true, false, 2, 4); + } else if (id_ == 0x7C) // Skull head + { + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0x7D) // Big spike + { + DrawSpriteTile((x * 16), (y * 16), 4, 28, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 4, 28, 11, true); + DrawSpriteTile((x * 16), (y * 16) + 16, 4, 28, 11, false, true); + DrawSpriteTile((x * 16) + 16, (y * 16) + 16, 4, 28, 11, true, true); + } else if (id_ == 0x7E) // Guruguru clockwise + { + DrawSpriteTile((x * 16), (y * 16) - 14, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 28, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 42, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 56, 8, 18, 4); + } else if (id_ == 0x7F) // Guruguru Counterclockwise + { + DrawSpriteTile((x * 16), (y * 16) - 14, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 28, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 42, 8, 18, 4); + DrawSpriteTile((x * 16), (y * 16) - 56, 8, 18, 4); + } else if (id_ == 0x80) // Winder (moving firebar) + { + DrawSpriteTile((x * 16), (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 14, (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 28, (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 42, (y * 16), 8, 18, 4); + DrawSpriteTile((x * 16) - 56, (y * 16), 8, 18, 4); + } else if (id_ == 0x81) // Water tektite + { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 11); + } else if (id_ == 0x82) // circle antifairy + { + // Antifairy top + DrawSpriteTile((x * 16 + 2) - 4, (y * 16 + 8) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 2) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) - 4, (y * 16 + 8) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 14) - 16, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 8) - 16, 1, 30, 5, false, false, + 1, 1); // Middle + // Left + DrawSpriteTile((x * 16 + 2) - 16, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 16, (y * 16 + 2) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) - 16, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 16, (y * 16 + 14) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 16, (y * 16 + 8) - 4, 1, 30, 5, false, false, + 1, 1); // Middle + + DrawSpriteTile((x * 16 + 2) - 4, (y * 16 + 8) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 2) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) - 4, (y * 16 + 8) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 14) + 8, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) - 4, (y * 16 + 8) + 8, 1, 30, 5, false, false, + 1, 1); // Middle + // Left + DrawSpriteTile((x * 16 + 2) + 8, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) + 8, (y * 16 + 2) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 14) + 8, (y * 16 + 8) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) + 8, (y * 16 + 14) - 4, 3, 30, 5, false, false, + 1, 1); + DrawSpriteTile((x * 16 + 8) + 8, (y * 16 + 8) - 4, 1, 30, 5, false, false, + 1, 1); // Middle + } else if (id_ == 0x83) // Green eyegore + { + DrawSpriteTile((x * 16), (y * 16), 12, 24, 14, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 24, 14, true, false, 1, 3); + } else if (id_ == 0x84) // Red eyegore + { + DrawSpriteTile((x * 16), (y * 16), 12, 24, 8, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 24, 8, true, false, 1, 3); + } else if (id_ == 0x85) // Yellow stalfos + { + DrawSpriteTile((x * 16), (y * 16), 10, 16, 11); + DrawSpriteTile((x * 16), (y * 16) - 12, 0, 16, 11); // Head + } else if (id_ == 0x86) // Kodongo + { + DrawSpriteTile((x * 16), (y * 16), 4, 26, 14); + } else if (id_ == 0x88) // Mothula + { + DrawSpriteTile((x * 16), (y * 16), 8, 24, 14, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16), 8, 24, 14, true, false, 2, 4); + } else if (id_ == 0x8A) // Spike + { + DrawSpriteTile((x * 16), (y * 16), 6, 30, 15); + } else if (id_ == 0x8B) // Gibdo + { + DrawSpriteTile((x * 16), (y * 16), 10, 24, 14); + DrawSpriteTile((x * 16), (y * 16) - 8, 0, 24, 14); + } else if (id_ == 0x8C) // Arrghus + { + DrawSpriteTile((x * 16), (y * 16), 0, 24, 14, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16), 0, 24, 14, true, false, 2, 4); + } else if (id_ == 0x8D) // Arrghus spawn + { + DrawSpriteTile((x * 16), (y * 16), 6, 24, 14); + } else if (id_ == 0x8E) // Terrorpin + { + DrawSpriteTile((x * 16), (y * 16), 14, 24, 12); + } else if (id_ == 0x8F) // Slime + { + DrawSpriteTile((x * 16), (y * 16), 0, 20, 12); + } else if (id_ == 0x90) // Wall master + { + DrawSpriteTile((x * 16), (y * 16), 6, 26, 12); + DrawSpriteTile((x * 16) + 16, (y * 16), 15, 26, 12, false, false, 1, 1); + DrawSpriteTile((x * 16) + 16, (y * 16) + 8, 9, 26, 12, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16) + 16, 10, 27, 12, false, false, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 16, 8, 27, 12, false, false, 1, 1); + } else if (id_ == 0x91) // Stalfos knight + { + DrawSpriteTile((x * 16) - 2, (y * 16) + 12, 4, 22, 12, false, false, 1, 2); + DrawSpriteTile((x * 16) + 10, (y * 16) + 12, 4, 22, 12, true, false, 1, 2); + DrawSpriteTile((x * 16) - 4, (y * 16) + 4, 1, 22, 12); + DrawSpriteTile((x * 16) + 12, (y * 16) + 4, 3, 22, 12, false, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16) - 8, 6, 20, 12); + } else if (id_ == 0x92) // Helmaking + { + DrawSpriteTile((x * 16), (y * 16) + 32, 14, 26, 14); + DrawSpriteTile((x * 16) + 16, (y * 16) + 32, 0, 28, 14); + DrawSpriteTile((x * 16) + 32, (y * 16) + 32, 14, 26, 14, true); + + DrawSpriteTile((x * 16), (y * 16) + 16 + 32, 2, 28, 14); + DrawSpriteTile((x * 16) + 16, (y * 16) + 16 + 32, 4, 28, 14); + DrawSpriteTile((x * 16) + 32, (y * 16) + 16 + 32, 2, 28, 14, true); + + DrawSpriteTile((x * 16) + 8, (y * 16) + 32 + 32, 6, 28, 14); + DrawSpriteTile((x * 16) + 24, (y * 16) + 32 + 32, 6, 28, 14, true); + } else if (id_ == 0x93) // Bumper + { + DrawSpriteTile((x * 16), (y * 16), 12, 30, 7); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 30, 7, true); + DrawSpriteTile((x * 16) + 16, (y * 16) + 16, 12, 30, 7, true, true); + DrawSpriteTile((x * 16), (y * 16) + 16, 12, 30, 7, false, true); + } else if (id_ == 0x95) // Right laser eye + { + DrawSpriteTile((x * 16), (y * 16), 9, 28, 3, true, false, 1, 2); + DrawSpriteTile((x * 16), (y * 16) + 16, 9, 28, 3, true, true, 1, 1); + } else if (id_ == 0x96) // Left laser eye + { + DrawSpriteTile((x * 16) + 8, (y * 16) - 4, 9, 28, 3, false, false, 1, 2); + DrawSpriteTile((x * 16) + 8, (y * 16) + 12, 9, 28, 3, false, true, 1, 1); + } else if (id_ == 0x97) // Right laser eye + { + DrawSpriteTile((x * 16), (y * 16), 6, 28, 3, false, false, 2, 1); + DrawSpriteTile((x * 16) + 16, (y * 16), 6, 28, 3, true, false, 1, 1); + } else if (id_ == 0x98) // Right laser eye + { + DrawSpriteTile((x * 16), (y * 16), 6, 28, 3, false, true, 2, 1); + DrawSpriteTile((x * 16) + 16, (y * 16), 6, 28, 3, true, true, 1, 1); + } else if (id_ == 0x99) { + DrawSpriteTile((x * 16), (y * 16), 6, 24, 12); + DrawSpriteTile((x * 16), (y * 16) - 8, 0, 24, 12); + } else if (id_ == 0x9A) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 10, 24, 6); + } else if (id_ == 0x9B) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 6, 24, 11); + DrawSpriteTile((x * 16), (y * 16) - 8, 2, 27, 11, false, false, 2, 1); + } else if (id_ == 0x9C) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 12, 22, 11); + DrawSpriteTile((x * 16) + 16, (y * 16), 13, 22, 11, false, false, 1, 2); + } else if (id_ == 0x9D) // Water bubble kyameron + { + DrawSpriteTile((x * 16), (y * 16), 14, 21, 11); + DrawSpriteTile((x * 16), (y * 16) - 16, 14, 20, 11, false, false, 2, 1); + } else if (id_ == 0xA1) { + DrawSpriteTile((x * 16) - 8, (y * 16) + 8, 6, 26, 14); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 6, 26, 14, true); + } else if (id_ == 0xA2) { + DrawSpriteTile((x * 16), (y * 16) + 8, 0, 24, 14, false, false, 4, 4); + } else if (id_ == 0xA5) { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 10, false, false, 3, 2); + DrawSpriteTile((x * 16) + 4, (y * 16) - 8, 0, 24, 10); + } else if (id_ == 0xA6) { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 8, false, false, 3, 2); + DrawSpriteTile((x * 16) + 4, (y * 16) - 8, 0, 24, 8); + } else if (id_ == 0xA7) { + DrawSpriteTile((x * 16), (y * 16) + 12, 12, 16, 10); + DrawSpriteTile((x * 16), (y * 16), 0, 16, 10); + } else if (id_ == 0xAC) { + DrawSpriteTile((x * 16), (y * 16), 5, 14, 4); + } else if (id_ == 0xAD) { + DrawSpriteTile((x * 16), (y * 16) + 8, 14, 10, 10); + DrawSpriteTile((x * 16), (y * 16), 12, 10, 10); + } else if (id_ == 0xBA) { + DrawSpriteTile((x * 16), (y * 16), 14, 14, 6); + } else if (id_ == 0xC1) { + DrawSpriteTile((x * 16), (y * 16) - 16, 2, 24, 12, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16) - 16, 2, 24, 12, true, false, 2, 4); + } else if (id_ == 0xC3) { + DrawSpriteTile((x * 16), (y * 16), 10, 14, 12); + } else if (id_ == 0xC4) { + DrawSpriteTile((x * 16), (y * 16), 0, 18, 14); + DrawSpriteTile((x * 16), (y * 16) - 8, 0, 16, 14); + } else if (id_ == 0xC5) { + } else if (id_ == 0xC6) { + DrawSpriteTile((x * 16) + 4, (y * 16) + 14, 3, 30, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) + 14, (y * 16) + 4, 3, 30, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) + 2, 1, 31, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) - 6, (y * 16) + 4, 3, 30, 14, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) - 6, 3, 30, 14, false, false, 1, 1); + } else if (id_ == 0xC7) { + DrawSpriteTile((x * 16), (y * 16), 0, 26, 4); + DrawSpriteTile((x * 16), (y * 16) - 10, 0, 26, 4); + DrawSpriteTile((x * 16), (y * 16) - 20, 0, 26, 4); + DrawSpriteTile((x * 16), (y * 16) - 30, 2, 26, 4); + } else if (id_ == 0xC8) { + DrawSpriteTile((x * 16), (y * 16), 12, 24, 12, false, false, 2, 3); + DrawSpriteTile((x * 16) + 16, (y * 16), 12, 24, 12, true, false, 1, 3); + } else if (id_ == 0xC9) { + DrawSpriteTile((x * 16), (y * 16), 8, 28, 8, false); + DrawSpriteTile((x * 16) + 16, (y * 16), 8, 28, 8, true); + } else if (id_ == 0xCA) { + DrawSpriteTile((x * 16), (y * 16), 8, 10, 10); + } else if (id_ == 0xD0) { + DrawSpriteTile((x * 16), (y * 16), 7, 14, 11, false, false, 3, 2); + DrawSpriteTile((x * 16), (y * 16) - 10, 8, 12, 11); + } else if (id_ == 0xD1) { + DrawSpriteTile((x * 16) + 2, (y * 16) + 8, 7, 13, 11, true, true, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 2, 7, 13, 11, true, false, 1, 1); + DrawSpriteTile((x * 16) + 14, (y * 16) + 8, 7, 13, 11, true, true, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 14, 7, 13, 11, false, true, 1, 1); + DrawSpriteTile((x * 16) + 8, (y * 16) + 8, 7, 13, 11, false, false, 1, + 1); // Middle + // 6,7 / 13 + } else if (id_ == 0xD4) { + DrawSpriteTile((x * 16) - 4, (y * 16), 0, 7, 7, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16), 0, 7, 7, true, false, 1, 1); + } else if (id_ == 0xE3) // Fairy + { + DrawSpriteTile((x * 16), (y * 16), 10, 14, 10); + } else if (id_ == 0xE4) // Key + { + DrawSpriteTile((x * 16), (y * 16), 11, 06, 11, false, false, 1, 2); + } else if (id_ == 0xE7) // Mushroom + { + DrawSpriteTile((x * 16), (y * 16), 14, 30, 16); + } else if (id_ == 0xE8) // Fake ms + { + DrawSpriteTile((x * 16) + 4, (y * 16), 4, 31, 10, false, false, 1, 1); + DrawSpriteTile((x * 16) + 4, (y * 16) + 8, 5, 31, 10, false, false, 1, 1); + } else if (id_ == 0xEB) { + DrawSpriteTile((x * 16), (y * 16), 0, 14, 5); + } else if (id_ == 0xF2) { + DrawSpriteTile((x * 16), (y * 16) - 16, 12, 24, 2, false, false, 2, 4); + DrawSpriteTile((x * 16) + 16, (y * 16) - 16, 12, 24, 2, true, false, 2, 4); + } else if (id_ == 0xF4) { + DrawSpriteTile((x * 16), (y * 16), 12, 28, 5, false, false, 4, 4); + } else { + // stringtodraw.Add(new SpriteName(x, (y *16), sprites_name.name[id])); + DrawSpriteTile((x * 16), (y * 16), 4, 4, 5); + } + + bounding_box_.x = (lowerX_ + (x * 16)); + bounding_box_.y = (lowerY_ + (y * 16)); + bounding_box_.w = width_; + bounding_box_.h = height_; +} + +void Sprite::DrawSpriteTile(int x, int y, int srcx, int srcy, int pal, + bool mirror_x, bool mirror_y, int sizex, int sizey, + bool iskey) { + x += 16; + y += 16; + int drawid_ = (srcx + (srcy * 16)) + 512; + for (auto yl = 0; yl < sizey * 8; yl++) { + for (auto xl = 0; xl < (sizex * 8) / 2; xl++) { + int mx = xl; + int my = yl; + + if (mirror_x) { + mx = (((sizex * 8) / 2) - 1) - xl; + } + if (mirror_y) { + my = (((sizey * 8)) - 1) - yl; + } + + // Formula information to get tile index position in the array + //((ID / nbrofXtiles) * (imgwidth/2) + (ID - ((ID/16)*16) )) + + int tx = ((drawid_ / 0x10) * 0x400) + + ((drawid_ - ((drawid_ / 0x10) * 0x10)) * 8); + auto pixel = current_gfx_[tx + (yl * 0x80) + xl]; + // nx,ny = object position, xx,yy = tile position, xl,yl = pixel + // position + int index = (x) + (y * 64) + (mx + (my * 0x80)); + + if (index >= 0 && index <= 4096) { + preview_gfx_[index] = (uchar)((pixel & 0x0F) + 112 + (pal * 8)); + } + } + } +} + +} // namespace zelda3 +} // namespace app +} // namespace yaze diff --git a/src/app/zelda3/sprite.h b/src/app/zelda3/sprite.h new file mode 100644 index 00000000..aeb3308e --- /dev/null +++ b/src/app/zelda3/sprite.h @@ -0,0 +1,68 @@ +#ifndef YAZE_APP_ZELDA3_SPRITE_H +#define YAZE_APP_ZELDA3_SPRITE_H + +#include + +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" +#include "app/gfx/bitmap.h" +#include "app/gfx/snes_tile.h" +#include "app/rom.h" + +namespace yaze { +namespace app { +namespace zelda3 { + +class Sprite { + public: + uchar x_, y_, id_; + uchar nx_, ny_; + uchar layer_ = 0; + uchar subtype_ = 0; + uchar overlord_ = 0; + std::string name_; + uchar keyDrop_ = 0; + int sizeMap_ = 512; + bool overworld_ = false; + bool preview_ = false; + uchar map_id_ = 0; + int map_x_ = 0; + int map_y_ = 0; + short room_id_ = 0; + bool picker_ = false; + bool selected_ = false; + SDL_Rect bounding_box_; + + Bytes current_gfx_; + Bytes preview_gfx_; + + int lowerX_ = 32; + int lowerY_ = 32; + int higherX_ = 0; + int higherY_ = 0; + int width_ = 16; + int height_ = 16; + + Sprite(Bytes src, uchar mapid, uchar id, uchar x, uchar y, int map_x, + int map_y); + void updateBBox(); + + void Draw(bool picker = false); + + void DrawSpriteTile(int x, int y, int srcx, int srcy, int pal, + bool mirror_x = false, bool mirror_y = false, + int sizex = 2, int sizey = 2, bool iskey = false); + + auto PreviewGraphics() { return preview_gfx_; } +}; + +} // namespace zelda3 +} // namespace app +} // namespace yaze + +#endif \ No newline at end of file diff --git a/src/app/zelda3/screen.cc b/src/app/zelda3/title_screen.cc similarity index 85% rename from src/app/zelda3/screen.cc rename to src/app/zelda3/title_screen.cc index 2f408835..7553ca77 100644 --- a/src/app/zelda3/screen.cc +++ b/src/app/zelda3/title_screen.cc @@ -1,4 +1,4 @@ -#include "screen.h" +#include "title_screen.h" #include @@ -11,7 +11,7 @@ namespace yaze { namespace app { namespace zelda3 { -void Screen::Create() { +void TitleScreen::Create() { tiles8Bitmap.Create(128, 512, 8, 0x20000); tilesBG1Bitmap.Create(256, 256, 8, 0x80000); tilesBG2Bitmap.Create(256, 256, 8, 0x80000); @@ -20,12 +20,9 @@ void Screen::Create() { BuildTileset(); LoadTitleScreen(); - LoadOverworldMap(); - LoadDungeonMaps(); - LoadAllMapIcons(); } -void Screen::BuildTileset() { +void TitleScreen::BuildTileset() { uchar staticgfx[16]; // Main Blocksets @@ -66,7 +63,7 @@ void Screen::BuildTileset() { } } -void Screen::LoadTitleScreen() { +void TitleScreen::LoadTitleScreen() { int pos = (rom_[0x138C + 3] << 16) + (rom_[0x1383 + 3] << 8) + rom_[0x137A + 3]; @@ -127,14 +124,6 @@ void Screen::LoadTitleScreen() { pal_selected_ = 2; } -void Screen::LoadNamingScreen() {} - -void Screen::LoadOverworldMap() {} - -void Screen::LoadDungeonMaps() {} - -void Screen::LoadAllMapIcons() {} - } // namespace zelda3 } // namespace app } // namespace yaze \ No newline at end of file diff --git a/src/app/zelda3/screen.h b/src/app/zelda3/title_screen.h similarity index 94% rename from src/app/zelda3/screen.h rename to src/app/zelda3/title_screen.h index a8d92a0d..4cade272 100644 --- a/src/app/zelda3/screen.h +++ b/src/app/zelda3/title_screen.h @@ -12,17 +12,13 @@ namespace yaze { namespace app { namespace zelda3 { -class Screen { +class TitleScreen { public: void Create(); private: void BuildTileset(); void LoadTitleScreen(); - void LoadNamingScreen(); - void LoadOverworldMap(); - void LoadDungeonMaps(); - void LoadAllMapIcons(); int sword_x_ = 0; int mx_click_ = 0; diff --git a/src/gui/canvas.cc b/src/gui/canvas.cc index eaf7f7c5..e97f2a25 100644 --- a/src/gui/canvas.cc +++ b/src/gui/canvas.cc @@ -96,12 +96,14 @@ void Canvas::DrawTilesFromUser(app::ROM &rom, Bytes &tile, } } -void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset) { - draw_list_->AddImage( - (void *)bitmap.GetTexture(), - ImVec2(canvas_p0_.x + border_offset, canvas_p0_.y + border_offset), - ImVec2(canvas_p0_.x + (bitmap.GetWidth() * 2), - canvas_p0_.y + (bitmap.GetHeight() * 2))); +void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset, bool ready) { + if (ready) { + draw_list_->AddImage( + (void *)bitmap.GetTexture(), + ImVec2(canvas_p0_.x + border_offset, canvas_p0_.y + border_offset), + ImVec2(canvas_p0_.x + (bitmap.GetWidth() * 2), + canvas_p0_.y + (bitmap.GetHeight() * 2))); + } } void Canvas::DrawBitmap(const Bitmap &bitmap, int x_offset, int y_offset) { @@ -121,6 +123,15 @@ void Canvas::DrawOutline(int x, int y, int w, int h) { draw_list_->AddRect(origin, size, IM_COL32(255, 255, 255, 255)); } +void Canvas::DrawRect(int x, int y, int w, int h, ImVec4 color) { + ImVec2 origin(canvas_p0_.x + scrolling_.x + x, + canvas_p0_.y + scrolling_.y + y); + ImVec2 size(canvas_p0_.x + scrolling_.x + x + w, + canvas_p0_.y + scrolling_.y + y + h); + draw_list_->AddRectFilled(origin, size, + IM_COL32(color.x, color.y, color.z, color.w)); +} + void Canvas::DrawText(std::string text, int x, int y) { draw_list_->AddText( ImVec2(canvas_p0_.x + scrolling_.x + x, canvas_p0_.y + scrolling_.y + y), diff --git a/src/gui/canvas.h b/src/gui/canvas.h index 341cab0f..d7be46b6 100644 --- a/src/gui/canvas.h +++ b/src/gui/canvas.h @@ -24,9 +24,11 @@ class Canvas { void DrawContextMenu(); void DrawTilesFromUser(app::ROM& rom, Bytes& tile, app::gfx::SNESPalette& pal); - void DrawBitmap(const Bitmap& bitmap, int border_offset = 0); + void DrawBitmap(const Bitmap& bitmap, int border_offset = 0, + bool ready = true); void DrawBitmap(const Bitmap& bitmap, int x_offset, int y_offset); void DrawOutline(int x, int y, int w, int h); + void DrawRect(int x, int y, int w, int h, ImVec4 color); void DrawText(std::string text, int x, int y); void DrawGrid(float grid_step = 64.0f); void DrawOverlay(); // last