Add Object selector to DungeonEditor
Loads current room gfx from ROM gfx buffer
This commit is contained in:
@@ -8,6 +8,24 @@ namespace editor {
|
|||||||
|
|
||||||
void DungeonEditor::Update() {
|
void DungeonEditor::Update() {
|
||||||
DrawToolset();
|
DrawToolset();
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
if (ImGui::BeginTable("#DungeonEditTable", 2, toolset_table_flags_,
|
||||||
|
ImVec2(0, 0))) {
|
||||||
|
ImGui::TableSetupColumn("Canvas", ImGuiTableColumnFlags_WidthStretch,
|
||||||
|
ImGui::GetContentRegionAvail().x);
|
||||||
|
ImGui::TableSetupColumn("Object Selector");
|
||||||
|
ImGui::TableHeadersRow();
|
||||||
|
ImGui::TableNextRow();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
DrawDungeonCanvas();
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
DrawTileSelector();
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DungeonEditor::DrawDungeonCanvas() {
|
||||||
canvas_.DrawBackground();
|
canvas_.DrawBackground();
|
||||||
canvas_.DrawContextMenu();
|
canvas_.DrawContextMenu();
|
||||||
canvas_.DrawGrid();
|
canvas_.DrawGrid();
|
||||||
@@ -56,6 +74,30 @@ void DungeonEditor::DrawToolset() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DungeonEditor::DrawRoomGraphics() {
|
||||||
|
room_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 0x10 * 0x40 + 1));
|
||||||
|
room_gfx_canvas_.DrawContextMenu();
|
||||||
|
room_gfx_canvas_.DrawTileSelector(32);
|
||||||
|
room_gfx_canvas_.DrawBitmap(room_gfx_bmp_, 2, is_loaded_);
|
||||||
|
room_gfx_canvas_.DrawGrid(32.0f);
|
||||||
|
room_gfx_canvas_.DrawOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DungeonEditor::DrawTileSelector() {
|
||||||
|
if (ImGui::BeginTabBar("##TabBar", ImGuiTabBarFlags_FittingPolicyScroll)) {
|
||||||
|
if (ImGui::BeginTabItem("Room Graphics")) {
|
||||||
|
if (ImGuiID child_id = ImGui::GetID((void *)(intptr_t)3);
|
||||||
|
ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
|
||||||
|
ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
|
||||||
|
DrawRoomGraphics();
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
ImGui::EndTabBar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include "gui/canvas.h"
|
#include "gui/canvas.h"
|
||||||
#include "gui/icons.h"
|
#include "gui/icons.h"
|
||||||
|
#include "rom.h"
|
||||||
|
#include "zelda3/dungeon/room.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
@@ -16,7 +18,18 @@ class DungeonEditor {
|
|||||||
private:
|
private:
|
||||||
void DrawToolset();
|
void DrawToolset();
|
||||||
|
|
||||||
|
void DrawDungeonCanvas();
|
||||||
|
void DrawRoomGraphics();
|
||||||
|
void DrawTileSelector();
|
||||||
|
|
||||||
|
bool is_loaded_ = false;
|
||||||
|
|
||||||
|
gfx::Bitmap room_gfx_bmp_;
|
||||||
|
|
||||||
|
std::vector<zelda3::dungeon::Room> rooms_;
|
||||||
|
|
||||||
gui::Canvas canvas_;
|
gui::Canvas canvas_;
|
||||||
|
gui::Canvas room_gfx_canvas_;
|
||||||
ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit;
|
ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit;
|
||||||
};
|
};
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
|
|||||||
@@ -80,6 +80,8 @@ class Bitmap {
|
|||||||
std::shared_ptr<SDL_Surface> surface_ = nullptr;
|
std::shared_ptr<SDL_Surface> surface_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using BitmapTable = std::unordered_map<int, gfx::Bitmap>;
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -99,15 +99,13 @@ class ROM {
|
|||||||
void Write(int addr, int value);
|
void Write(int addr, int value);
|
||||||
void WriteShort(int addr, int value);
|
void WriteShort(int addr, int value);
|
||||||
|
|
||||||
void RenderBitmap(gfx::Bitmap* bitmap) const;
|
|
||||||
|
|
||||||
absl::Status ApplyAssembly(const absl::string_view& filename,
|
absl::Status ApplyAssembly(const absl::string_view& filename,
|
||||||
size_t patch_size);
|
size_t patch_size);
|
||||||
absl::Status PatchOverworldMosaic(char mosaic_tiles[core::kNumOverworldMaps],
|
absl::Status PatchOverworldMosaic(char mosaic_tiles[core::kNumOverworldMaps],
|
||||||
int routine_offset);
|
int routine_offset);
|
||||||
|
|
||||||
auto GetTitle() const { return title; }
|
auto GetTitle() const { return title; }
|
||||||
auto GetGraphicsBin() const { return graphics_bin_; }
|
gfx::BitmapTable GetGraphicsBin() const { return graphics_bin_; }
|
||||||
auto GetGraphicsBuffer() const { return graphics_buffer_; }
|
auto GetGraphicsBuffer() const { return graphics_buffer_; }
|
||||||
auto GetPaletteGroup(std::string group) { return palette_groups_[group]; }
|
auto GetPaletteGroup(std::string group) { return palette_groups_[group]; }
|
||||||
void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer) {
|
void SetupRenderer(std::shared_ptr<SDL_Renderer> renderer) {
|
||||||
@@ -140,17 +138,23 @@ class ROM {
|
|||||||
return (ushort)((rom_data_[offset + 1]) << 8) | rom_data_[offset];
|
return (ushort)((rom_data_[offset + 1]) << 8) | rom_data_[offset];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderBitmap(gfx::Bitmap* bitmap) const {
|
||||||
|
bitmap->CreateTexture(renderer_);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long size_ = 0;
|
long size_ = 0;
|
||||||
uchar title[21] = "ROM Not Loaded";
|
uchar title[21] = "ROM Not Loaded";
|
||||||
bool is_loaded_ = false;
|
|
||||||
bool isbpp3[223];
|
bool isbpp3[223];
|
||||||
|
bool is_loaded_ = false;
|
||||||
std::string filename_;
|
std::string filename_;
|
||||||
|
|
||||||
Bytes rom_data_;
|
Bytes rom_data_;
|
||||||
Bytes graphics_buffer_;
|
Bytes graphics_buffer_;
|
||||||
|
|
||||||
|
gfx::BitmapTable graphics_bin_;
|
||||||
|
|
||||||
std::shared_ptr<SDL_Renderer> renderer_;
|
std::shared_ptr<SDL_Renderer> renderer_;
|
||||||
std::unordered_map<int, gfx::Bitmap> graphics_bin_;
|
|
||||||
std::unordered_map<std::string, gfx::PaletteGroup> palette_groups_;
|
std::unordered_map<std::string, gfx::PaletteGroup> palette_groups_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,68 @@ namespace app {
|
|||||||
namespace zelda3 {
|
namespace zelda3 {
|
||||||
namespace dungeon {
|
namespace dungeon {
|
||||||
|
|
||||||
|
void Room::LoadGfxGroups() {
|
||||||
|
int gfxPointer =
|
||||||
|
(rom_[gfx_groups_pointer + 1] << 8) + rom_[gfx_groups_pointer];
|
||||||
|
gfxPointer = core::SnesToPc(gfxPointer);
|
||||||
|
|
||||||
|
for (int i = 0; i < 37; i++) {
|
||||||
|
for (int j = 0; j < 8; j++) {
|
||||||
|
mainGfx[i][j] = rom_[gfxPointer + (i * 8) + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 82; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
roomGfx[i][j] = rom_[entrance_gfx_group + (i * 4) + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 144; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
spriteGfx[i][j] = rom_[sprite_blockset_pointer + (i * 4) + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 72; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
paletteGfx[i][j] = rom_[dungeons_palettes_groups + (i * 4) + j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Room::SaveGroupsToROM() {
|
||||||
|
int gfxPointer =
|
||||||
|
(rom_[gfx_groups_pointer + 1] << 8) + rom_[gfx_groups_pointer];
|
||||||
|
gfxPointer = core::SnesToPc(gfxPointer);
|
||||||
|
|
||||||
|
for (int i = 0; i < 37; i++) {
|
||||||
|
for (int j = 0; j < 8; j++) {
|
||||||
|
rom_.Write(gfxPointer + (i * 8) + j, mainGfx[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 82; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
rom_.Write(entrance_gfx_group + (i * 4) + j, roomGfx[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 144; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
rom_.Write(sprite_blockset_pointer + (i * 4) + j, spriteGfx[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 72; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
rom_.Write(dungeons_palettes_groups + (i * 4) + j, paletteGfx[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Room::LoadChests() {}
|
void Room::LoadChests() {}
|
||||||
|
|
||||||
void Room::LoadBlocks() {}
|
void Room::LoadBlocks() {}
|
||||||
@@ -20,12 +82,82 @@ void Room::LoadTorches() {}
|
|||||||
|
|
||||||
void Room::LoadSecrets() {}
|
void Room::LoadSecrets() {}
|
||||||
|
|
||||||
void Room::Resync() {}
|
void Room::Resync() {}
|
||||||
|
|
||||||
void Room::LoadObjectsFromArray(int loc) {}
|
void Room::LoadObjectsFromArray(int loc) {}
|
||||||
|
|
||||||
void Room::LoadSpritesFromArray(int loc) {}
|
void Room::LoadSpritesFromArray(int loc) {}
|
||||||
|
|
||||||
|
void Room::LoadRoomGraphics(uchar entrance_blockset) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
blocks[i] = mainGfx[BackgroundTileset][i];
|
||||||
|
if (i >= 6 && i <= 6) {
|
||||||
|
// 3-6
|
||||||
|
if (entrance_blockset != 0xFF) {
|
||||||
|
// 6 is wrong for the entrance? -NOP need to fix that
|
||||||
|
// TODO: Find why this is wrong - Thats because of the stairs need to
|
||||||
|
// find a workaround
|
||||||
|
if (roomGfx[entrance_blockset][i - 3] != 0) {
|
||||||
|
blocks[i] = roomGfx[entrance_blockset][i - 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks[8] = 115 + 0; // Static Sprites Blocksets (fairy,pot,ect...)
|
||||||
|
blocks[9] = 115 + 10;
|
||||||
|
blocks[10] = 115 + 6;
|
||||||
|
blocks[11] = 115 + 7;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
blocks[12 + i] = (uchar)(spriteGfx[SpriteTileset + 64][i] + 115);
|
||||||
|
} // 12-16 sprites
|
||||||
|
|
||||||
|
auto newPdata = rom_.GetGraphicsBuffer();
|
||||||
|
|
||||||
|
uchar* sheetsData = current_graphics_.GetData();
|
||||||
|
// Into "room gfx16" 16 of them
|
||||||
|
|
||||||
|
int sheetPos = 0;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
int d = 0;
|
||||||
|
int ioff = blocks[i] * 2048;
|
||||||
|
while (d < 2048) {
|
||||||
|
// NOTE LOAD BLOCKSETS SOMEWHERE FIRST
|
||||||
|
uchar mapByte = newPdata[d + ioff];
|
||||||
|
if (i < 4) // removed switch
|
||||||
|
{
|
||||||
|
mapByte += 0x88;
|
||||||
|
} // Last line of 6, first line of 7 ?
|
||||||
|
|
||||||
|
sheetsData[d + sheetPos] = mapByte;
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
|
||||||
|
sheetPos += 2048;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadAnimatedGraphics();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Room::LoadAnimatedGraphics() {
|
||||||
|
int gfxanimatedPointer = core::SnesToPc(gfx_animated_pointer);
|
||||||
|
|
||||||
|
auto newPdata = rom_.GetGraphicsBuffer();
|
||||||
|
|
||||||
|
uchar* sheetsData = current_graphics_.GetData();
|
||||||
|
int data = 0;
|
||||||
|
while (data < 512) {
|
||||||
|
uchar mapByte = newPdata[data + (92 * 2048) + (512 * animated_frame)];
|
||||||
|
sheetsData[data + (7 * 2048)] = mapByte;
|
||||||
|
|
||||||
|
mapByte =
|
||||||
|
newPdata[data + (rom_[gfxanimatedPointer + BackgroundTileset] * 2048) +
|
||||||
|
(512 * animated_frame)];
|
||||||
|
sheetsData[data + (7 * 2048) - 512] = mapByte;
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Room::LoadRoomFromROM() {
|
void Room::LoadRoomFromROM() {
|
||||||
// Load dungeon header
|
// Load dungeon header
|
||||||
int headerPointer = core::SnesToPc(room_header_pointer);
|
int headerPointer = core::SnesToPc(room_header_pointer);
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ namespace app {
|
|||||||
namespace zelda3 {
|
namespace zelda3 {
|
||||||
namespace dungeon {
|
namespace dungeon {
|
||||||
|
|
||||||
|
constexpr int entrance_gfx_group = 0x5D97;
|
||||||
|
constexpr int gfx_animated_pointer = 0x10275; // JP 0x10624 //long pointer
|
||||||
|
|
||||||
class DungeonDestination {
|
class DungeonDestination {
|
||||||
public:
|
public:
|
||||||
DungeonDestination(uint8_t i) : Index(i) {}
|
DungeonDestination(uint8_t i) : Index(i) {}
|
||||||
@@ -85,6 +88,8 @@ class Room {
|
|||||||
Room() = default;
|
Room() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void LoadGfxGroups();
|
||||||
|
bool SaveGroupsToROM();
|
||||||
void LoadChests();
|
void LoadChests();
|
||||||
void LoadBlocks();
|
void LoadBlocks();
|
||||||
void LoadTorches();
|
void LoadTorches();
|
||||||
@@ -94,6 +99,9 @@ class Room {
|
|||||||
void LoadObjectsFromArray(int loc);
|
void LoadObjectsFromArray(int loc);
|
||||||
void LoadSpritesFromArray(int loc);
|
void LoadSpritesFromArray(int loc);
|
||||||
|
|
||||||
|
void LoadRoomGraphics(uchar entrance_blockset = 0xFF);
|
||||||
|
void LoadAnimatedGraphics();
|
||||||
|
|
||||||
void LoadRoomFromROM();
|
void LoadRoomFromROM();
|
||||||
|
|
||||||
DungeonDestination Pits;
|
DungeonDestination Pits;
|
||||||
@@ -102,6 +110,8 @@ class Room {
|
|||||||
DungeonDestination Stair3;
|
DungeonDestination Stair3;
|
||||||
DungeonDestination Stair4;
|
DungeonDestination Stair4;
|
||||||
|
|
||||||
|
int animated_frame = 0;
|
||||||
|
|
||||||
int RoomID = 0;
|
int RoomID = 0;
|
||||||
ushort MessageID = 0;
|
ushort MessageID = 0;
|
||||||
uchar BackgroundTileset;
|
uchar BackgroundTileset;
|
||||||
@@ -111,6 +121,12 @@ class Room {
|
|||||||
uchar Floor1Graphics;
|
uchar Floor1Graphics;
|
||||||
uchar Floor2Graphics;
|
uchar Floor2Graphics;
|
||||||
uchar Layer2Mode;
|
uchar Layer2Mode;
|
||||||
|
std::array<uchar, 16> blocks;
|
||||||
|
|
||||||
|
uint8_t mainGfx[37][8];
|
||||||
|
uint8_t roomGfx[82][4];
|
||||||
|
uint8_t spriteGfx[144][4];
|
||||||
|
uint8_t paletteGfx[72][4];
|
||||||
|
|
||||||
// LayerMergeType LayerMerging;
|
// LayerMergeType LayerMerging;
|
||||||
uchar Tag1;
|
uchar Tag1;
|
||||||
@@ -118,6 +134,8 @@ class Room {
|
|||||||
bool IsDark;
|
bool IsDark;
|
||||||
|
|
||||||
ROM rom_;
|
ROM rom_;
|
||||||
|
|
||||||
|
gfx::Bitmap current_graphics_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dungeon
|
} // namespace dungeon
|
||||||
|
|||||||
Reference in New Issue
Block a user