diff --git a/src/app/core/constants.h b/src/app/core/constants.h index d6ebdc78..fa279b7f 100644 --- a/src/app/core/constants.h +++ b/src/app/core/constants.h @@ -252,7 +252,7 @@ constexpr int blocks_pointer4 = 0x15B0F; constexpr int torch_data = 0x2736A; // JP 0x2704A constexpr int torches_length_pointer = 0x88C1; -constexpr int sprite_blockset_pointer = 0x5B57; +constexpr int kSpriteBlocksetPointer = 0x5B57; constexpr int sprites_data = 0x4D8B0; // It use the unused pointers to have more space //Save purpose constexpr int sprites_data_empty_room = 0x4D8AE; diff --git a/src/app/editor/overworld_editor.cc b/src/app/editor/overworld_editor.cc index e1962cef..9e25b80b 100644 --- a/src/app/editor/overworld_editor.cc +++ b/src/app/editor/overworld_editor.cc @@ -117,7 +117,9 @@ void OverworldEditor::DrawToolset() { ImGui::TableNextColumn(); if (ImGui::Button(ICON_MD_UPDATE)) { - overworld_.Load(rom_); + overworld_.Load(rom_, tile16_blockset_bmp_.GetData(), + current_gfx_bmp_.GetData()); + tile16_blockset_bmp_.CreateTexture(rom_.Renderer()); } ImGui::TableNextColumn(); @@ -192,101 +194,60 @@ void OverworldEditor::DrawOverworldMapSettings() { void OverworldEditor::DrawOverworldCanvas() { DrawOverworldMapSettings(); ImGui::Separator(); - overworld_map_canvas_.Update(); + overworld_map_canvas_.DrawBackground(); + overworld_map_canvas_.UpdateContext(); + overworld_map_canvas_.DrawGrid(64.f); + overworld_map_canvas_.DrawOverlay(); } void OverworldEditor::DrawTileSelector() { if (ImGui::BeginTabBar("##TabBar", ImGuiTabBarFlags_FittingPolicyScroll)) { - if (ImGui::BeginTabItem("Tile16")) { - bool child_is_visible = - ImGui::BeginChild("#Tile16Child", ImGui::GetContentRegionAvail(), - true, ImGuiWindowFlags_AlwaysVerticalScrollbar); - if (child_is_visible) DrawTile16Selector(); - - ImGui::EndChild(); - ImGui::EndTabItem(); - } if (ImGui::BeginTabItem("Tile8")) { ImGuiID child_id = ImGui::GetID((void *)(intptr_t)1); - bool child_is_visible = - ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true, - ImGuiWindowFlags_AlwaysVerticalScrollbar); - if (child_is_visible) { + if (ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true, + ImGuiWindowFlags_AlwaysVerticalScrollbar)) { DrawTile8Selector(); } ImGui::EndChild(); ImGui::EndTabItem(); } - if (ImGui::BeginTabItem("VRAM")) { - DrawPseudoVRAM(); + if (ImGui::BeginTabItem("Tile16")) { + if (ImGui::BeginChild("#Tile16Child", ImGui::GetContentRegionAvail(), + true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) { + DrawTile16Selector(); + } + ImGui::EndChild(); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Current Graphics")) { + DrawAreaGraphics(); ImGui::EndTabItem(); } ImGui::EndTabBar(); } } -void OverworldEditor::DrawTile16Selector() const { - static ImVec2 scrolling(0.0f, 0.0f); - ImVec2 canvas_p0 = ImGui::GetCursorScreenPos(); - auto canvas_sz = ImVec2(256 + 1, kNumSheetsToLoad * 64 + 1); - auto canvas_p1 = ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y); - - // Draw border and background color - const ImGuiIO &io = ImGui::GetIO(); - ImDrawList *draw_list = ImGui::GetWindowDrawList(); - draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(32, 32, 32, 255)); - draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255)); - - // This will catch our interactions - ImGui::InvisibleButton( - "Tile16SelectorCanvas", canvas_sz, - ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight); - const ImVec2 origin(canvas_p0.x + scrolling.x, - canvas_p0.y + scrolling.y); // Lock scrolled origin - const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x, - io.MousePos.y - origin.y); - - // Context menu (under default mouse threshold) - ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right); - if (drag_delta.x == 0.0f && drag_delta.y == 0.0f) - ImGui::OpenPopupOnItemClick("contextTile16", - ImGuiPopupFlags_MouseButtonRight); - if (ImGui::BeginPopup("context")) { - ImGui::EndPopup(); - } - +void OverworldEditor::DrawTile16Selector() { + blockset_canvas_.DrawBackground(ImVec2(256 + 1, kNumSheetsToLoad * 64 + 1)); + blockset_canvas_.UpdateContext(); if (map_blockset_loaded_) { - draw_list->AddImage( + blockset_canvas_.GetDrawList()->AddImage( (void *)tile16_blockset_bmp_.GetTexture(), - ImVec2(canvas_p0.x + 2, canvas_p0.y + 2), - ImVec2(canvas_p0.x + (tile16_blockset_bmp_.GetWidth() * 2), - canvas_p0.y + (tile16_blockset_bmp_.GetHeight() * 2))); + ImVec2(blockset_canvas_.GetZeroPoint().x + 2, + blockset_canvas_.GetZeroPoint().y + 2), + ImVec2(blockset_canvas_.GetZeroPoint().x + + (tile16_blockset_bmp_.GetWidth() * 2), + blockset_canvas_.GetZeroPoint().y + + (tile16_blockset_bmp_.GetHeight() * 2))); } - - // Draw grid + all lines in the canvas - draw_list->PushClipRect(canvas_p0, canvas_p1, true); - if (opt_enable_grid) { - const float GRID_STEP = 32.0f; - for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; - x += GRID_STEP) - draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), - ImVec2(canvas_p0.x + x, canvas_p1.y), - IM_COL32(200, 200, 200, 40)); - for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; - y += GRID_STEP) - draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), - ImVec2(canvas_p1.x, canvas_p0.y + y), - IM_COL32(200, 200, 200, 40)); - } - - draw_list->PopClipRect(); + blockset_canvas_.DrawGrid(32.0f); + blockset_canvas_.DrawOverlay(); } void OverworldEditor::DrawTile8Selector() { graphics_bin_canvas_.DrawBackground( ImVec2(256 + 1, kNumSheetsToLoad * 64 + 1)); graphics_bin_canvas_.UpdateContext(); - graphics_bin_canvas_.DrawGrid(16.0f); if (all_gfx_loaded_) { for (const auto &[key, value] : graphics_bin_) { int offset = 64 * (key + 1); @@ -301,32 +262,33 @@ void OverworldEditor::DrawTile8Selector() { graphics_bin_canvas_.GetZeroPoint().y + offset)); } } + graphics_bin_canvas_.DrawGrid(16.0f); graphics_bin_canvas_.DrawOverlay(); } -void OverworldEditor::DrawPseudoVRAM() { - if (!vram_loaded_ && rom_.isLoaded()) { - // rom_.GetVRAM().ChangeGraphicsTileset( - // gfx::CreateGraphicsSet(0, rom_.GetGraphicsBin())); - // for (int tileset_index = 0; tileset_index < 16; tileset_index++) { - // rom_.GetVRAM().GetTileset(tileset_index); - // } +void OverworldEditor::DrawAreaGraphics() { + if (rom_.isLoaded()) { + // TODO } - pseudo_vram_canvas_.DrawBackground(); - pseudo_vram_canvas_.UpdateContext(); - pseudo_vram_canvas_.DrawGrid(); - pseudo_vram_canvas_.GetDrawList()->AddImage( - (void *)rom_.GetVRAM().GetTileset(0).GetTexture(), - ImVec2(pseudo_vram_canvas_.GetZeroPoint().x + 2, - pseudo_vram_canvas_.GetZeroPoint().y + 2), - ImVec2(pseudo_vram_canvas_.GetZeroPoint().x + 256, - pseudo_vram_canvas_.GetZeroPoint().y + 64)); - pseudo_vram_canvas_.DrawOverlay(); + current_gfx_canvas_.DrawBackground(); + current_gfx_canvas_.UpdateContext(); + current_gfx_canvas_.DrawGrid(); + current_gfx_canvas_.GetDrawList()->AddImage( + (void *)current_gfx_bmp_.GetTexture(), + ImVec2(current_gfx_canvas_.GetZeroPoint().x + 2, + current_gfx_canvas_.GetZeroPoint().y + 2), + ImVec2( + current_gfx_canvas_.GetZeroPoint().x + current_gfx_bmp_.GetWidth(), + current_gfx_canvas_.GetZeroPoint().y + current_gfx_bmp_.GetHeight())); + current_gfx_canvas_.DrawOverlay(); } void OverworldEditor::LoadGraphics() { rom_.LoadAllGraphicsData(); graphics_bin_ = rom_.GetGraphicsBin(); + + tile16_blockset_bmp_.Create(128, 8192, 8, 1048576); + current_gfx_bmp_.Create(128, 512, 8, 32768); } } // namespace editor diff --git a/src/app/editor/overworld_editor.h b/src/app/editor/overworld_editor.h index e032340c..8ef676af 100644 --- a/src/app/editor/overworld_editor.h +++ b/src/app/editor/overworld_editor.h @@ -34,9 +34,9 @@ class OverworldEditor { void DrawOverworldMapSettings(); void DrawOverworldCanvas(); void DrawTileSelector(); - void DrawTile16Selector() const; + void DrawTile16Selector(); void DrawTile8Selector(); - void DrawPseudoVRAM(); + void DrawAreaGraphics(); void LoadBlockset(); void LoadGraphics(); @@ -53,7 +53,6 @@ class OverworldEditor { bool opt_enable_grid = true; bool all_gfx_loaded_ = false; bool map_blockset_loaded_ = false; - bool vram_loaded_ = false; std::unordered_map all_texture_sheet_; std::unordered_map graphics_bin_; @@ -67,7 +66,8 @@ class OverworldEditor { gfx::Bitmap all_gfx_bmp; // pointer size 456704 gui::Canvas overworld_map_canvas_; - gui::Canvas pseudo_vram_canvas_; + gui::Canvas current_gfx_canvas_; + gui::Canvas blockset_canvas_; gui::Canvas graphics_bin_canvas_; ImVec4 current_palette_[8]; diff --git a/src/app/zelda3/overworld.cc b/src/app/zelda3/overworld.cc index 6d28326a..cfd7fe1c 100644 --- a/src/app/zelda3/overworld.cc +++ b/src/app/zelda3/overworld.cc @@ -7,9 +7,8 @@ namespace yaze { namespace app { namespace zelda3 { -void Overworld::Load(ROM &rom) { +void Overworld::Load(ROM &rom, uchar *ow_blockset, uchar *current_gfx) { rom_ = rom; - //mapblockset16.Create(128, 8192, 8, 1048576); AssembleMap32Tiles(); AssembleMap16Tiles(); @@ -24,7 +23,8 @@ void Overworld::Load(ROM &rom) { auto size = tiles16.size(); for (int i = 0; i < core::NumberOfOWMaps; i++) { - overworld_maps_[i].BuildMap(size, game_state_, map_parent_, map_tiles_); + overworld_maps_[i].BuildMap(size, game_state_, map_parent_, ow_blockset, + current_gfx, map_tiles_); } is_loaded_ = true; diff --git a/src/app/zelda3/overworld.h b/src/app/zelda3/overworld.h index adf4998a..8caa958f 100644 --- a/src/app/zelda3/overworld.h +++ b/src/app/zelda3/overworld.h @@ -20,7 +20,7 @@ namespace zelda3 { class Overworld { public: - void Load(ROM &rom); + void Load(ROM &rom, uchar *ow_blockset, uchar *current_gfx); auto GetTiles16() const { return tiles16; } private: @@ -49,7 +49,6 @@ class Overworld { ROM rom_; OWMapTiles map_tiles_; - gfx::Bitmap tile16_blockset_bmp_; gfx::Bitmap current_gfx_bmp_; gfx::Bitmap overworld_map_bmp_; diff --git a/src/app/zelda3/overworld_map.cc b/src/app/zelda3/overworld_map.cc index 6db47d33..0431f0f3 100644 --- a/src/app/zelda3/overworld_map.cc +++ b/src/app/zelda3/overworld_map.cc @@ -19,16 +19,16 @@ namespace zelda3 { OverworldMap::OverworldMap(int index, ROM& rom, const std::vector& tiles16) : parent_(index), index_(index), rom_(rom), tiles16_(tiles16) { - if (index_ != 0x80 && index_ <= 150 && - rom_.data()[core::overworldMapSize + (index_ & 0x3F)] != 0) { - large_map_ = true; - } LoadAreaInfo(); + bitmap_.Create(512, 512, 8, 512 * 512); } void OverworldMap::LoadAreaInfo() { auto z3data = rom_.data(); - + if (index_ != 0x80 && index_ <= 150 && + rom_.data()[core::overworldMapSize + (index_ & 0x3F)] != 0) { + large_map_ = true; + } if (index_ < 64) { area_graphics_ = z3data[core::mapGfx + parent_]; area_palette_ = z3data[core::overworldMapPalette + parent_]; @@ -85,8 +85,8 @@ void OverworldMap::LoadAreaInfo() { } else if (index_ == 0x88) { area_graphics_ = 81; area_palette_ = 0; - } else // pyramid bg use 0x5B map - { + } else { + // pyramid bg use 0x5B map area_graphics_ = z3data[core::mapGfx + parent_]; area_palette_ = z3data[core::overworldMapPalette + parent_]; } @@ -101,9 +101,12 @@ void OverworldMap::LoadAreaInfo() { sprite_palette_[1] = z3data[core::overworldSpritePalette + parent_ + 128]; sprite_palette_[2] = z3data[core::overworldSpritePalette + parent_ + 128]; } + + std::cout << "Loading header for overworld area #" << index_ << std::endl; } void OverworldMap::BuildMap(int count, int game_state, uchar* map_parent, + uchar* ow_blockset, uchar* current_gfx, OWMapTiles& map_tiles) { if (large_map_) { parent_ = map_parent[index_]; @@ -124,8 +127,8 @@ void OverworldMap::BuildMap(int count, int game_state, uchar* map_parent, } } - BuildTileset(game_state); - BuildTiles16Gfx(count); // build on GFX.mapgfx16Ptr + BuildTileset(game_state, current_gfx); + BuildTiles16Gfx(count, ow_blockset); // build on GFX.mapgfx16Ptr int world = 0; if (index_ < 64) { @@ -142,13 +145,16 @@ void OverworldMap::BuildMap(int count, int game_state, uchar* map_parent, int superX = index_ - (world * 64) - (superY * 8); for (int y = 0; y < 32; y++) { for (int x = 0; x < 32; x++) { - CopyTile8bpp16((x * 16), (y * 16), - tiles_used_[x + (superX * 32)][y + (superY * 32)], gfxPtr); + auto xt = x + (superX * 32); + auto yt = y + (superY * 32); + CopyTile8bpp16((x * 16), (y * 16), tiles_used_[xt][yt], ow_blockset); } } + + std::cout << "Finished building overworld map #" << index_ << std::endl; } -void OverworldMap::BuildTileset(int gameState) { +void OverworldMap::BuildTileset(int game_state, uchar* current_gfx) { int index_world = 0x20; if (parent_ < 0x40) { index_world = 0x20; @@ -165,9 +171,9 @@ void OverworldMap::BuildTileset(int gameState) { static_graphics_[11] = 115 + 7; for (int i = 0; i < 4; i++) { static_graphics_[12 + i] = - (uchar)(rom_.data()[core::sprite_blockset_pointer + - (sprite_graphics_[gameState] * 4) + i] + - 115); + (rom_.data()[core::kSpriteBlocksetPointer + + (sprite_graphics_[game_state] * 4) + i] + + 115); } // Main Blocksets @@ -204,7 +210,7 @@ void OverworldMap::BuildTileset(int gameState) { static_graphics_[7] = 91; } - uchar* current_map_gfx_tile8_data = rom_.GetVRAM().GetGraphicsData(); + uchar* current_map_gfx_tile8_data = current_gfx; uchar const* all_gfx_data = rom_.GetMasterGraphicsBin(); for (int i = 0; i < 16; i++) { @@ -224,9 +230,9 @@ void OverworldMap::BuildTileset(int gameState) { } } -void OverworldMap::BuildTiles16Gfx(int count) { - auto gfx_tile16_data = tile16_blockset_bmp_.GetData(); - auto gfx_tile8_data = rom_.GetVRAM().GetGraphicsData(); +void OverworldMap::BuildTiles16Gfx(int count, uchar* ow_blockset) { + auto gfx_tile16_data = ow_blockset; + auto gfx_tile8_data = rom_.GetMasterGraphicsBin(); int offsets[] = {0, 8, 1024, 1032}; auto yy = 0; @@ -282,6 +288,24 @@ void OverworldMap::CopyTile(int x, int y, int xx, int yy, int offset, gfx16Pointer[index + r] = (uchar)(((pixel >> 4) & 0x0F) + tile.palette_ * 16); } +void OverworldMap::CopyTile8bpp16(int x, int y, int tile, uchar* ow_blockset) { + // (sourceX * 16) + (sourceY * 128) + int source_ptr_pos = ((tile - ((tile / 8) * 8)) * 16) + ((tile / 8) * 2048); + auto source_ptr = ow_blockset; + + int dest_ptr_pos = (x + (y * 512)); + auto dest_ptr = bitmap_.GetData(); + + for (int ystrip = 0; ystrip < 16; ystrip++) { + for (int xstrip = 0; xstrip < 16; xstrip++) { + dest_ptr[dest_ptr_pos + xstrip + (ystrip * 512)] = + source_ptr[source_ptr_pos + xstrip + (ystrip * 128)]; + } + } +} + +// EXPERIMENTAL ---------------------------------------------------------------- + // map,current void OverworldMap::CopyTileToMap(int x, int y, int xx, int yy, int offset, gfx::TileInfo tile, uchar* gfx16Pointer, @@ -307,26 +331,10 @@ void OverworldMap::CopyTileToMap(int x, int y, int xx, int yy, int offset, gfx16Pointer[index + r] = (uchar)(((pixel >> 4) & 0x0F) + tile.palette_ * 16); } -void OverworldMap::CopyTile8bpp16(int x, int y, int tile, uchar* destbmpPtr) { - // (sourceX * 16) + (sourceY * 128) - int source_ptr_pos = ((tile - ((tile / 8) * 8)) * 16) + ((tile / 8) * 2048); - auto source_ptr = tile16_blockset_bmp_.GetData(); - - int dest_ptr_pos = (x + (y * 512)); - auto dest_ptr = destbmpPtr; - - for (int ystrip = 0; ystrip < 16; ystrip++) { - for (int xstrip = 0; xstrip < 16; xstrip++) { - dest_ptr[dest_ptr_pos + xstrip + (ystrip * 512)] = - source_ptr[source_ptr_pos + xstrip + (ystrip * 128)]; - } - } -} - void OverworldMap::CopyTile8bpp16From8(int xP, int yP, int tileID, - uchar* destbmpPtr) { - auto gfx_tile16_data = destbmpPtr; - auto gfx_tile8_data = rom_.GetVRAM().GetGraphicsData(); + uchar* current_gfx) { + auto gfx_tile16_data = rom_.GetMasterGraphicsBin(); + auto gfx_tile8_data = current_gfx; auto tiles = tiles16_[tileID]; diff --git a/src/app/zelda3/overworld_map.h b/src/app/zelda3/overworld_map.h index 83cff996..ba2bef18 100644 --- a/src/app/zelda3/overworld_map.h +++ b/src/app/zelda3/overworld_map.h @@ -20,21 +20,25 @@ class OverworldMap { public: OverworldMap(int index, ROM& rom, const std::vector& tiles16); void BuildMap(int count, int game_state, uchar* map_parent, - OWMapTiles& map_tiles); + uchar* ow_blockset, uchar* current_gfx, OWMapTiles& map_tiles); auto SetLargeMap(bool is_set) { large_map_ = is_set; } auto IsLargeMap() { return large_map_; } + auto GetBitmap() { return bitmap_; } private: void LoadAreaInfo(); - void BuildTileset(int gameState); - void BuildTiles16Gfx(int count); + void BuildTileset(int game_state, uchar* current_gfx); + void BuildTiles16Gfx(int count, uchar* ow_blockset); + void CopyTile(int x, int y, int xx, int yy, int offset, gfx::TileInfo tile, uchar* gfx16Pointer, uchar* gfx8Pointer); + + void CopyTile8bpp16(int x, int y, int tile, uchar* ow_blockset); + void CopyTileToMap(int x, int y, int xx, int yy, int offset, gfx::TileInfo tile, uchar* gfx16Pointer, uchar* gfx8Pointer); - void CopyTile8bpp16(int x, int y, int tile, uchar* destbmpPtr); void CopyTile8bpp16From8(int xP, int yP, int tileID, uchar* destbmpPtr); int parent_ = 0; @@ -47,6 +51,7 @@ class OverworldMap { uchar sprite_palette_[3]; uchar area_music_[4]; uchar static_graphics_[16]; + gfx::Bitmap bitmap_; uchar* gfxPtr = new uchar[512 * 512]; bool initialized_ = false; @@ -56,7 +61,6 @@ class OverworldMap { std::vector> tiles_used_; ROM rom_; - gfx::Bitmap tile16_blockset_bmp_; // psuedo vram? }; } // namespace zelda3