Merge pull request #27 from scawful/ow-map-draw
Overworld Map Drawing with Palettes
This commit is contained in:
@@ -466,6 +466,14 @@ constexpr int dungeonMapBgPalettes = 0xDE544; // 16*6
|
|||||||
constexpr int hardcodedGrassLW = 0x5FEA9;
|
constexpr int hardcodedGrassLW = 0x5FEA9;
|
||||||
constexpr int hardcodedGrassDW = 0x05FEB3; // 0x7564F
|
constexpr int hardcodedGrassDW = 0x05FEB3; // 0x7564F
|
||||||
constexpr int hardcodedGrassSpecial = 0x75640;
|
constexpr int hardcodedGrassSpecial = 0x75640;
|
||||||
|
constexpr int overworldMiniMapPalettes = 0x55B27;
|
||||||
|
constexpr int triforcePalette = 0x64425;
|
||||||
|
constexpr int crystalPalette = 0xF4CD3;
|
||||||
|
constexpr int customAreaSpecificBGPalette =
|
||||||
|
0x140000; // 2 bytes for each overworld area (320)
|
||||||
|
constexpr int customAreaSpecificBGASM = 0x140150;
|
||||||
|
constexpr int customAreaSpecificBGEnabled =
|
||||||
|
0x140140; // 1 byte, not 0 if enabled
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Dungeon Map Related Variables
|
// Dungeon Map Related Variables
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace {
|
|||||||
void InitializeKeymap() {
|
void InitializeKeymap() {
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
io.KeyMap[ImGuiKey_Backspace] = SDL_GetScancodeFromKey(SDLK_BACKSPACE);
|
io.KeyMap[ImGuiKey_Backspace] = SDL_GetScancodeFromKey(SDLK_BACKSPACE);
|
||||||
|
io.KeyMap[ImGuiKey_LeftShift] = SDL_GetScancodeFromKey(SDLK_LSHIFT);
|
||||||
io.KeyMap[ImGuiKey_Enter] = SDL_GetScancodeFromKey(SDLK_RETURN);
|
io.KeyMap[ImGuiKey_Enter] = SDL_GetScancodeFromKey(SDLK_RETURN);
|
||||||
io.KeyMap[ImGuiKey_UpArrow] = SDL_GetScancodeFromKey(SDLK_UP);
|
io.KeyMap[ImGuiKey_UpArrow] = SDL_GetScancodeFromKey(SDLK_UP);
|
||||||
io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN);
|
io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN);
|
||||||
@@ -37,6 +38,8 @@ void HandleKeyDown(SDL_Event &event) {
|
|||||||
case SDLK_DOWN:
|
case SDLK_DOWN:
|
||||||
case SDLK_RETURN:
|
case SDLK_RETURN:
|
||||||
case SDLK_BACKSPACE:
|
case SDLK_BACKSPACE:
|
||||||
|
case SDLK_LSHIFT:
|
||||||
|
case SDLK_LCTRL:
|
||||||
case SDLK_TAB:
|
case SDLK_TAB:
|
||||||
io.KeysDown[event.key.keysym.scancode] = (event.type == SDL_KEYDOWN);
|
io.KeysDown[event.key.keysym.scancode] = (event.type == SDL_KEYDOWN);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -236,9 +236,6 @@ void MasterEditor::DrawViewMenu() {
|
|||||||
ImGui::MenuItem("HEX Editor", nullptr, &show_memory_editor);
|
ImGui::MenuItem("HEX Editor", nullptr, &show_memory_editor);
|
||||||
ImGui::MenuItem("ASM Editor", nullptr, &show_asm_editor);
|
ImGui::MenuItem("ASM Editor", nullptr, &show_asm_editor);
|
||||||
ImGui::MenuItem("ImGui Demo", nullptr, &show_imgui_demo);
|
ImGui::MenuItem("ImGui Demo", nullptr, &show_imgui_demo);
|
||||||
if (ImGui::MenuItem("Overworld Debug")) {
|
|
||||||
overworld_editor_.OverworldDebugMenu();
|
|
||||||
}
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::BeginMenu("GUI Tools")) {
|
if (ImGui::BeginMenu("GUI Tools")) {
|
||||||
ImGui::MenuItem("Metrics (ImGui)", nullptr, &show_imgui_metrics);
|
ImGui::MenuItem("Metrics (ImGui)", nullptr, &show_imgui_metrics);
|
||||||
|
|||||||
@@ -16,35 +16,69 @@
|
|||||||
#include "gui/canvas.h"
|
#include "gui/canvas.h"
|
||||||
#include "gui/icons.h"
|
#include "gui/icons.h"
|
||||||
|
|
||||||
/**
|
|
||||||
* Drawing the Overworld
|
|
||||||
* Tips by Zarby
|
|
||||||
*
|
|
||||||
* 1) Find the graphics pointers (constants.h)
|
|
||||||
* 2) Convert the 3bpp SNES data into PC 4bpp (Hard)
|
|
||||||
* 3) Get the tiles32 data
|
|
||||||
* 4) Get the tiles16 data
|
|
||||||
* 5) Get the map32 data using lz2 variant decompression
|
|
||||||
* 6) Get the graphics data of the map
|
|
||||||
* 7) Load 4bpp into Pseudo VRAM for rendering tiles to screen
|
|
||||||
* 8) Render the tiles to a bitmap with a B&W palette to start
|
|
||||||
* 9) Get the palette data and find how it's loaded in game
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void UpdateSelectedTile16(int selected, gfx::Bitmap &tile16_blockset,
|
||||||
|
gfx::Bitmap &selected_tile) {
|
||||||
|
auto blockset = tile16_blockset.GetData();
|
||||||
|
auto bitmap = selected_tile.GetData();
|
||||||
|
|
||||||
|
int src_pos = ((selected - ((selected / 0x08) * 0x08)) * 0x10) +
|
||||||
|
((selected / 0x08) * 2048);
|
||||||
|
for (int yy = 0; yy < 0x10; yy++) {
|
||||||
|
for (int xx = 0; xx < 0x10; xx++) {
|
||||||
|
bitmap[xx + (yy * 0x10)] = blockset[src_pos + xx + (yy * 0x80)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void OverworldEditor::SetupROM(ROM &rom) { rom_ = rom; }
|
void OverworldEditor::SetupROM(ROM &rom) { rom_ = rom; }
|
||||||
|
|
||||||
absl::Status OverworldEditor::Update() {
|
absl::Status OverworldEditor::Update() {
|
||||||
if (rom_.isLoaded() && !all_gfx_loaded_) {
|
if (rom_.isLoaded() && !all_gfx_loaded_) {
|
||||||
LoadGraphics();
|
LoadGraphics();
|
||||||
all_gfx_loaded_ = true;
|
all_gfx_loaded_ = true;
|
||||||
|
|
||||||
|
RETURN_IF_ERROR(overworld_.Load(rom_))
|
||||||
|
current_gfx_bmp_.Create(128, 512, 64, overworld_.GetCurrentGraphics());
|
||||||
|
rom_.RenderBitmap(¤t_gfx_bmp_);
|
||||||
|
|
||||||
|
auto tile16_palette = overworld_.GetCurrentPalette();
|
||||||
|
tile16_blockset_bmp_.Create(128, 8192, 128,
|
||||||
|
overworld_.GetCurrentBlockset());
|
||||||
|
for (int j = 0; j < tile16_palette.colors.size(); j++) {
|
||||||
|
tile16_blockset_bmp_.SetPaletteColor(j, tile16_palette.GetColor(j));
|
||||||
|
}
|
||||||
|
rom_.RenderBitmap(&tile16_blockset_bmp_);
|
||||||
|
map_blockset_loaded_ = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < core::kNumOverworldMaps; ++i) {
|
||||||
|
overworld_.SetCurrentMap(i);
|
||||||
|
auto palette = overworld_.GetCurrentPalette();
|
||||||
|
maps_bmp_[i].Create(512, 512, 512, overworld_.GetCurrentBitmapData());
|
||||||
|
for (int j = 0; j < palette.colors.size(); j++) {
|
||||||
|
maps_bmp_[i].SetPaletteColor(j, palette.GetColor(j));
|
||||||
|
}
|
||||||
|
rom_.RenderBitmap(&(maps_bmp_[i]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overworld_debug_menu_) {
|
if (update_selected_tile_ && all_gfx_loaded_) {
|
||||||
RETURN_IF_ERROR(DrawOverworldDebugMenu())
|
if (!selected_tile_loaded_) {
|
||||||
|
selected_tile_bmp_.Create(16, 16, 64, 256);
|
||||||
|
}
|
||||||
|
UpdateSelectedTile16(selected_tile_, tile16_blockset_bmp_,
|
||||||
|
selected_tile_bmp_);
|
||||||
|
auto palette = overworld_.GetCurrentPalette();
|
||||||
|
for (int j = 0; j < palette.colors.size(); j++) {
|
||||||
|
selected_tile_bmp_.SetPaletteColor(j, palette.GetColor(j));
|
||||||
|
}
|
||||||
|
rom_.RenderBitmap(&selected_tile_bmp_);
|
||||||
|
update_selected_tile_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto toolset_status = DrawToolset();
|
auto toolset_status = DrawToolset();
|
||||||
@@ -68,7 +102,7 @@ absl::Status OverworldEditor::Update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OverworldEditor::DrawToolset() {
|
absl::Status OverworldEditor::DrawToolset() {
|
||||||
if (ImGui::BeginTable("OWToolset", 17, toolset_table_flags, ImVec2(0, 0))) {
|
if (ImGui::BeginTable("OWToolset", 15, toolset_table_flags, ImVec2(0, 0))) {
|
||||||
for (const auto &name : kToolsetColumnNames)
|
for (const auto &name : kToolsetColumnNames)
|
||||||
ImGui::TableSetupColumn(name.data());
|
ImGui::TableSetupColumn(name.data());
|
||||||
|
|
||||||
@@ -106,19 +140,6 @@ absl::Status OverworldEditor::DrawToolset() {
|
|||||||
// Music
|
// Music
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Button(ICON_MD_MUSIC_NOTE);
|
ImGui::Button(ICON_MD_MUSIC_NOTE);
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text(ICON_MD_MORE_VERT);
|
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
|
||||||
ImGui::Text("Palette:");
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
std::string id = "##PaletteColor" + std::to_string(i);
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::ColorEdit4(id.c_str(), ¤t_palette_[i].x,
|
|
||||||
ImGuiColorEditFlags_NoInputs |
|
|
||||||
ImGuiColorEditFlags_DisplayRGB |
|
|
||||||
ImGuiColorEditFlags_DisplayHex);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
@@ -126,10 +147,14 @@ absl::Status OverworldEditor::DrawToolset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OverworldEditor::DrawOverworldMapSettings() {
|
void OverworldEditor::DrawOverworldMapSettings() {
|
||||||
if (ImGui::BeginTable("#mapSettings", 7, ow_map_flags, ImVec2(0, 0), -1)) {
|
if (ImGui::BeginTable("#mapSettings", 8, ow_map_flags, ImVec2(0, 0), -1)) {
|
||||||
for (const auto &name : kOverworldSettingsColumnNames)
|
for (const auto &name : kOverworldSettingsColumnNames)
|
||||||
ImGui::TableSetupColumn(name.data());
|
ImGui::TableSetupColumn(name.data());
|
||||||
|
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
ImGui::SetNextItemWidth(50.f);
|
||||||
|
ImGui::InputInt("Current Map", ¤t_map_);
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::SetNextItemWidth(100.f);
|
ImGui::SetNextItemWidth(100.f);
|
||||||
ImGui::Combo("##world", ¤t_world_,
|
ImGui::Combo("##world", ¤t_world_,
|
||||||
@@ -174,20 +199,30 @@ void OverworldEditor::DrawOverworldMapSettings() {
|
|||||||
void OverworldEditor::DrawOverworldCanvas() {
|
void OverworldEditor::DrawOverworldCanvas() {
|
||||||
DrawOverworldMapSettings();
|
DrawOverworldMapSettings();
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
overworld_map_canvas_.DrawBackground();
|
ImGuiID child_id = ImGui::GetID((void *)(intptr_t)7);
|
||||||
overworld_map_canvas_.DrawContextMenu();
|
if (ImGui::BeginChild(child_id, ImGui::GetContentRegionAvail(), true,
|
||||||
if (overworld_.isLoaded()) {
|
ImGuiWindowFlags_AlwaysVerticalScrollbar |
|
||||||
auto map = overworld_.GetOverworldMap(0);
|
ImGuiWindowFlags_AlwaysHorizontalScrollbar)) {
|
||||||
if (map.IsBuilt()) {
|
overworld_map_canvas_.DrawBackground(ImVec2(0x200 * 8, 0x200 * 8));
|
||||||
if (map.IsLargeMap() && map.IsInitialized()) {
|
overworld_map_canvas_.DrawContextMenu();
|
||||||
overworld_map_canvas_.DrawBitmap(overworld_map_bmp_, 2);
|
if (overworld_.isLoaded()) {
|
||||||
} else {
|
int xx = 0;
|
||||||
overworld_map_canvas_.DrawBitmap(overworld_map_bmp_, 2);
|
int yy = 0;
|
||||||
|
for (int i = 0; i < 0x40; i++) {
|
||||||
|
overworld_map_canvas_.DrawBitmap(maps_bmp_[i + (current_world_ * 0x40)],
|
||||||
|
(xx * 0x200), (yy * 0x200));
|
||||||
|
|
||||||
|
xx++;
|
||||||
|
if (xx >= 8) {
|
||||||
|
yy++;
|
||||||
|
xx = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
overworld_map_canvas_.DrawGrid(64.f);
|
||||||
|
overworld_map_canvas_.DrawOverlay();
|
||||||
}
|
}
|
||||||
overworld_map_canvas_.DrawGrid(64.f);
|
ImGui::EndChild();
|
||||||
overworld_map_canvas_.DrawOverlay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverworldEditor::DrawTileSelector() {
|
void OverworldEditor::DrawTileSelector() {
|
||||||
@@ -224,7 +259,7 @@ void OverworldEditor::DrawTileSelector() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OverworldEditor::DrawTile16Selector() {
|
void OverworldEditor::DrawTile16Selector() {
|
||||||
blockset_canvas_.DrawBackground(ImVec2(256 + 1, (8192 * 2) + 1));
|
blockset_canvas_.DrawBackground(ImVec2(0x100 + 1, (8192 * 2) + 1));
|
||||||
blockset_canvas_.DrawContextMenu();
|
blockset_canvas_.DrawContextMenu();
|
||||||
if (map_blockset_loaded_) {
|
if (map_blockset_loaded_) {
|
||||||
blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, 2);
|
blockset_canvas_.DrawBitmap(tile16_blockset_bmp_, 2);
|
||||||
@@ -235,19 +270,19 @@ void OverworldEditor::DrawTile16Selector() {
|
|||||||
|
|
||||||
void OverworldEditor::DrawTile8Selector() {
|
void OverworldEditor::DrawTile8Selector() {
|
||||||
graphics_bin_canvas_.DrawBackground(
|
graphics_bin_canvas_.DrawBackground(
|
||||||
ImVec2(256 + 1, kNumSheetsToLoad * 64 + 1));
|
ImVec2(0x100 + 1, kNumSheetsToLoad * 0x40 + 1));
|
||||||
graphics_bin_canvas_.DrawContextMenu();
|
graphics_bin_canvas_.DrawContextMenu();
|
||||||
if (all_gfx_loaded_) {
|
if (all_gfx_loaded_) {
|
||||||
for (const auto &[key, value] : graphics_bin_) {
|
for (const auto &[key, value] : graphics_bin_) {
|
||||||
int offset = 64 * (key + 1);
|
int offset = 0x40 * (key + 1);
|
||||||
int top_left_y = graphics_bin_canvas_.GetZeroPoint().y + 2;
|
int top_left_y = graphics_bin_canvas_.GetZeroPoint().y + 2;
|
||||||
if (key >= 1) {
|
if (key >= 1) {
|
||||||
top_left_y = graphics_bin_canvas_.GetZeroPoint().y + 64 * key;
|
top_left_y = graphics_bin_canvas_.GetZeroPoint().y + 0x40 * key;
|
||||||
}
|
}
|
||||||
graphics_bin_canvas_.GetDrawList()->AddImage(
|
graphics_bin_canvas_.GetDrawList()->AddImage(
|
||||||
(void *)value.GetTexture(),
|
(void *)value.GetTexture(),
|
||||||
ImVec2(graphics_bin_canvas_.GetZeroPoint().x + 2, top_left_y),
|
ImVec2(graphics_bin_canvas_.GetZeroPoint().x + 2, top_left_y),
|
||||||
ImVec2(graphics_bin_canvas_.GetZeroPoint().x + 256,
|
ImVec2(graphics_bin_canvas_.GetZeroPoint().x + 0x100,
|
||||||
graphics_bin_canvas_.GetZeroPoint().y + offset));
|
graphics_bin_canvas_.GetZeroPoint().y + offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,51 +292,14 @@ void OverworldEditor::DrawTile8Selector() {
|
|||||||
|
|
||||||
void OverworldEditor::DrawAreaGraphics() {
|
void OverworldEditor::DrawAreaGraphics() {
|
||||||
if (overworld_.isLoaded()) {
|
if (overworld_.isLoaded()) {
|
||||||
static bool set_loaded = false;
|
|
||||||
if (!set_loaded) {
|
|
||||||
current_graphics_set_ =
|
|
||||||
overworld_.GetOverworldMap(0).GetCurrentGraphicsSet();
|
|
||||||
set_loaded = true;
|
|
||||||
}
|
|
||||||
current_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 16 * 64 + 1));
|
current_gfx_canvas_.DrawBackground(ImVec2(256 + 1, 16 * 64 + 1));
|
||||||
current_gfx_canvas_.DrawContextMenu();
|
current_gfx_canvas_.DrawContextMenu();
|
||||||
current_gfx_canvas_.DrawBitmap(current_gfx_bmp_);
|
current_gfx_canvas_.DrawBitmap(current_gfx_bmp_);
|
||||||
// for (const auto &[key, value] : current_graphics_set_) {
|
|
||||||
// int offset = 64 * (key + 1);
|
|
||||||
// int top_left_y = current_gfx_canvas_.GetZeroPoint().y + 2;
|
|
||||||
// if (key >= 1) {
|
|
||||||
// top_left_y = current_gfx_canvas_.GetZeroPoint().y + 64 * key;
|
|
||||||
// }
|
|
||||||
// current_gfx_canvas_.GetDrawList()->AddImage(
|
|
||||||
// (void *)value.GetTexture(),
|
|
||||||
// ImVec2(current_gfx_canvas_.GetZeroPoint().x + 2, top_left_y),
|
|
||||||
// ImVec2(current_gfx_canvas_.GetZeroPoint().x + 256,
|
|
||||||
// current_gfx_canvas_.GetZeroPoint().y + offset));
|
|
||||||
// }
|
|
||||||
current_gfx_canvas_.DrawGrid(32.0f);
|
current_gfx_canvas_.DrawGrid(32.0f);
|
||||||
current_gfx_canvas_.DrawOverlay();
|
current_gfx_canvas_.DrawOverlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OverworldEditor::DrawOverworldDebugMenu() {
|
|
||||||
ImGui::Begin("Overworld Debug Menu");
|
|
||||||
|
|
||||||
if (ImGui::Button("Load Overworld")) {
|
|
||||||
RETURN_IF_ERROR(overworld_.Load(rom_))
|
|
||||||
current_gfx_bmp_.Create(128, 512, 64, overworld_.GetCurrentGraphics());
|
|
||||||
rom_.RenderBitmap(¤t_gfx_bmp_);
|
|
||||||
tile16_blockset_bmp_.Create(128, 8192, 128,
|
|
||||||
overworld_.GetCurrentBlockset());
|
|
||||||
rom_.RenderBitmap(&tile16_blockset_bmp_);
|
|
||||||
map_blockset_loaded_ = true;
|
|
||||||
overworld_map_bmp_.Create(512, 512, 512, overworld_.GetCurrentBitmapData());
|
|
||||||
rom_.RenderBitmap(&overworld_map_bmp_);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
return absl::OkStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OverworldEditor::LoadGraphics() {
|
void OverworldEditor::LoadGraphics() {
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
current_palette_[i].x = (i * 0.21f);
|
current_palette_[i].x = (i * 0.21f);
|
||||||
@@ -312,8 +310,6 @@ void OverworldEditor::LoadGraphics() {
|
|||||||
|
|
||||||
PRINT_IF_ERROR(rom_.LoadAllGraphicsData())
|
PRINT_IF_ERROR(rom_.LoadAllGraphicsData())
|
||||||
graphics_bin_ = rom_.GetGraphicsBin();
|
graphics_bin_ = rom_.GetGraphicsBin();
|
||||||
|
|
||||||
PRINT_IF_ERROR(rom_.CreateAllGraphicsData())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ static constexpr absl::string_view kToolsetColumnNames[] = {
|
|||||||
"#undoTool", "#redoTool", "#drawTool", "#separator2",
|
"#undoTool", "#redoTool", "#drawTool", "#separator2",
|
||||||
"#zoomOutTool", "#zoomInTool", "#separator", "#history",
|
"#zoomOutTool", "#zoomInTool", "#separator", "#history",
|
||||||
"#entranceTool", "#exitTool", "#itemTool", "#spriteTool",
|
"#entranceTool", "#exitTool", "#itemTool", "#spriteTool",
|
||||||
"#transportTool", "#musicTool", "#separator3", "#reloadTool"};
|
"#transportTool", "#musicTool" };
|
||||||
|
|
||||||
static constexpr absl::string_view kOverworldSettingsColumnNames[] = {
|
static constexpr absl::string_view kOverworldSettingsColumnNames[] = {
|
||||||
"##1stCol", "##gfxCol", "##palCol", "##sprgfxCol",
|
"##1stCol", "##gfxCol", "##palCol", "##sprgfxCol",
|
||||||
@@ -48,8 +48,6 @@ class OverworldEditor {
|
|||||||
absl::Status Copy() { return absl::UnimplementedError("Copy"); }
|
absl::Status Copy() { return absl::UnimplementedError("Copy"); }
|
||||||
absl::Status Paste() { return absl::UnimplementedError("Paste"); }
|
absl::Status Paste() { return absl::UnimplementedError("Paste"); }
|
||||||
|
|
||||||
void OverworldDebugMenu() { overworld_debug_menu_ = true; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
absl::Status DrawToolset();
|
absl::Status DrawToolset();
|
||||||
void DrawOverworldMapSettings();
|
void DrawOverworldMapSettings();
|
||||||
@@ -58,12 +56,11 @@ class OverworldEditor {
|
|||||||
void DrawTile16Selector();
|
void DrawTile16Selector();
|
||||||
void DrawTile8Selector();
|
void DrawTile8Selector();
|
||||||
void DrawAreaGraphics();
|
void DrawAreaGraphics();
|
||||||
|
|
||||||
absl::Status DrawOverworldDebugMenu();
|
|
||||||
|
|
||||||
void LoadGraphics();
|
void LoadGraphics();
|
||||||
|
|
||||||
int current_world_ = 0;
|
int current_world_ = 0;
|
||||||
|
int current_map_ = 0;
|
||||||
|
int selected_tile_ = 0;
|
||||||
char map_gfx_[3] = "";
|
char map_gfx_[3] = "";
|
||||||
char map_palette_[3] = "";
|
char map_palette_[3] = "";
|
||||||
char spr_gfx_[3] = "";
|
char spr_gfx_[3] = "";
|
||||||
@@ -74,7 +71,8 @@ class OverworldEditor {
|
|||||||
bool opt_enable_grid = true;
|
bool opt_enable_grid = true;
|
||||||
bool all_gfx_loaded_ = false;
|
bool all_gfx_loaded_ = false;
|
||||||
bool map_blockset_loaded_ = false;
|
bool map_blockset_loaded_ = false;
|
||||||
bool overworld_debug_menu_ = false;
|
bool selected_tile_loaded_ = false;
|
||||||
|
bool update_selected_tile_ = true;
|
||||||
|
|
||||||
ImVec4 current_palette_[8];
|
ImVec4 current_palette_[8];
|
||||||
|
|
||||||
@@ -86,6 +84,7 @@ class OverworldEditor {
|
|||||||
|
|
||||||
std::unordered_map<int, gfx::Bitmap> graphics_bin_;
|
std::unordered_map<int, gfx::Bitmap> graphics_bin_;
|
||||||
std::unordered_map<int, gfx::Bitmap> current_graphics_set_;
|
std::unordered_map<int, gfx::Bitmap> current_graphics_set_;
|
||||||
|
std::unordered_map<int, gfx::Bitmap> maps_bmp_;
|
||||||
|
|
||||||
ROM rom_;
|
ROM rom_;
|
||||||
zelda3::Overworld overworld_;
|
zelda3::Overworld overworld_;
|
||||||
@@ -94,7 +93,7 @@ class OverworldEditor {
|
|||||||
gfx::Bitmap tile16_blockset_bmp_; // pointer size 1048576
|
gfx::Bitmap tile16_blockset_bmp_; // pointer size 1048576
|
||||||
gfx::Bitmap current_gfx_bmp_; // pointer size 32768
|
gfx::Bitmap current_gfx_bmp_; // pointer size 32768
|
||||||
gfx::Bitmap all_gfx_bmp; // pointer size 456704
|
gfx::Bitmap all_gfx_bmp; // pointer size 456704
|
||||||
gfx::Bitmap overworld_map_bmp_;
|
gfx::Bitmap selected_tile_bmp_;
|
||||||
|
|
||||||
gui::Canvas overworld_map_canvas_;
|
gui::Canvas overworld_map_canvas_;
|
||||||
gui::Canvas current_gfx_canvas_;
|
gui::Canvas current_gfx_canvas_;
|
||||||
|
|||||||
@@ -103,8 +103,17 @@ void Bitmap::CreateTexture(std::shared_ptr<SDL_Renderer> renderer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert SNESPalette to SDL_Palette for surface.
|
// Convert SNESPalette to SDL_Palette for surface.
|
||||||
void Bitmap::ApplyPalette(SNESPalette &palette) {
|
void Bitmap::ApplyPalette(const SNESPalette & palette) {
|
||||||
surface_->format->palette = palette.GetSDL_Palette();
|
palette_ = palette;
|
||||||
|
SDL_SetPaletteColors(surface_->format->palette,
|
||||||
|
palette_.GetSDL_Palette()->colors,
|
||||||
|
0, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bitmap::SetPaletteColor(int id, gfx::SNESColor color) {
|
||||||
|
surface_->format->palette->colors[id].r = color.rgb.x;
|
||||||
|
surface_->format->palette->colors[id].g = color.rgb.y;
|
||||||
|
surface_->format->palette->colors[id].b = color.rgb.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a vector of bitmaps which are individual 8x8 tiles.
|
// Creates a vector of bitmaps which are individual 8x8 tiles.
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ class Bitmap {
|
|||||||
|
|
||||||
void CreateTexture(std::shared_ptr<SDL_Renderer> renderer);
|
void CreateTexture(std::shared_ptr<SDL_Renderer> renderer);
|
||||||
|
|
||||||
void ApplyPalette(SNESPalette &palette);
|
void ApplyPalette(const SNESPalette &palette);
|
||||||
|
void SetPaletteColor(int id, gfx::SNESColor color);
|
||||||
|
|
||||||
absl::StatusOr<std::vector<Bitmap>> CreateTiles();
|
absl::StatusOr<std::vector<Bitmap>> CreateTiles();
|
||||||
absl::Status CreateFromTiles(const std::vector<Bitmap> &tiles);
|
absl::Status CreateFromTiles(const std::vector<Bitmap> &tiles);
|
||||||
@@ -71,6 +72,7 @@ class Bitmap {
|
|||||||
bool freed_ = false;
|
bool freed_ = false;
|
||||||
uchar *pixel_data_;
|
uchar *pixel_data_;
|
||||||
Bytes data_;
|
Bytes data_;
|
||||||
|
gfx::SNESPalette palette_;
|
||||||
std::shared_ptr<SDL_Texture> texture_ = nullptr;
|
std::shared_ptr<SDL_Texture> texture_ = nullptr;
|
||||||
std::shared_ptr<SDL_Surface> surface_ = nullptr;
|
std::shared_ptr<SDL_Surface> surface_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ char* Convert(const snes_palette pal) {
|
|||||||
|
|
||||||
SNESColor::SNESColor() : rgb(ImVec4(0.f, 0.f, 0.f, 0.f)) {}
|
SNESColor::SNESColor() : rgb(ImVec4(0.f, 0.f, 0.f, 0.f)) {}
|
||||||
|
|
||||||
|
SNESColor::SNESColor(snes_color val) {
|
||||||
|
rgb.x = val.red;
|
||||||
|
rgb.y = val.blue;
|
||||||
|
rgb.z = val.green;
|
||||||
|
}
|
||||||
|
|
||||||
SNESColor::SNESColor(ImVec4 val) : rgb(val) {
|
SNESColor::SNESColor(ImVec4 val) : rgb(val) {
|
||||||
snes_color col;
|
snes_color col;
|
||||||
col.red = (uchar)val.x;
|
col.red = (uchar)val.x;
|
||||||
@@ -81,6 +87,10 @@ void SNESColor::setRgb(ImVec4 val) {
|
|||||||
snes = ConvertRGBtoSNES(col);
|
snes = ConvertRGBtoSNES(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SNESColor::setSNES(snes_color val) {
|
||||||
|
rgb = ImVec4(val.red, val.green, val.blue, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
void SNESColor::setSNES(uint16_t val) {
|
void SNESColor::setSNES(uint16_t val) {
|
||||||
snes = val;
|
snes = val;
|
||||||
snes_color col = ConvertSNEStoRGB(val);
|
snes_color col = ConvertSNEStoRGB(val);
|
||||||
@@ -130,6 +140,29 @@ SNESPalette::SNESPalette(const std::vector<ImVec4>& cols) {
|
|||||||
size_ = cols.size();
|
size_ = cols.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SNESPalette::SNESPalette(const std::vector<snes_color>& cols) {
|
||||||
|
for (const auto& each : cols) {
|
||||||
|
SNESColor scol;
|
||||||
|
scol.setSNES(each);
|
||||||
|
colors.push_back(scol);
|
||||||
|
}
|
||||||
|
size_ = cols.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
SNESPalette::SNESPalette(const std::vector<SNESColor>& cols) {
|
||||||
|
for (const auto& each : cols) {
|
||||||
|
colors.push_back(each);
|
||||||
|
}
|
||||||
|
size_ = cols.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SNESPalette::Create(const std::vector<SNESColor>& cols) {
|
||||||
|
for (const auto each : cols) {
|
||||||
|
colors.push_back(each);
|
||||||
|
}
|
||||||
|
size_ = cols.size();
|
||||||
|
}
|
||||||
|
|
||||||
char* SNESPalette::encode() {
|
char* SNESPalette::encode() {
|
||||||
auto data = new char[size_ * 2];
|
auto data = new char[size_ * 2];
|
||||||
for (unsigned int i = 0; i < size_; i++) {
|
for (unsigned int i = 0; i < size_; i++) {
|
||||||
@@ -141,7 +174,6 @@ char* SNESPalette::encode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_Palette* SNESPalette::GetSDL_Palette() {
|
SDL_Palette* SNESPalette::GetSDL_Palette() {
|
||||||
std::cout << "Converting SNESPalette to SDL_Palette" << std::endl;
|
|
||||||
auto sdl_palette = std::make_shared<SDL_Palette>();
|
auto sdl_palette = std::make_shared<SDL_Palette>();
|
||||||
sdl_palette->ncolors = size_;
|
sdl_palette->ncolors = size_;
|
||||||
|
|
||||||
@@ -150,15 +182,16 @@ SDL_Palette* SNESPalette::GetSDL_Palette() {
|
|||||||
color[i].r = (uint8_t)colors[i].rgb.x * 100;
|
color[i].r = (uint8_t)colors[i].rgb.x * 100;
|
||||||
color[i].g = (uint8_t)colors[i].rgb.y * 100;
|
color[i].g = (uint8_t)colors[i].rgb.y * 100;
|
||||||
color[i].b = (uint8_t)colors[i].rgb.z * 100;
|
color[i].b = (uint8_t)colors[i].rgb.z * 100;
|
||||||
|
color[i].a = 0;
|
||||||
std::cout << "Color " << i << " added (R:" << color[i].r
|
std::cout << "Color " << i << " added (R:" << color[i].r
|
||||||
<< " G:" << color[i].g << " B:" << color[i].b << ")" << std::endl;
|
<< " G:" << color[i].g << " B:" << color[i].b << ")" << std::endl;
|
||||||
}
|
}
|
||||||
sdl_palette->colors = color.data();
|
sdl_palette->colors = color.data();
|
||||||
colors_.push_back(color);
|
|
||||||
|
|
||||||
return sdl_palette.get();
|
return sdl_palette.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PaletteGroup::PaletteGroup(uint8_t mSize) : size(mSize) {}
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -40,10 +40,14 @@ char* Convert(const snes_palette pal);
|
|||||||
struct SNESColor {
|
struct SNESColor {
|
||||||
SNESColor();
|
SNESColor();
|
||||||
explicit SNESColor(ImVec4);
|
explicit SNESColor(ImVec4);
|
||||||
|
explicit SNESColor(snes_color);
|
||||||
|
|
||||||
|
void setRgb(ImVec4);
|
||||||
|
void setSNES(snes_color);
|
||||||
|
void setSNES(uint16_t);
|
||||||
|
|
||||||
uint16_t snes = 0;
|
uint16_t snes = 0;
|
||||||
ImVec4 rgb;
|
ImVec4 rgb;
|
||||||
void setRgb(ImVec4);
|
|
||||||
void setSNES(uint16_t);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SNESPalette {
|
class SNESPalette {
|
||||||
@@ -53,14 +57,51 @@ class SNESPalette {
|
|||||||
explicit SNESPalette(char* snesPal);
|
explicit SNESPalette(char* snesPal);
|
||||||
explicit SNESPalette(const unsigned char* snes_pal);
|
explicit SNESPalette(const unsigned char* snes_pal);
|
||||||
explicit SNESPalette(const std::vector<ImVec4>&);
|
explicit SNESPalette(const std::vector<ImVec4>&);
|
||||||
|
explicit SNESPalette(const std::vector<snes_color>&);
|
||||||
|
explicit SNESPalette(const std::vector<SNESColor>&);
|
||||||
|
|
||||||
|
void Create(const std::vector<SNESColor>&);
|
||||||
|
void AddColor(SNESColor color) { colors.push_back(color); }
|
||||||
|
auto GetColor(int i) const { return colors[i]; }
|
||||||
|
|
||||||
|
SNESColor operator[](int i) {
|
||||||
|
if (i > size_) {
|
||||||
|
std::cout << "SNESPalette: Index out of bounds" << std::endl;
|
||||||
|
return colors[0];
|
||||||
|
}
|
||||||
|
return colors[i];
|
||||||
|
}
|
||||||
|
|
||||||
char* encode();
|
char* encode();
|
||||||
SDL_Palette* GetSDL_Palette();
|
SDL_Palette* GetSDL_Palette();
|
||||||
|
|
||||||
int size_ = 0;
|
int size_ = 0;
|
||||||
std::vector<SNESColor> colors;
|
std::vector<SNESColor> colors;
|
||||||
std::vector<SDL_Color*> colors_arrays_;
|
};
|
||||||
std::vector<std::vector<SDL_Color>> colors_;
|
|
||||||
|
struct PaletteGroup {
|
||||||
|
PaletteGroup() = default;
|
||||||
|
explicit PaletteGroup(uint8_t mSize);
|
||||||
|
void AddPalette(SNESPalette pal) {
|
||||||
|
palettes.emplace_back(pal);
|
||||||
|
size = palettes.size();
|
||||||
|
}
|
||||||
|
void AddColor(SNESColor color) {
|
||||||
|
if (size == 0) {
|
||||||
|
SNESPalette empty_pal;
|
||||||
|
palettes.emplace_back(empty_pal);
|
||||||
|
}
|
||||||
|
palettes[0].AddColor(color);
|
||||||
|
}
|
||||||
|
SNESPalette operator[](int i) {
|
||||||
|
if (i > size) {
|
||||||
|
std::cout << "PaletteGroup: Index out of bounds" << std::endl;
|
||||||
|
return palettes[0];
|
||||||
|
}
|
||||||
|
return palettes[i];
|
||||||
|
}
|
||||||
|
int size = 0;
|
||||||
|
std::vector<SNESPalette> palettes;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
|||||||
@@ -11,15 +11,15 @@ namespace gfx {
|
|||||||
|
|
||||||
TileInfo GetTilesInfo(ushort tile) {
|
TileInfo GetTilesInfo(ushort tile) {
|
||||||
// vhopppcc cccccccc
|
// vhopppcc cccccccc
|
||||||
ushort o = 0;
|
bool o = false;
|
||||||
ushort v = 0;
|
bool v = false;
|
||||||
ushort h = 0;
|
bool h = false;
|
||||||
auto tid = (ushort)(tile & 0x3FF);
|
auto tid = (ushort)(tile & core::TileNameMask);
|
||||||
auto p = (uchar)((tile >> 10) & 0x07);
|
auto p = (uchar)((tile >> 10) & 0x07);
|
||||||
|
|
||||||
o = (ushort)((tile & 0x2000) >> 13);
|
o = ((tile & core::TilePriorityBit) == core::TilePriorityBit);
|
||||||
h = (ushort)((tile & 0x4000) >> 14);
|
h = ((tile & core::TileHFlipBit) == core::TileHFlipBit);
|
||||||
v = (ushort)((tile & 0x8000) >> 15);
|
v = ((tile & core::TileVFlipBit) == core::TileVFlipBit);
|
||||||
|
|
||||||
return TileInfo(tid, p, v, h, o);
|
return TileInfo(tid, p, v, h, o);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ using tile8 = struct tile8;
|
|||||||
class TileInfo {
|
class TileInfo {
|
||||||
public:
|
public:
|
||||||
ushort id_;
|
ushort id_;
|
||||||
ushort over_;
|
bool over_;
|
||||||
ushort vertical_mirror_;
|
bool vertical_mirror_;
|
||||||
ushort horizontal_mirror_;
|
bool horizontal_mirror_;
|
||||||
uchar palette_;
|
uchar palette_;
|
||||||
TileInfo() = default;
|
TileInfo() = default;
|
||||||
TileInfo(ushort id, uchar palette, ushort v, ushort h, ushort o)
|
TileInfo(ushort id, uchar palette, bool v, bool h, bool o)
|
||||||
: id_(id),
|
: id_(id),
|
||||||
over_(o),
|
over_(o),
|
||||||
vertical_mirror_(v),
|
vertical_mirror_(v),
|
||||||
|
|||||||
339
src/app/rom.cc
339
src/app/rom.cc
@@ -528,33 +528,37 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, int mode) {
|
|||||||
offset += 1; // Advance 1 byte in the ROM
|
offset += 1; // Advance 1 byte in the ROM
|
||||||
} break;
|
} break;
|
||||||
case kCommandRepeatingBytes: {
|
case kCommandRepeatingBytes: {
|
||||||
|
ushort s1 = ((rom_data_[offset + 1] & kSnesByteMax) << 8);
|
||||||
|
ushort s2 = ((rom_data_[offset] & kSnesByteMax));
|
||||||
|
int addr = (s1 | s2);
|
||||||
|
|
||||||
if (mode == kNintendoMode1) { // Reversed byte order for overworld maps
|
if (mode == kNintendoMode1) { // Reversed byte order for overworld maps
|
||||||
auto addr = (rom_data_[offset + 2]) | ((rom_data_[offset + 1]) << 8);
|
// addr = (s2 | s1);
|
||||||
if (addr > offset) {
|
addr = (rom_data_[offset + 1]) | ((rom_data_[offset]) << 8);
|
||||||
return absl::InternalError(absl::StrFormat(
|
memcpy(buffer.data() + buffer_pos, buffer.data() + addr, length);
|
||||||
"DecompressOverworld: Offset for command copy exceeds "
|
buffer_pos += length;
|
||||||
"current position (Offset : %#04x | Pos : %#06x)\n",
|
|
||||||
addr, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer_pos + length >= size) {
|
|
||||||
size *= 2;
|
|
||||||
buffer.resize(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(buffer.data() + buffer_pos, rom_data_.data() + addr, length);
|
|
||||||
offset += 2;
|
offset += 2;
|
||||||
} else {
|
break;
|
||||||
ushort s1 = ((rom_data_[offset + 1] & kSnesByteMax) << 8);
|
|
||||||
ushort s2 = ((rom_data_[offset] & kSnesByteMax));
|
|
||||||
auto addr = (s1 | s2);
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
buffer[buffer_pos] = buffer[addr + i];
|
|
||||||
buffer_pos++;
|
|
||||||
}
|
|
||||||
offset += 2; // Advance 2 bytes in the ROM
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr > offset) {
|
||||||
|
return absl::InternalError(absl::StrFormat(
|
||||||
|
"DecompressOverworld: Offset for command copy exceeds "
|
||||||
|
"current position (Offset : %#04x | Pos : %#06x)\n",
|
||||||
|
addr, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer_pos + length >= size) {
|
||||||
|
size *= 2;
|
||||||
|
buffer.resize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
buffer[buffer_pos] = buffer[addr + i];
|
||||||
|
buffer_pos++;
|
||||||
|
}
|
||||||
|
offset += 2; // Advance 2 bytes in the ROM
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
std::cout << absl::StrFormat(
|
std::cout << absl::StrFormat(
|
||||||
@@ -578,166 +582,6 @@ absl::StatusOr<Bytes> ROM::DecompressOverworld(int pos, int size) {
|
|||||||
return Decompress(pos, size, kNintendoMode1);
|
return Decompress(pos, size, kNintendoMode1);
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::StatusOr<Bytes> ROM::CreateAllGfxDataRaw() {
|
|
||||||
// 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 bytes
|
|
||||||
// 113-114 -> compressed 2bpp -> (decompressed each) 0x800 bytes
|
|
||||||
// 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 bytes
|
|
||||||
// 127-217 -> compressed 3bpp sprites -> (decompressed each) 0x600 bytes
|
|
||||||
// 218-222 -> compressed 2bpp -> (decompressed each) 0x800 bytes
|
|
||||||
Bytes buffer(0x54A00);
|
|
||||||
for (int i = 0; i < 0x54A00; ++i) {
|
|
||||||
buffer.push_back(0x00);
|
|
||||||
}
|
|
||||||
int bufferPos = 0;
|
|
||||||
Bytes data(0x600);
|
|
||||||
for (int i = 0; i < 0x600; ++i) {
|
|
||||||
buffer.push_back(0x00);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 223; i++) {
|
|
||||||
bool c = true;
|
|
||||||
if (i >= 0 && i <= 112) // compressed 3bpp bgr
|
|
||||||
{
|
|
||||||
isbpp3[i] = true;
|
|
||||||
} else if (i >= 113 && i <= 114) // compressed 2bpp
|
|
||||||
{
|
|
||||||
isbpp3[i] = false;
|
|
||||||
} else if (i >= 115 && i <= 126) // uncompressed 3bpp sprites
|
|
||||||
{
|
|
||||||
isbpp3[i] = true;
|
|
||||||
c = false;
|
|
||||||
} else if (i >= 127 && i <= 217) // compressed 3bpp sprites
|
|
||||||
{
|
|
||||||
isbpp3[i] = true;
|
|
||||||
} else if (i >= 218 && i <= 222) // compressed 2bpp
|
|
||||||
{
|
|
||||||
isbpp3[i] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c) // if data is compressed decompress it
|
|
||||||
{
|
|
||||||
auto offset = GetGraphicsAddress(rom_data_.data(), i);
|
|
||||||
ASSIGN_OR_RETURN(data, Decompress(offset))
|
|
||||||
} else {
|
|
||||||
data.resize(core::Uncompressed3BPPSize);
|
|
||||||
auto offset = GetGraphicsAddress(rom_data_.data(), i);
|
|
||||||
for (int j = 0; j < core::Uncompressed3BPPSize; j++) {
|
|
||||||
data[j] = rom_data_[j + offset];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < data.size(); j++) {
|
|
||||||
buffer[j + bufferPos] = data[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
bufferPos += data.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::Status ROM::CreateAllGraphicsData() {
|
|
||||||
ASSIGN_OR_RETURN(Bytes data, CreateAllGfxDataRaw())
|
|
||||||
Bytes newData(0x6F800);
|
|
||||||
for (int i = 0; i < 0x6F800; i++) {
|
|
||||||
newData.push_back(0x00);
|
|
||||||
}
|
|
||||||
Bytes mask{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
|
||||||
int sheetPosition = 0;
|
|
||||||
|
|
||||||
// 8x8 tile
|
|
||||||
// Per Sheet
|
|
||||||
for (int s = 0; s < 223; s++) {
|
|
||||||
// Per Tile Line Y
|
|
||||||
for (int j = 0; j < 4; j++) {
|
|
||||||
// Per Tile Line X
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
// Per Pixel Line
|
|
||||||
for (int y = 0; y < 8; y++) {
|
|
||||||
if (isbpp3[s]) {
|
|
||||||
auto lineBits0 =
|
|
||||||
data[(y * 2) + (i * 24) + (j * 384) + sheetPosition];
|
|
||||||
auto lineBits1 =
|
|
||||||
data[(y * 2) + (i * 24) + (j * 384) + 1 + sheetPosition];
|
|
||||||
auto lineBits2 =
|
|
||||||
data[(y) + (i * 24) + (j * 384) + 16 + sheetPosition];
|
|
||||||
|
|
||||||
// Per Pixel X
|
|
||||||
for (int x = 0; x < 4; x++) {
|
|
||||||
auto pixdata = 0;
|
|
||||||
auto pixdata2 = 0;
|
|
||||||
|
|
||||||
if ((lineBits0 & mask[(x * 2)]) == mask[(x * 2)]) {
|
|
||||||
pixdata += 1;
|
|
||||||
}
|
|
||||||
if ((lineBits1 & mask[(x * 2)]) == mask[(x * 2)]) {
|
|
||||||
pixdata += 2;
|
|
||||||
}
|
|
||||||
if ((lineBits2 & mask[(x * 2)]) == mask[(x * 2)]) {
|
|
||||||
pixdata += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((lineBits0 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
|
||||||
pixdata2 += 1;
|
|
||||||
}
|
|
||||||
if ((lineBits1 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
|
||||||
pixdata2 += 2;
|
|
||||||
}
|
|
||||||
if ((lineBits2 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
|
||||||
pixdata2 += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
newData[(y * 64) + (x) + (i * 4) + (j * 512) + (s * 2048)] =
|
|
||||||
((pixdata << 4) | pixdata2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto lineBits0 =
|
|
||||||
data[(y * 2) + (i * 16) + (j * 256) + sheetPosition];
|
|
||||||
auto lineBits1 =
|
|
||||||
data[(y * 2) + (i * 16) + (j * 256) + 1 + sheetPosition];
|
|
||||||
|
|
||||||
// Per Pixel X
|
|
||||||
for (int x = 0; x < 4; x++) {
|
|
||||||
auto pixdata = 0;
|
|
||||||
auto pixdata2 = 0;
|
|
||||||
|
|
||||||
if ((lineBits0 & mask[(x * 2)]) == mask[(x * 2)]) {
|
|
||||||
pixdata += 1;
|
|
||||||
}
|
|
||||||
if ((lineBits1 & mask[(x * 2)]) == mask[(x * 2)]) {
|
|
||||||
pixdata += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((lineBits0 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
|
||||||
pixdata2 += 1;
|
|
||||||
}
|
|
||||||
if ((lineBits1 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
|
||||||
pixdata2 += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
newData[(y * 64) + (x) + (i * 4) + (j * 512) + (s * 2048)] =
|
|
||||||
((pixdata << 4) | pixdata2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isbpp3[s]) {
|
|
||||||
sheetPosition += 0x600;
|
|
||||||
} else {
|
|
||||||
sheetPosition += 0x800;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
graphics_buffer_.reserve(0x6F800);
|
|
||||||
for (int i = 0; i < 0x6F800; i++) {
|
|
||||||
graphics_buffer_.push_back(newData[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return absl::OkStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 chars
|
// 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 chars
|
||||||
// 113-114 -> compressed 2bpp -> (decompressed each) 0x800 chars
|
// 113-114 -> compressed 2bpp -> (decompressed each) 0x800 chars
|
||||||
// 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 chars
|
// 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 chars
|
||||||
@@ -771,11 +615,11 @@ absl::Status ROM::LoadAllGraphicsData() {
|
|||||||
graphics_bin_.at(i).CreateTexture(renderer_);
|
graphics_bin_.at(i).CreateTexture(renderer_);
|
||||||
|
|
||||||
for (int j = 0; j < graphics_bin_.at(i).GetSize(); ++j) {
|
for (int j = 0; j < graphics_bin_.at(i).GetSize(); ++j) {
|
||||||
graphics_8bpp_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
|
graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int j = 0; j < 0x1000; ++j) {
|
for (int j = 0; j < 0x1000; ++j) {
|
||||||
graphics_8bpp_buffer_.push_back(0xFF);
|
graphics_buffer_.push_back(0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -802,6 +646,7 @@ absl::Status ROM::LoadFromFile(const absl::string_view& filename) {
|
|||||||
memcpy(title, rom_data_.data() + kTitleStringOffset, kTitleStringLength);
|
memcpy(title, rom_data_.data() + kTitleStringOffset, kTitleStringLength);
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
LoadAllPalettes();
|
||||||
is_loaded_ = true;
|
is_loaded_ = true;
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
@@ -841,5 +686,129 @@ void ROM::RenderBitmap(gfx::Bitmap* bitmap) const {
|
|||||||
bitmap->CreateTexture(renderer_);
|
bitmap->CreateTexture(renderer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx::SNESColor ROM::ReadColor(int offset) {
|
||||||
|
short color = (short)((rom_data_[offset + 1] << 8) + rom_data_[offset]);
|
||||||
|
gfx::snes_color new_color;
|
||||||
|
new_color.red = (color & 0x1F) * 8;
|
||||||
|
new_color.green = ((color >> 5) & 0x1F) * 8;
|
||||||
|
new_color.blue = ((color >> 10) & 0x1F) * 8;
|
||||||
|
gfx::SNESColor snes_color(new_color);
|
||||||
|
return snes_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::SNESPalette ROM::ReadPalette(int offset, int num_colors) {
|
||||||
|
int color_offset = 0;
|
||||||
|
std::vector<gfx::SNESColor> colors(num_colors);
|
||||||
|
|
||||||
|
while (color_offset < num_colors) {
|
||||||
|
short color = (short)((rom_data_[offset + 1] << 8) + rom_data_[offset]);
|
||||||
|
gfx::snes_color new_color;
|
||||||
|
new_color.red = (color & 0x1F) * 8;
|
||||||
|
new_color.green = ((color >> 5) & 0x1F) * 8;
|
||||||
|
new_color.blue = ((color >> 10) & 0x1F) * 8;
|
||||||
|
colors[color_offset].setSNES(new_color);
|
||||||
|
color_offset++;
|
||||||
|
offset += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
gfx::SNESPalette palette(colors);
|
||||||
|
return palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ROM::LoadAllPalettes() {
|
||||||
|
// 35 colors each, 7x5 (0,2 on grid)
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
palette_groups_["ow_main"].AddPalette(
|
||||||
|
ReadPalette(core::overworldPaletteMain + (i * (35 * 2)), 35));
|
||||||
|
}
|
||||||
|
// 21 colors each, 7x3 (8,2 and 8,5 on grid)
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
palette_groups_["ow_aux"].AddPalette(
|
||||||
|
ReadPalette(core::overworldPaletteAuxialiary + (i * (21 * 2)), 21));
|
||||||
|
}
|
||||||
|
// 7 colors each 7x1 (0,7 on grid)
|
||||||
|
for (int i = 0; i < 14; i++) {
|
||||||
|
palette_groups_["ow_animated"].AddPalette(
|
||||||
|
ReadPalette(core::overworldPaletteAnimated + (i * (7 * 2)), 7));
|
||||||
|
}
|
||||||
|
// 32 colors each 16x2 (0,0 on grid)
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
palette_groups_["hud"].AddPalette(
|
||||||
|
ReadPalette(core::hudPalettes + (i * 64), 32));
|
||||||
|
}
|
||||||
|
|
||||||
|
palette_groups_["global_sprites"].AddPalette(
|
||||||
|
ReadPalette(core::globalSpritePalettesLW, 60));
|
||||||
|
palette_groups_["global_sprites"].AddPalette(
|
||||||
|
ReadPalette(core::globalSpritePalettesDW, 60));
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
palette_groups_["armors"].AddPalette(
|
||||||
|
ReadPalette(core::armorPalettes + (i * 30), 15));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
palette_groups_["swords"].AddPalette(
|
||||||
|
ReadPalette(core::swordPalettes + (i * 6), 3));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
palette_groups_["shields"].AddPalette(
|
||||||
|
ReadPalette(core::shieldPalettes + (i * 8), 4));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
palette_groups_["sprites_aux1"].AddPalette(
|
||||||
|
ReadPalette(core::spritePalettesAux1 + (i * 14), 7));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 11; i++) {
|
||||||
|
palette_groups_["sprites_aux2"].AddPalette(
|
||||||
|
ReadPalette(core::spritePalettesAux2 + (i * 14), 7));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
palette_groups_["sprites_aux3"].AddPalette(
|
||||||
|
ReadPalette(core::spritePalettesAux3 + (i * 14), 7));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 20; i++) {
|
||||||
|
palette_groups_["dungeon_main"].AddPalette(
|
||||||
|
ReadPalette(core::dungeonMainPalettes + (i * 180), 90));
|
||||||
|
}
|
||||||
|
|
||||||
|
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassLW));
|
||||||
|
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassDW));
|
||||||
|
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassSpecial));
|
||||||
|
|
||||||
|
palette_groups_["3d_object"].AddPalette(
|
||||||
|
ReadPalette(core::triforcePalette, 8));
|
||||||
|
palette_groups_["3d_object"].AddPalette(ReadPalette(core::crystalPalette, 8));
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
palette_groups_["ow_mini_map"].AddPalette(
|
||||||
|
ReadPalette(core::overworldMiniMapPalettes + (i * 256), 128));
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check for the paletts in the empty bank space that kan will allocate
|
||||||
|
// and read them in here
|
||||||
|
// TODO magic colors
|
||||||
|
// LW
|
||||||
|
// int j = 0;
|
||||||
|
// while (j < 64) {
|
||||||
|
// zelda3::overworld_BackgroundPalette[j++] =
|
||||||
|
// Color.FromArgb(0xFF, 0x48, 0x98, 0x48);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // DW
|
||||||
|
// while (j < 128) {
|
||||||
|
// zelda3::overworld_BackgroundPalette[j++] =
|
||||||
|
// Color.FromArgb(0xFF, 0x90, 0x88, 0x50);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // SP
|
||||||
|
// while (j < core::kNumOverworldMaps) {
|
||||||
|
// zelda3::overworld_BackgroundPalette[j++] =
|
||||||
|
// Color.FromArgb(0xFF, 0x48, 0x98, 0x48);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// zelda3::overworld_BackgroundPalette =
|
||||||
|
// ReadPalette(core::customAreaSpecificBGPalette, 160);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -77,22 +77,23 @@ class ROM {
|
|||||||
absl::StatusOr<Bytes> DecompressOverworld(int pos, int size);
|
absl::StatusOr<Bytes> DecompressOverworld(int pos, int size);
|
||||||
|
|
||||||
absl::Status LoadAllGraphicsData();
|
absl::Status LoadAllGraphicsData();
|
||||||
|
|
||||||
absl::StatusOr<Bytes> CreateAllGfxDataRaw();
|
|
||||||
absl::Status CreateAllGraphicsData();
|
|
||||||
|
|
||||||
absl::Status LoadFromFile(const absl::string_view& filename);
|
absl::Status LoadFromFile(const absl::string_view& filename);
|
||||||
absl::Status LoadFromPointer(uchar* data, size_t length);
|
absl::Status LoadFromPointer(uchar* data, size_t length);
|
||||||
absl::Status LoadFromBytes(const Bytes& data);
|
absl::Status LoadFromBytes(const Bytes& data);
|
||||||
|
void LoadAllPalettes();
|
||||||
|
|
||||||
absl::Status SaveToFile();
|
absl::Status SaveToFile();
|
||||||
|
|
||||||
|
gfx::SNESColor ReadColor(int offset);
|
||||||
|
gfx::SNESPalette ReadPalette(int offset, int num_colors);
|
||||||
|
|
||||||
void RenderBitmap(gfx::Bitmap* bitmap) const;
|
void RenderBitmap(gfx::Bitmap* bitmap) const;
|
||||||
|
|
||||||
auto GetSize() const { return size_; }
|
auto GetSize() const { return size_; }
|
||||||
auto GetTitle() const { return title; }
|
auto GetTitle() const { return title; }
|
||||||
auto GetGraphicsBin() const { return graphics_bin_; }
|
auto GetGraphicsBin() const { return graphics_bin_; }
|
||||||
auto GetGraphicsBuffer() const { return graphics_buffer_; }
|
auto GetGraphicsBuffer() const { return graphics_buffer_; }
|
||||||
auto GetGraphics8BPP() const { return graphics_8bpp_buffer_; }
|
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) {
|
||||||
renderer_ = renderer;
|
renderer_ = renderer;
|
||||||
}
|
}
|
||||||
@@ -117,6 +118,10 @@ class ROM {
|
|||||||
}
|
}
|
||||||
const uchar* operator&() { return rom_data_.data(); }
|
const uchar* operator&() { return rom_data_.data(); }
|
||||||
|
|
||||||
|
ushort toint16(int offset) {
|
||||||
|
return (ushort)((rom_data_[offset + 1]) << 8) | rom_data_[offset];
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
long size_ = 0;
|
long size_ = 0;
|
||||||
uchar title[21] = "ROM Not Loaded";
|
uchar title[21] = "ROM Not Loaded";
|
||||||
@@ -126,9 +131,9 @@ class ROM {
|
|||||||
|
|
||||||
Bytes rom_data_;
|
Bytes rom_data_;
|
||||||
Bytes graphics_buffer_;
|
Bytes graphics_buffer_;
|
||||||
Bytes graphics_8bpp_buffer_;
|
|
||||||
std::shared_ptr<SDL_Renderer> renderer_;
|
std::shared_ptr<SDL_Renderer> renderer_;
|
||||||
std::unordered_map<int, gfx::Bitmap> graphics_bin_;
|
std::unordered_map<int, gfx::Bitmap> graphics_bin_;
|
||||||
|
std::unordered_map<std::string, gfx::PaletteGroup> palette_groups_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|||||||
@@ -88,13 +88,13 @@ void Overworld::AssembleMap32Tiles() {
|
|||||||
void Overworld::AssembleMap16Tiles() {
|
void Overworld::AssembleMap16Tiles() {
|
||||||
int tpos = core::map16Tiles;
|
int tpos = core::map16Tiles;
|
||||||
for (int i = 0; i < 4096; i += 1) {
|
for (int i = 0; i < 4096; i += 1) {
|
||||||
auto t0 = gfx::GetTilesInfo((uintptr_t)(rom_ + tpos));
|
auto t0 = gfx::GetTilesInfo((rom_.toint16(tpos)));
|
||||||
tpos += 2;
|
tpos += 2;
|
||||||
auto t1 = gfx::GetTilesInfo((uintptr_t)(rom_ + tpos));
|
auto t1 = gfx::GetTilesInfo((rom_.toint16(tpos)));
|
||||||
tpos += 2;
|
tpos += 2;
|
||||||
auto t2 = gfx::GetTilesInfo((uintptr_t)(rom_ + tpos));
|
auto t2 = gfx::GetTilesInfo((rom_.toint16(tpos)));
|
||||||
tpos += 2;
|
tpos += 2;
|
||||||
auto t3 = gfx::GetTilesInfo((uintptr_t)(rom_ + tpos));
|
auto t3 = gfx::GetTilesInfo((rom_.toint16(tpos)));
|
||||||
tpos += 2;
|
tpos += 2;
|
||||||
tiles16.emplace_back(t0, t1, t2, t3);
|
tiles16.emplace_back(t0, t1, t2, t3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,11 @@ class Overworld {
|
|||||||
auto GetCurrentBitmapData() const {
|
auto GetCurrentBitmapData() const {
|
||||||
return overworld_maps_[current_map_].GetBitmapData();
|
return overworld_maps_[current_map_].GetBitmapData();
|
||||||
}
|
}
|
||||||
|
auto GetCurrentPalette() const {
|
||||||
|
return overworld_maps_[current_map_].GetCurrentPalette();
|
||||||
|
}
|
||||||
auto isLoaded() const { return is_loaded_; }
|
auto isLoaded() const { return is_loaded_; }
|
||||||
|
void SetCurrentMap(int i) { current_map_ = i; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int map32address[4] = {core::map32TilesTL, core::map32TilesTR,
|
const int map32address[4] = {core::map32TilesTL, core::map32TilesTR,
|
||||||
|
|||||||
@@ -19,41 +19,132 @@ namespace zelda3 {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void CopyTile(int x, int y, int xx, int yy, int offset, gfx::TileInfo tile,
|
void CopyTile8bpp16(int x, int y, int tile, Bytes& bitmap, Bytes& blockset) {
|
||||||
Bytes& ow_blockset, Bytes& current_gfx) {
|
int src_pos =
|
||||||
int mx = x;
|
((tile - ((tile / 0x08) * 0x08)) * 0x10) + ((tile / 0x08) * 2048);
|
||||||
int my = y;
|
int dest_pos = (x + (y * 0x200));
|
||||||
uchar r = 0;
|
for (int yy = 0; yy < 0x10; yy++) {
|
||||||
|
for (int xx = 0; xx < 0x10; xx++) {
|
||||||
if (tile.horizontal_mirror_ != 0) {
|
bitmap[dest_pos + xx + (yy * 0x200)] =
|
||||||
mx = 3 - x;
|
blockset[src_pos + xx + (yy * 0x80)];
|
||||||
r = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile.vertical_mirror_ != 0) {
|
|
||||||
my = 7 - y;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tx = ((tile.id_ / 16) * 512) + ((tile.id_ - ((tile.id_ / 16) * 16)) * 4);
|
|
||||||
auto index = xx + yy + offset + (mx * 2) + (my * 0x80);
|
|
||||||
auto pixel = current_gfx[tx + (y * 64) + x];
|
|
||||||
|
|
||||||
auto p1 = index + r ^ 1;
|
|
||||||
ow_blockset[p1] = (uchar)((pixel & 0x0F) + tile.palette_ * 16);
|
|
||||||
auto p2 = index + r;
|
|
||||||
ow_blockset[p2] = (uchar)(((pixel >> 4) & 0x0F) + tile.palette_ * 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CopyTile8bpp16(int x, int y, int tile, Bytes& dest, Bytes& src) {
|
|
||||||
int src_pos = ((tile - ((tile / 8) * 8)) * 16) + ((tile / 8) * 2048);
|
|
||||||
int dest_pos = (x + (y * 512));
|
|
||||||
for (int yy = 0; yy < 16; yy++) {
|
|
||||||
for (int xx = 0; xx < 16; xx++) {
|
|
||||||
dest[dest_pos + xx + (yy * 512)] = src[src_pos + xx + (yy * 0x80)];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetColorsPalette(ROM& rom, int index, gfx::SNESPalette& current,
|
||||||
|
gfx::SNESPalette main, gfx::SNESPalette animated,
|
||||||
|
gfx::SNESPalette aux1, gfx::SNESPalette aux2,
|
||||||
|
gfx::SNESPalette hud, gfx::SNESColor bgrcolor,
|
||||||
|
gfx::SNESPalette spr, gfx::SNESPalette spr2) {
|
||||||
|
// Palettes infos, color 0 of a palette is always transparent (the arrays
|
||||||
|
// contains 7 colors width wide) There is 16 color per line so 16*Y
|
||||||
|
|
||||||
|
// Left side of the palette - Main, Animated
|
||||||
|
std::vector<gfx::SNESColor> new_palette(256);
|
||||||
|
|
||||||
|
// Main Palette, Location 0,2 : 35 colors [7x5]
|
||||||
|
int k = 0;
|
||||||
|
for (int y = 2; y < 7; y++) {
|
||||||
|
for (int x = 1; x < 8; x++) {
|
||||||
|
new_palette[x + (16 * y)] = main[k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animated Palette, Location 0,7 : 7colors
|
||||||
|
for (int x = 1; x < 8; x++) {
|
||||||
|
new_palette[(16 * 7) + (x)] = animated[(x - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right side of the palette - Aux1, Aux2
|
||||||
|
|
||||||
|
// Aux1 Palette, Location 8,2 : 21 colors [7x3]
|
||||||
|
k = 0;
|
||||||
|
for (int y = 2; y < 5; y++) {
|
||||||
|
for (int x = 9; x < 16; x++) {
|
||||||
|
new_palette[x + (16 * y)] = aux1[k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aux2 Palette, Location 8,5 : 21 colors [7x3]
|
||||||
|
k = 0;
|
||||||
|
for (int y = 5; y < 8; y++) {
|
||||||
|
for (int x = 9; x < 16; x++) {
|
||||||
|
new_palette[x + (16 * y)] = aux2[k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hud Palette, Location 0,0 : 32 colors [16x2]
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
new_palette[i] = hud[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hardcoded grass color (that might change to become invisible instead)
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
new_palette[(i * 16)] = bgrcolor;
|
||||||
|
new_palette[(i * 16) + 8] = bgrcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite Palettes
|
||||||
|
k = 0;
|
||||||
|
for (int y = 8; y < 9; y++) {
|
||||||
|
for (int x = 1; x < 8; x++) {
|
||||||
|
new_palette[x + (16 * y)] = rom.GetPaletteGroup("sprites_aux1")[1][k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite Palettes
|
||||||
|
k = 0;
|
||||||
|
for (int y = 8; y < 9; y++) {
|
||||||
|
for (int x = 9; x < 16; x++) {
|
||||||
|
new_palette[x + (16 * y)] = rom.GetPaletteGroup("sprites_aux3")[0][k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite Palettes
|
||||||
|
k = 0;
|
||||||
|
for (int y = 9; y < 13; y++) {
|
||||||
|
for (int x = 1; x < 16; x++) {
|
||||||
|
new_palette[x + (16 * y)] = rom.GetPaletteGroup("global_sprites")[0][k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite Palettes
|
||||||
|
k = 0;
|
||||||
|
for (int y = 13; y < 14; y++) {
|
||||||
|
for (int x = 1; x < 8; x++) {
|
||||||
|
new_palette[x + (16 * y)] = spr[k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite Palettes
|
||||||
|
k = 0;
|
||||||
|
for (int y = 14; y < 15; y++) {
|
||||||
|
for (int x = 1; x < 8; x++) {
|
||||||
|
new_palette[x + (16 * y)] = spr2[k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite Palettes
|
||||||
|
k = 0;
|
||||||
|
for (int y = 15; y < 16; y++) {
|
||||||
|
for (int x = 1; x < 16; x++) {
|
||||||
|
new_palette[x + (16 * y)] = rom.GetPaletteGroup("armors")[0][k++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current.Create(new_palette);
|
||||||
|
// ColorPalette pal = GFX.editort16Bitmap.Palette;
|
||||||
|
// for (int i = 0; i < 256; i++) {
|
||||||
|
// pal.Entries[i] = new_palette[i];
|
||||||
|
// pal.Entries[(i / 16) * 16] = Color.Transparent;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// GFX.mapgfx16Bitmap.Palette = pal;
|
||||||
|
// GFX.mapblockset16Bitmap.Palette = pal;
|
||||||
|
|
||||||
|
// gfxBitmap.Palette = pal;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
OverworldMap::OverworldMap(int index, ROM& rom,
|
OverworldMap::OverworldMap(int index, ROM& rom,
|
||||||
@@ -74,8 +165,8 @@ absl::Status OverworldMap::BuildMap(int count, int game_state, int world,
|
|||||||
rom_[core::overworldSpecialGFXGroup + (parent_ - 0x80)];
|
rom_[core::overworldSpecialGFXGroup + (parent_ - 0x80)];
|
||||||
area_palette_ = rom_[core::overworldSpecialPALGroup + 1];
|
area_palette_ = rom_[core::overworldSpecialPALGroup + 1];
|
||||||
} else if (index_ == 0x88) {
|
} else if (index_ == 0x88) {
|
||||||
area_graphics_ = 81;
|
area_graphics_ = 0x51;
|
||||||
area_palette_ = 0;
|
area_palette_ = 0x00;
|
||||||
} else {
|
} else {
|
||||||
area_graphics_ = rom_[core::mapGfx + parent_];
|
area_graphics_ = rom_[core::mapGfx + parent_];
|
||||||
area_palette_ = rom_[core::overworldMapPalette + parent_];
|
area_palette_ = rom_[core::overworldMapPalette + parent_];
|
||||||
@@ -91,12 +182,13 @@ absl::Status OverworldMap::BuildMap(int count, int game_state, int world,
|
|||||||
} else if (parent_ >= 0x40 && parent_ < 0x80) {
|
} else if (parent_ >= 0x40 && parent_ < 0x80) {
|
||||||
world_index = 0x21;
|
world_index = 0x21;
|
||||||
} else if (parent_ == 0x88) {
|
} else if (parent_ == 0x88) {
|
||||||
world_index = 36;
|
world_index = 0x24;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadAreaGraphics(game_state, world_index);
|
LoadAreaGraphics(game_state, world_index);
|
||||||
RETURN_IF_ERROR(BuildTileset())
|
RETURN_IF_ERROR(BuildTileset())
|
||||||
RETURN_IF_ERROR(BuildTiles16Gfx(count))
|
RETURN_IF_ERROR(BuildTiles16Gfx(count))
|
||||||
|
LoadPalette();
|
||||||
RETURN_IF_ERROR(BuildBitmap(world_blockset))
|
RETURN_IF_ERROR(BuildBitmap(world_blockset))
|
||||||
built_ = true;
|
built_ = true;
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
@@ -117,11 +209,11 @@ void OverworldMap::LoadAreaInfo() {
|
|||||||
area_music_[3] = rom_[core::overworldMusicAgahim + parent_];
|
area_music_[3] = rom_[core::overworldMusicAgahim + parent_];
|
||||||
|
|
||||||
sprite_graphics_[0] = rom_[core::overworldSpriteset + parent_];
|
sprite_graphics_[0] = rom_[core::overworldSpriteset + parent_];
|
||||||
sprite_graphics_[1] = rom_[core::overworldSpriteset + parent_ + 64];
|
sprite_graphics_[1] = rom_[core::overworldSpriteset + parent_ + 0x40];
|
||||||
sprite_graphics_[2] = rom_[core::overworldSpriteset + parent_ + 0x80];
|
sprite_graphics_[2] = rom_[core::overworldSpriteset + parent_ + 0x80];
|
||||||
|
|
||||||
sprite_palette_[0] = rom_[core::overworldSpritePalette + parent_];
|
sprite_palette_[0] = rom_[core::overworldSpritePalette + parent_];
|
||||||
sprite_palette_[1] = rom_[core::overworldSpritePalette + parent_ + 64];
|
sprite_palette_[1] = rom_[core::overworldSpritePalette + parent_ + 0x40];
|
||||||
sprite_palette_[2] = rom_[core::overworldSpritePalette + parent_ + 0x80];
|
sprite_palette_[2] = rom_[core::overworldSpritePalette + parent_ + 0x80];
|
||||||
} else if (index_ < 0x80) {
|
} else if (index_ < 0x80) {
|
||||||
area_graphics_ = rom_[core::mapGfx + parent_];
|
area_graphics_ = rom_[core::mapGfx + parent_];
|
||||||
@@ -183,14 +275,14 @@ void OverworldMap::LoadAreaInfo() {
|
|||||||
|
|
||||||
void OverworldMap::LoadAreaGraphics(int game_state, int world_index) {
|
void OverworldMap::LoadAreaGraphics(int game_state, int world_index) {
|
||||||
// Sprites Blocksets
|
// Sprites Blocksets
|
||||||
static_graphics_[8] = 115 + 0;
|
static_graphics_[8] = 0x73 + 0x00;
|
||||||
static_graphics_[9] = 115 + 1;
|
static_graphics_[9] = 0x73 + 0x01;
|
||||||
static_graphics_[10] = 115 + 6;
|
static_graphics_[10] = 0x73 + 0x06;
|
||||||
static_graphics_[11] = 115 + 7;
|
static_graphics_[11] = 0x73 + 0x07;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
static_graphics_[12 + i] = (rom_[core::kSpriteBlocksetPointer +
|
static_graphics_[12 + i] = (rom_[core::kSpriteBlocksetPointer +
|
||||||
(sprite_graphics_[game_state] * 4) + i] +
|
(sprite_graphics_[game_state] * 4) + i] +
|
||||||
115);
|
0x73);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main Blocksets
|
// Main Blocksets
|
||||||
@@ -218,62 +310,200 @@ void OverworldMap::LoadAreaGraphics(int game_state, int world_index) {
|
|||||||
// Hardcoded overworld GFX Values, for death mountain
|
// Hardcoded overworld GFX Values, for death mountain
|
||||||
if ((parent_ >= 0x03 && parent_ <= 0x07) ||
|
if ((parent_ >= 0x03 && parent_ <= 0x07) ||
|
||||||
(parent_ >= 0x0B && parent_ <= 0x0E)) {
|
(parent_ >= 0x0B && parent_ <= 0x0E)) {
|
||||||
static_graphics_[7] = 89;
|
static_graphics_[7] = 0x59;
|
||||||
} else if ((parent_ >= 0x43 && parent_ <= 0x47) ||
|
} else if ((parent_ >= 0x43 && parent_ <= 0x47) ||
|
||||||
(parent_ >= 0x4B && parent_ <= 0x4E)) {
|
(parent_ >= 0x4B && parent_ <= 0x4E)) {
|
||||||
static_graphics_[7] = 89;
|
static_graphics_[7] = 0x59;
|
||||||
} else {
|
} else {
|
||||||
static_graphics_[7] = 91;
|
static_graphics_[7] = 0x5B;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OverworldMap::BuildTileset() {
|
void OverworldMap::LoadPalette() {
|
||||||
for (int i = 0; i < 16; i++) {
|
int previousPalId = 0;
|
||||||
auto sheet = rom_.GetGraphicsBin().at(static_graphics_[i]);
|
int previousSprPalId = 0;
|
||||||
current_graphics_sheet_set[i] = sheet;
|
if (index_ > 0) {
|
||||||
|
previousPalId = rom_[core::overworldMapPalette + parent_ - 1];
|
||||||
|
previousSprPalId = rom_[core::overworldSpritePalette + parent_ - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
all_gfx_ = rom_.GetGraphics8BPP();
|
if (area_palette_ >= 0xA3) {
|
||||||
|
area_palette_ = 0xA3;
|
||||||
|
}
|
||||||
|
|
||||||
current_gfx_.reserve(32768);
|
uchar pal0 = 0;
|
||||||
for (int i = 0; i < 32768; i++) {
|
|
||||||
|
uchar pal1 =
|
||||||
|
rom_[core::overworldMapPaletteGroup + (area_palette_ * 4)]; // aux1
|
||||||
|
uchar pal2 =
|
||||||
|
rom_[core::overworldMapPaletteGroup + (area_palette_ * 4) + 1]; // aux2
|
||||||
|
uchar pal3 = rom_[core::overworldMapPaletteGroup + (area_palette_ * 4) +
|
||||||
|
2]; // animated
|
||||||
|
|
||||||
|
uchar pal4 = rom_[core::overworldSpritePaletteGroup +
|
||||||
|
(sprite_palette_[game_state_] * 2)]; // spr3
|
||||||
|
uchar pal5 = rom_[core::overworldSpritePaletteGroup +
|
||||||
|
(sprite_palette_[game_state_] * 2) + 1]; // spr4
|
||||||
|
|
||||||
|
gfx::SNESPalette aux1;
|
||||||
|
gfx::SNESPalette aux2;
|
||||||
|
gfx::SNESPalette main;
|
||||||
|
gfx::SNESPalette animated;
|
||||||
|
gfx::SNESPalette hud;
|
||||||
|
gfx::SNESPalette spr;
|
||||||
|
gfx::SNESPalette spr2;
|
||||||
|
gfx::SNESColor bgr = rom_.GetPaletteGroup("grass")[0].GetColor(0);
|
||||||
|
|
||||||
|
if (pal1 == 255) {
|
||||||
|
pal1 = rom_[core::overworldMapPaletteGroup + (previousPalId * 4)];
|
||||||
|
}
|
||||||
|
if (pal1 != 255) {
|
||||||
|
if (pal1 >= 20) {
|
||||||
|
pal1 = 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
aux1 = rom_.GetPaletteGroup("ow_aux")[pal1];
|
||||||
|
} else {
|
||||||
|
aux1 = rom_.GetPaletteGroup("ow_aux")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pal2 == 255) {
|
||||||
|
pal2 = rom_[core::overworldMapPaletteGroup + (previousPalId * 4) + 1];
|
||||||
|
}
|
||||||
|
if (pal2 != 255) {
|
||||||
|
if (pal2 >= 20) {
|
||||||
|
pal2 = 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
aux2 = rom_.GetPaletteGroup("ow_aux")[pal2];
|
||||||
|
} else {
|
||||||
|
aux2 = rom_.GetPaletteGroup("ow_aux")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pal3 == 255) {
|
||||||
|
pal3 = rom_[core::overworldMapPaletteGroup + (previousPalId * 4) + 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent_ < 0x40) {
|
||||||
|
// Default LW Palette
|
||||||
|
pal0 = 0;
|
||||||
|
|
||||||
|
if (parent_ == 0x03 || parent_ == 0x05 || parent_ == 0x07) {
|
||||||
|
pal0 = 2;
|
||||||
|
}
|
||||||
|
} else if (parent_ >= 0x40 && parent_ < 0x80) {
|
||||||
|
// Default DW Palette
|
||||||
|
pal0 = 1;
|
||||||
|
bgr = rom_.GetPaletteGroup("grass")[0].GetColor(1);
|
||||||
|
if (parent_ == 0x43 || parent_ == 0x45 || parent_ == 0x47) {
|
||||||
|
pal0 = 3;
|
||||||
|
}
|
||||||
|
} else if (parent_ >= 128 && parent_ < core::kNumOverworldMaps) {
|
||||||
|
// Default SP Palette
|
||||||
|
pal0 = 0;
|
||||||
|
bgr = rom_.GetPaletteGroup("grass")[0].GetColor(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent_ == 0x88) {
|
||||||
|
pal0 = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pal0 != 255) {
|
||||||
|
main = rom_.GetPaletteGroup("ow_main")[pal0];
|
||||||
|
} else {
|
||||||
|
main = rom_.GetPaletteGroup("ow_main")[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pal3 >= 14) {
|
||||||
|
pal3 = 13;
|
||||||
|
}
|
||||||
|
animated = rom_.GetPaletteGroup("ow_animated")[(pal3)];
|
||||||
|
|
||||||
|
hud = rom_.GetPaletteGroup("hud")[0];
|
||||||
|
if (pal4 == 255) {
|
||||||
|
pal4 = rom_[core::overworldSpritePaletteGroup +
|
||||||
|
(previousSprPalId * 2)]; // spr3
|
||||||
|
}
|
||||||
|
if (pal4 == 255) {
|
||||||
|
pal4 = 0;
|
||||||
|
}
|
||||||
|
if (pal4 >= 24) {
|
||||||
|
pal4 = 23;
|
||||||
|
}
|
||||||
|
spr = rom_.GetPaletteGroup("sprites_aux3")[pal4];
|
||||||
|
|
||||||
|
if (pal5 == 255) {
|
||||||
|
pal5 = rom_[core::overworldSpritePaletteGroup + (previousSprPalId * 2) +
|
||||||
|
1]; // spr3
|
||||||
|
}
|
||||||
|
if (pal5 == 255) {
|
||||||
|
pal5 = 0;
|
||||||
|
}
|
||||||
|
if (pal5 >= 24) {
|
||||||
|
pal5 = 23;
|
||||||
|
}
|
||||||
|
spr2 = rom_.GetPaletteGroup("sprites_aux3")[pal5];
|
||||||
|
|
||||||
|
SetColorsPalette(rom_, parent_, current_palette_, main, animated, aux1, aux2,
|
||||||
|
hud, bgr, spr, spr2);
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status OverworldMap::BuildTileset() {
|
||||||
|
all_gfx_ = rom_.GetGraphicsBuffer();
|
||||||
|
current_gfx_.reserve(0x10000);
|
||||||
|
for (int i = 0; i < 0x10000; i++) {
|
||||||
current_gfx_.push_back(0x00);
|
current_gfx_.push_back(0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 32; i++) {
|
for (int i = 0; i < 0x10; i++) {
|
||||||
for (int j = 0; j < 4096; j++) {
|
for (int j = 0; j < 0x1000; j++) {
|
||||||
current_gfx_[(i * 4096) + j] = all_gfx_[j + (static_graphics_[i] * 4096)];
|
current_gfx_[(i * 0x1000) + j] =
|
||||||
|
all_gfx_[j + (static_graphics_[i] * 0x1000)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OverworldMap::BuildTiles16Gfx(int count) {
|
absl::Status OverworldMap::BuildTiles16Gfx(int count) {
|
||||||
current_blockset_.reserve(1048576);
|
current_blockset_.reserve(0x100000);
|
||||||
for (int i = 0; i < 1048576; i++) {
|
for (int i = 0; i < 0x100000; i++) {
|
||||||
current_blockset_.push_back(0x00);
|
current_blockset_.push_back(0x00);
|
||||||
}
|
}
|
||||||
int offsets[] = {0, 8, 1024, 1032};
|
const int offsets[] = {0x00, 0x08, 0x400, 0x408};
|
||||||
auto yy = 0;
|
auto yy = 0;
|
||||||
auto xx = 0;
|
auto xx = 0;
|
||||||
|
|
||||||
// number of tiles16 3748?
|
|
||||||
for (auto i = 0; i < count; i++) {
|
for (auto i = 0; i < count; i++) {
|
||||||
// 8x8 tile draw, gfx8 = 4bpp so everyting is /2F
|
for (auto tile = 0; tile < 0x04; tile++) {
|
||||||
for (auto tile = 0; tile < 4; tile++) {
|
|
||||||
gfx::TileInfo info = tiles16_[i].tiles_info[tile];
|
gfx::TileInfo info = tiles16_[i].tiles_info[tile];
|
||||||
int offset = offsets[tile];
|
int offset = offsets[tile];
|
||||||
|
for (auto y = 0; y < 0x08; ++y) {
|
||||||
|
for (auto x = 0; x < 0x08; ++x) {
|
||||||
|
int mx = x;
|
||||||
|
int my = y;
|
||||||
|
|
||||||
for (auto y = 0; y < 8; y++) {
|
if (info.horizontal_mirror_ != 0) {
|
||||||
for (auto x = 0; x < 4; x++) {
|
mx = 0x07 - x;
|
||||||
CopyTile(x, y, xx, yy, offset, info, current_blockset_, current_gfx_);
|
}
|
||||||
|
|
||||||
|
if (info.vertical_mirror_ != 0) {
|
||||||
|
my = 0x07 - y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xpos = ((info.id_ % 0x10) * 0x08);
|
||||||
|
int ypos = (((info.id_ / 0x10)) * 0x400);
|
||||||
|
int source = ypos + xpos + (x + (y * 0x80));
|
||||||
|
|
||||||
|
auto destination = xx + yy + offset + (mx + (my * 0x80));
|
||||||
|
current_blockset_[destination] =
|
||||||
|
current_gfx_[source] + (info.palette_ * 0x10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xx += 16;
|
xx += 0x10;
|
||||||
if (xx >= 0x80) {
|
if (xx >= 0x80) {
|
||||||
yy += 2048;
|
yy += 0x800;
|
||||||
xx = 0;
|
xx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -282,20 +512,20 @@ absl::Status OverworldMap::BuildTiles16Gfx(int count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
absl::Status OverworldMap::BuildBitmap(OWBlockset& world_blockset) {
|
absl::Status OverworldMap::BuildBitmap(OWBlockset& world_blockset) {
|
||||||
bitmap_data_.reserve(262144);
|
bitmap_data_.reserve(0x40000);
|
||||||
for (int i = 0; i < 262144; i++) {
|
for (int i = 0; i < 0x40000; i++) {
|
||||||
bitmap_data_.push_back(0x00);
|
bitmap_data_.push_back(0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
int superY = ((index_ - (world_ * 64)) / 8);
|
int superY = ((index_ - (world_ * 0x40)) / 0x08);
|
||||||
int superX = index_ - (world_ * 64) - (superY * 8);
|
int superX = index_ - (world_ * 0x40) - (superY * 0x08);
|
||||||
|
|
||||||
for (int y = 0; y < 32; y++) {
|
for (int y = 0; y < 0x20; y++) {
|
||||||
for (int x = 0; x < 32; x++) {
|
for (int x = 0; x < 0x20; x++) {
|
||||||
auto xt = x + (superX * 32);
|
auto xt = x + (superX * 0x20);
|
||||||
auto yt = y + (superY * 32);
|
auto yt = y + (superY * 0x20);
|
||||||
CopyTile8bpp16((x * 16), (y * 16), world_blockset[xt][yt], bitmap_data_,
|
CopyTile8bpp16((x * 0x10), (y * 0x10), world_blockset[xt][yt],
|
||||||
current_blockset_);
|
bitmap_data_, current_blockset_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ class OverworldMap {
|
|||||||
absl::Status BuildMap(int count, int game_state, int world, uchar* map_parent,
|
absl::Status BuildMap(int count, int game_state, int world, uchar* map_parent,
|
||||||
OWBlockset& world_blockset);
|
OWBlockset& world_blockset);
|
||||||
|
|
||||||
auto GetCurrentGraphicsSet() const { return current_graphics_sheet_set; }
|
|
||||||
auto GetCurrentBlockset() const { return current_blockset_; }
|
auto GetCurrentBlockset() const { return current_blockset_; }
|
||||||
auto GetCurrentGraphics() const { return current_gfx_; }
|
auto GetCurrentGraphics() const { return current_gfx_; }
|
||||||
|
auto GetCurrentPalette() const { return current_palette_; }
|
||||||
auto GetBitmapData() const { return bitmap_data_; }
|
auto GetBitmapData() const { return bitmap_data_; }
|
||||||
auto SetLargeMap(bool is_set) { large_map_ = is_set; }
|
auto SetLargeMap(bool is_set) { large_map_ = is_set; }
|
||||||
auto IsLargeMap() const { return large_map_; }
|
auto IsLargeMap() const { return large_map_; }
|
||||||
@@ -40,6 +40,7 @@ class OverworldMap {
|
|||||||
private:
|
private:
|
||||||
void LoadAreaInfo();
|
void LoadAreaInfo();
|
||||||
void LoadAreaGraphics(int game_state, int world_index);
|
void LoadAreaGraphics(int game_state, int world_index);
|
||||||
|
void LoadPalette();
|
||||||
|
|
||||||
absl::Status BuildTileset();
|
absl::Status BuildTileset();
|
||||||
absl::Status BuildTiles16Gfx(int count);
|
absl::Status BuildTiles16Gfx(int count);
|
||||||
@@ -52,6 +53,9 @@ class OverworldMap {
|
|||||||
int area_graphics_ = 0;
|
int area_graphics_ = 0;
|
||||||
int area_palette_ = 0;
|
int area_palette_ = 0;
|
||||||
|
|
||||||
|
// TODO SET ME
|
||||||
|
int game_state_ = 0;
|
||||||
|
|
||||||
uchar sprite_graphics_[3];
|
uchar sprite_graphics_[3];
|
||||||
uchar sprite_palette_[3];
|
uchar sprite_palette_[3];
|
||||||
uchar area_music_[4];
|
uchar area_music_[4];
|
||||||
@@ -68,8 +72,9 @@ class OverworldMap {
|
|||||||
Bytes bitmap_data_;
|
Bytes bitmap_data_;
|
||||||
OWMapTiles map_tiles_;
|
OWMapTiles map_tiles_;
|
||||||
|
|
||||||
|
gfx::SNESPalette current_palette_;
|
||||||
|
|
||||||
std::vector<gfx::Tile16> tiles16_;
|
std::vector<gfx::Tile16> tiles16_;
|
||||||
std::unordered_map<int, gfx::Bitmap> current_graphics_sheet_set;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace zelda3
|
} // namespace zelda3
|
||||||
|
|||||||
@@ -37,15 +37,14 @@ void Canvas::DrawContextMenu() {
|
|||||||
io.MousePos.y - origin.y);
|
io.MousePos.y - origin.y);
|
||||||
|
|
||||||
// Add first and second point
|
// Add first and second point
|
||||||
if (is_hovered && !dragging_select_ &&
|
if (is_hovered && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||||
ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
ImVec2 draw_tile_outline_pos;
|
||||||
points_.push_back(mouse_pos_in_canvas);
|
draw_tile_outline_pos.x = std::round((double)mouse_pos_in_canvas.x / 32) * 32;
|
||||||
points_.push_back(mouse_pos_in_canvas);
|
draw_tile_outline_pos.y = std::round((double)mouse_pos_in_canvas.y / 32) * 32;
|
||||||
dragging_select_ = true;
|
|
||||||
}
|
points_.push_back(draw_tile_outline_pos);
|
||||||
if (dragging_select_) {
|
points_.push_back(
|
||||||
points_.back() = mouse_pos_in_canvas;
|
ImVec2(draw_tile_outline_pos.x + 32, draw_tile_outline_pos.y + 32));
|
||||||
if (!ImGui::IsMouseDown(ImGuiMouseButton_Left)) dragging_select_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pan (we use a zero mouse threshold when there's no context menu)
|
// Pan (we use a zero mouse threshold when there's no context menu)
|
||||||
@@ -60,9 +59,8 @@ void Canvas::DrawContextMenu() {
|
|||||||
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
|
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
|
||||||
if (enable_context_menu_ && drag_delta.x == 0.0f && drag_delta.y == 0.0f)
|
if (enable_context_menu_ && drag_delta.x == 0.0f && drag_delta.y == 0.0f)
|
||||||
ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
|
ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
|
||||||
|
|
||||||
if (ImGui::BeginPopup("context")) {
|
if (ImGui::BeginPopup("context")) {
|
||||||
if (dragging_select_) points_.resize(points_.size() - 2);
|
|
||||||
dragging_select_ = false;
|
|
||||||
if (ImGui::MenuItem("Remove all", nullptr, false, points_.Size > 0)) {
|
if (ImGui::MenuItem("Remove all", nullptr, false, points_.Size > 0)) {
|
||||||
points_.clear();
|
points_.clear();
|
||||||
}
|
}
|
||||||
@@ -78,6 +76,21 @@ void Canvas::DrawBitmap(const Bitmap &bitmap, int border_offset) {
|
|||||||
canvas_p0_.y + (bitmap.GetHeight() * 2)));
|
canvas_p0_.y + (bitmap.GetHeight() * 2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::DrawBitmap(const Bitmap &bitmap, int x_offset, int y_offset) {
|
||||||
|
draw_list_->AddImage(
|
||||||
|
(void *)bitmap.GetTexture(),
|
||||||
|
ImVec2(canvas_p0_.x + x_offset + scrolling_.x,
|
||||||
|
canvas_p0_.y + y_offset + scrolling_.y),
|
||||||
|
ImVec2(canvas_p0_.x + x_offset + scrolling_.x + (bitmap.GetWidth()),
|
||||||
|
canvas_p0_.y + y_offset + scrolling_.y + (bitmap.GetHeight())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::DrawOutline(int x, int y, int w, int h) {
|
||||||
|
ImVec2 origin(x, y);
|
||||||
|
ImVec2 size(x + w, y + h);
|
||||||
|
draw_list_->AddRect(origin, size, IM_COL32(255, 255, 255, 255));
|
||||||
|
}
|
||||||
|
|
||||||
void Canvas::DrawGrid(float grid_step) {
|
void Canvas::DrawGrid(float grid_step) {
|
||||||
// Draw grid + all lines in the canvas
|
// Draw grid + all lines in the canvas
|
||||||
draw_list_->PushClipRect(canvas_p0_, canvas_p1_, true);
|
draw_list_->PushClipRect(canvas_p0_, canvas_p1_, true);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ class Canvas {
|
|||||||
void DrawBackground(ImVec2 canvas_size = ImVec2(0, 0));
|
void DrawBackground(ImVec2 canvas_size = ImVec2(0, 0));
|
||||||
void DrawContextMenu();
|
void DrawContextMenu();
|
||||||
void DrawBitmap(const Bitmap& bitmap, int border_offset = 0);
|
void DrawBitmap(const Bitmap& bitmap, int border_offset = 0);
|
||||||
|
void DrawBitmap(const Bitmap& bitmap, int x_offset, int y_offset);
|
||||||
|
void DrawOutline(int x, int y, int w, int h);
|
||||||
void DrawGrid(float grid_step = 64.0f);
|
void DrawGrid(float grid_step = 64.0f);
|
||||||
void DrawOverlay(); // last
|
void DrawOverlay(); // last
|
||||||
|
|
||||||
@@ -35,7 +37,6 @@ class Canvas {
|
|||||||
private:
|
private:
|
||||||
bool enable_grid_ = true;
|
bool enable_grid_ = true;
|
||||||
bool enable_context_menu_ = true;
|
bool enable_context_menu_ = true;
|
||||||
bool dragging_select_ = false;
|
|
||||||
bool custom_canvas_size_ = false;
|
bool custom_canvas_size_ = false;
|
||||||
|
|
||||||
ImDrawList* draw_list_;
|
ImDrawList* draw_list_;
|
||||||
|
|||||||
Reference in New Issue
Block a user