Add support for JP rom and headered ROMs
This commit is contained in:
@@ -119,53 +119,8 @@ namespace core {
|
|||||||
// Window Variables
|
// Window Variables
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
constexpr int kScreenWidth = 1440;
|
constexpr int kScreenWidth = 1200;
|
||||||
constexpr int kScreenHeight = 900;
|
constexpr int kScreenHeight = 800;
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// Z3 Version Constants
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
enum class Z3_Version {
|
|
||||||
US = 1,
|
|
||||||
JP = 2,
|
|
||||||
SD = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
template <Z3_Version version>
|
|
||||||
class VersionConstants;
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class VersionConstants<Z3_Version::US> {
|
|
||||||
public:
|
|
||||||
static constexpr uint32_t kGgxAnimatedPointer = 0x10275;
|
|
||||||
static constexpr uint32_t kOverworldGfxGroups1 = 0x5D97;
|
|
||||||
static constexpr uint32_t kOverworldGfxGroups2 = 0x6073;
|
|
||||||
|
|
||||||
static constexpr uint32_t compressedAllMap32PointersHigh = 0x1794D;
|
|
||||||
static constexpr uint32_t compressedAllMap32PointersLow = 0x17B2D;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
class VersionConstants<Z3_Version::JP> {
|
|
||||||
public:
|
|
||||||
static constexpr uint32_t kGgxAnimatedPointer = 0x10624;
|
|
||||||
static constexpr uint32_t kOverworldGfxGroups1 = 0x5DD7;
|
|
||||||
static constexpr uint32_t kOverworldGfxGroups2 = 0x60B3;
|
|
||||||
|
|
||||||
// LONGPointers all tiles of maps[High] (mapid* 3)
|
|
||||||
static constexpr uint32_t compressedAllMap32PointersHigh = 0x176B1;
|
|
||||||
|
|
||||||
// LONGPointers all tiles of maps[Low] (mapid* 3)
|
|
||||||
static constexpr uint32_t compressedAllMap32PointersLow = 0x17891;
|
|
||||||
|
|
||||||
static constexpr uint32_t overworldMapPalette = 0x7D1C; // JP
|
|
||||||
static constexpr uint32_t overworldMapPaletteGroup = 0x67E74;
|
|
||||||
static constexpr uint32_t overworldMapSize = 0x1273B; // JP
|
|
||||||
static constexpr uint32_t overlayPointers = 0x3FAF4;
|
|
||||||
static constexpr uint32_t overlayPointersBank = 0x07;
|
|
||||||
static constexpr uint32_t overworldTilesType = 0x7FD94;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Magic numbers
|
// Magic numbers
|
||||||
@@ -209,10 +164,6 @@ constexpr int subtype3_tiles = 0x84F0; // JP = Same
|
|||||||
constexpr int gfx_animated_pointer = 0x10275; // JP 0x10624 //long pointer
|
constexpr int gfx_animated_pointer = 0x10275; // JP 0x10624 //long pointer
|
||||||
constexpr int overworldgfxGroups2 = 0x6073; // 0x60B3
|
constexpr int overworldgfxGroups2 = 0x6073; // 0x60B3
|
||||||
|
|
||||||
// 2 byte pointer bank 00 pc -> 0x4320
|
|
||||||
constexpr int gfx_1_pointer = 0x6790; // CF80 ; 004F80
|
|
||||||
constexpr int gfx_2_pointer = 0x6795; // D05F ; 00505F
|
|
||||||
constexpr int gfx_3_pointer = 0x679A; // D13E ; 00513E
|
|
||||||
constexpr int hud_palettes = 0xDD660;
|
constexpr int hud_palettes = 0xDD660;
|
||||||
constexpr int maxGfx = 0xC3FB5;
|
constexpr int maxGfx = 0xC3FB5;
|
||||||
|
|
||||||
@@ -380,7 +331,6 @@ constexpr int blocks_pointer4 = 0x15B0F;
|
|||||||
constexpr int torch_data = 0x2736A; // JP 0x2704A
|
constexpr int torch_data = 0x2736A; // JP 0x2704A
|
||||||
constexpr int torches_length_pointer = 0x88C1;
|
constexpr int torches_length_pointer = 0x88C1;
|
||||||
|
|
||||||
constexpr int kSpriteBlocksetPointer = 0x5B57;
|
|
||||||
constexpr int sprites_data =
|
constexpr int sprites_data =
|
||||||
0x4D8B0; // It use the unused pointers to have more space //Save purpose
|
0x4D8B0; // It use the unused pointers to have more space //Save purpose
|
||||||
constexpr int sprites_data_empty_room = 0x4D8AE;
|
constexpr int sprites_data_empty_room = 0x4D8AE;
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
#include "app/gfx/snes_tile.h"
|
#include "app/gfx/snes_tile.h"
|
||||||
#include "app/gui/canvas.h"
|
#include "app/gui/canvas.h"
|
||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
|
#include "app/gui/input.h"
|
||||||
|
#include "app/gui/style.h"
|
||||||
#include "app/rom.h"
|
#include "app/rom.h"
|
||||||
#include "app/zelda3/overworld.h"
|
#include "app/zelda3/overworld.h"
|
||||||
|
|
||||||
@@ -75,9 +77,16 @@ absl::Status OverworldEditor::DrawToolset() {
|
|||||||
TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator
|
TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator
|
||||||
ImGui::TableNextColumn(); // Palette
|
ImGui::TableNextColumn(); // Palette
|
||||||
palette_editor_.DisplayPalette(palette_, overworld_.isLoaded());
|
palette_editor_.DisplayPalette(palette_, overworld_.isLoaded());
|
||||||
|
TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator
|
||||||
|
ImGui::TableNextColumn(); // Experimental
|
||||||
|
ImGui::Checkbox("Experimental", &show_experimental);
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (show_experimental) {
|
||||||
|
RETURN_IF_ERROR(DrawExperimentalModal())
|
||||||
|
}
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,6 +373,50 @@ absl::Status OverworldEditor::LoadSpriteGraphics() {
|
|||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status OverworldEditor::DrawExperimentalModal() {
|
||||||
|
ImGui::Begin("Experimental", &show_experimental);
|
||||||
|
|
||||||
|
gui::TextWithSeparators("PROTOTYPE OVERWORLD TILEMAP LOADER");
|
||||||
|
ImGui::Text("Please provide two files:");
|
||||||
|
ImGui::Text("One based on MAPn.DAT, which represents the overworld tilemap");
|
||||||
|
ImGui::Text("One based on MAPDATn.DAT, which is the tile32 configurations.");
|
||||||
|
ImGui::Text("Currently, loading CGX for this component is NOT supported. ");
|
||||||
|
ImGui::Text("Please load a US ROM of LTTP (JP ROM support coming soon).");
|
||||||
|
ImGui::Text(
|
||||||
|
"Once you've loaded the files, you can click the button below to load "
|
||||||
|
"the tilemap into the editor");
|
||||||
|
|
||||||
|
ImGui::InputText("##TilemapFile", &ow_tilemap_filename_);
|
||||||
|
ImGui::SameLine();
|
||||||
|
core::FileDialogPipeline(
|
||||||
|
"ImportTilemapsKey", ".CGX,.cgx\0", "Tilemap Hex File", [this]() {
|
||||||
|
ow_tilemap_filename_ = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||||
|
});
|
||||||
|
|
||||||
|
ImGui::InputText("##Tile32ConfigurationFile",
|
||||||
|
&tile32_configuration_filename_);
|
||||||
|
ImGui::SameLine();
|
||||||
|
core::FileDialogPipeline("ImportTile32Key", ".CGX,.cgx\0", "Tile32 Hex File",
|
||||||
|
[this]() {
|
||||||
|
tile32_configuration_filename_ =
|
||||||
|
ImGuiFileDialog::Instance()->GetFilePathName();
|
||||||
|
});
|
||||||
|
|
||||||
|
ImGui::Button("Load Prototype Overworld with ROM graphics");
|
||||||
|
|
||||||
|
gui::TextWithSeparators("Configuration");
|
||||||
|
|
||||||
|
gui::InputHexShort("Tilemap File Offset (High)", &tilemap_file_offset_high_);
|
||||||
|
gui::InputHexShort("Tilemap File Offset (Low)", &tilemap_file_offset_low_);
|
||||||
|
|
||||||
|
gui::InputHexShort("LW Maps to Load", &light_maps_to_load_);
|
||||||
|
gui::InputHexShort("DW Maps to Load", &dark_maps_to_load_);
|
||||||
|
gui::InputHexShort("SP Maps to Load", &sp_maps_to_load_);
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -33,10 +33,10 @@ static constexpr uint kTile8DisplayHeight = 64;
|
|||||||
static constexpr float kInputFieldSize = 30.f;
|
static constexpr float kInputFieldSize = 30.f;
|
||||||
|
|
||||||
static constexpr absl::string_view kToolsetColumnNames[] = {
|
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"};
|
"#transportTool", "#musicTool", "#separator3", "#tilemapTool"};
|
||||||
|
|
||||||
static constexpr absl::string_view kOverworldSettingsColumnNames[] = {
|
static constexpr absl::string_view kOverworldSettingsColumnNames[] = {
|
||||||
"##1stCol", "##gfxCol", "##palCol", "##sprgfxCol",
|
"##1stCol", "##gfxCol", "##palCol", "##sprgfxCol",
|
||||||
@@ -78,6 +78,8 @@ class OverworldEditor : public Editor, public SharedROM {
|
|||||||
absl::Status LoadGraphics();
|
absl::Status LoadGraphics();
|
||||||
absl::Status LoadSpriteGraphics();
|
absl::Status LoadSpriteGraphics();
|
||||||
|
|
||||||
|
absl::Status DrawExperimentalModal();
|
||||||
|
|
||||||
int current_world_ = 0;
|
int current_world_ = 0;
|
||||||
int current_map_ = 0;
|
int current_map_ = 0;
|
||||||
int current_tile16_ = 0;
|
int current_tile16_ = 0;
|
||||||
@@ -90,12 +92,22 @@ class OverworldEditor : public Editor, public SharedROM {
|
|||||||
char message_id_[5] = "";
|
char message_id_[5] = "";
|
||||||
char staticgfx[16];
|
char staticgfx[16];
|
||||||
|
|
||||||
|
uint32_t tilemap_file_offset_high_ = 0;
|
||||||
|
uint32_t tilemap_file_offset_low_ = 0;
|
||||||
|
uint32_t light_maps_to_load_ = 0x51;
|
||||||
|
uint32_t dark_maps_to_load_ = 0x2A;
|
||||||
|
uint32_t sp_maps_to_load_ = 0x07;
|
||||||
|
|
||||||
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 selected_tile_loaded_ = false;
|
bool selected_tile_loaded_ = false;
|
||||||
bool update_selected_tile_ = true;
|
bool update_selected_tile_ = true;
|
||||||
|
|
||||||
|
bool show_experimental = false;
|
||||||
|
std::string ow_tilemap_filename_ = "";
|
||||||
|
std::string tile32_configuration_filename_ = "";
|
||||||
|
|
||||||
Bytes selected_tile_data_;
|
Bytes selected_tile_data_;
|
||||||
std::vector<Bytes> tile16_individual_data_;
|
std::vector<Bytes> tile16_individual_data_;
|
||||||
std::vector<gfx::Bitmap> tile16_individual_;
|
std::vector<gfx::Bitmap> tile16_individual_;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "rom.h"
|
#include "rom.h"
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
// #include <asar/src/asar/interface-lib.h>
|
#include <asar/src/asar/interface-lib.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@@ -27,18 +27,6 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
int GetGraphicsAddress(const uchar* data, uint8_t offset) {
|
|
||||||
auto part_one = data[kOverworldGraphicsPos1 + offset] << 16;
|
|
||||||
auto part_two = data[kOverworldGraphicsPos2 + offset] << 8;
|
|
||||||
auto part_three = data[kOverworldGraphicsPos3 + offset];
|
|
||||||
auto snes_addr = (part_one | part_two | part_three);
|
|
||||||
return core::SnesToPc(snes_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
absl::StatusOr<Bytes> ROM::Load2bppGraphics() {
|
absl::StatusOr<Bytes> ROM::Load2bppGraphics() {
|
||||||
Bytes sheet;
|
Bytes sheet;
|
||||||
const uint8_t sheets[] = {113, 114, 218, 219, 220, 221};
|
const uint8_t sheets[] = {113, 114, 218, 219, 220, 221};
|
||||||
@@ -120,10 +108,29 @@ absl::Status ROM::LoadFromFile(const absl::string_view& filename,
|
|||||||
rom_data_[i] = byte_to_read;
|
rom_data_[i] = byte_to_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the sROM has a header
|
||||||
|
constexpr size_t baseROMSize = 1048576; // 1MB
|
||||||
|
constexpr size_t headerSize = 0x200; // 512 bytes
|
||||||
|
|
||||||
|
if (size_ % baseROMSize == headerSize) {
|
||||||
|
has_header_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_header_) {
|
||||||
|
// remove header
|
||||||
|
rom_data_.erase(rom_data_.begin(), rom_data_.begin() + 0x200);
|
||||||
|
size_ -= 0x200;
|
||||||
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
if (z3_load) {
|
if (z3_load) {
|
||||||
// copy ROM title
|
// copy ROM title
|
||||||
memcpy(title_, rom_data_.data() + kTitleStringOffset, kTitleStringLength);
|
memcpy(title_, rom_data_.data() + kTitleStringOffset, kTitleStringLength);
|
||||||
|
if (rom_data_[kTitleStringOffset + 0x19] == 0) {
|
||||||
|
version_ = Z3_Version::JP;
|
||||||
|
} else {
|
||||||
|
version_ = Z3_Version::US;
|
||||||
|
}
|
||||||
LoadAllPalettes();
|
LoadAllPalettes();
|
||||||
}
|
}
|
||||||
is_loaded_ = true;
|
is_loaded_ = true;
|
||||||
@@ -213,6 +220,7 @@ void ROM::LoadAllPalettes() {
|
|||||||
ReadPalette(core::dungeonMainPalettes + (i * 180), 90));
|
ReadPalette(core::dungeonMainPalettes + (i * 180), 90));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Make these grass colors editable color fields
|
||||||
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassLW));
|
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassLW));
|
||||||
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassDW));
|
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassDW));
|
||||||
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassSpecial));
|
palette_groups_["grass"].AddColor(ReadColor(core::hardcodedGrassSpecial));
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -33,6 +34,83 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
|
struct VersionConstants {
|
||||||
|
uint32_t kGgxAnimatedPointer;
|
||||||
|
uint32_t kOverworldGfxGroups1;
|
||||||
|
uint32_t kOverworldGfxGroups2;
|
||||||
|
// long ptrs all tiles of maps[high/low] (mapid* 3)
|
||||||
|
uint32_t compressedAllMap32PointersHigh;
|
||||||
|
uint32_t compressedAllMap32PointersLow;
|
||||||
|
uint32_t overworldMapPaletteGroup;
|
||||||
|
uint32_t overlayPointers;
|
||||||
|
uint32_t overlayPointersBank;
|
||||||
|
uint32_t overworldTilesType;
|
||||||
|
uint32_t kOverworldGfxPtr1;
|
||||||
|
uint32_t kOverworldGfxPtr2;
|
||||||
|
uint32_t kOverworldGfxPtr3;
|
||||||
|
uint32_t kMap32TileTL;
|
||||||
|
uint32_t kMap32TileTR;
|
||||||
|
uint32_t kMap32TileBL;
|
||||||
|
uint32_t kMap32TileBR;
|
||||||
|
uint32_t kSpriteBlocksetPointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Z3_Version {
|
||||||
|
US = 1,
|
||||||
|
JP = 2,
|
||||||
|
SD = 3,
|
||||||
|
RANDO = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr uint32_t overworldMapPaletteGroup = 0x67E74;
|
||||||
|
static constexpr uint32_t overlayPointers = 0x3FAF4;
|
||||||
|
static constexpr uint32_t overlayPointersBank = 0x07;
|
||||||
|
static constexpr uint32_t overworldTilesType = 0x7FD94;
|
||||||
|
|
||||||
|
static const std::map<Z3_Version, VersionConstants> kVersionConstantsMap = {
|
||||||
|
{Z3_Version::US,
|
||||||
|
{
|
||||||
|
0x10275, // kGgxAnimatedPointer
|
||||||
|
0x5D97, // kOverworldGfxGroups1
|
||||||
|
0x6073, // kOverworldGfxGroups2
|
||||||
|
0x1794D, // compressedAllMap32PointersHigh
|
||||||
|
0x17B2D, // compressedAllMap32PointersLow
|
||||||
|
0x75504, // overworldMapPaletteGroup
|
||||||
|
0x77664, // overlayPointers
|
||||||
|
0x0E, // overlayPointersBank
|
||||||
|
0x71459, // overworldTilesType
|
||||||
|
0x4F80, // kOverworldGfxPtr1
|
||||||
|
0x505F, // kOverworldGfxPtr2
|
||||||
|
0x513E, // kOverworldGfxPtr3
|
||||||
|
0x18000, // kMap32TileTL
|
||||||
|
0x1B400, // kMap32TileTR
|
||||||
|
0x20000, // kMap32TileBL
|
||||||
|
0x23400, // kMap32TileBR
|
||||||
|
0x5B57, // kSpriteBlocksetPointer
|
||||||
|
}},
|
||||||
|
{Z3_Version::JP,
|
||||||
|
{
|
||||||
|
0x10624, // kGgxAnimatedPointer
|
||||||
|
0x5DD7, // kOverworldGfxGroups1
|
||||||
|
0x60B3, // kOverworldGfxGroups2
|
||||||
|
0x176B1, // compressedAllMap32PointersHigh
|
||||||
|
0x17891, // compressedAllMap32PointersLow
|
||||||
|
0x67E74, // overworldMapPaletteGroup
|
||||||
|
0x3FAF4, // overlayPointers
|
||||||
|
0x07, // overlayPointersBank
|
||||||
|
0x7FD94, // overworldTilesType
|
||||||
|
0x4FC0, // kOverworldGfxPtr1
|
||||||
|
0x509F, // kOverworldGfxPtr2
|
||||||
|
0x517E, // kOverworldGfxPtr3
|
||||||
|
0x18000, // kMap32TileTL
|
||||||
|
0x1B3C0, // kMap32TileTR
|
||||||
|
0x20000, // kMap32TileBL
|
||||||
|
0x233C0, // kMap32TileBR
|
||||||
|
0x5B97, // kSpriteBlocksetPointer
|
||||||
|
}}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
constexpr int kOverworldGraphicsPos1 = 0x4F80;
|
constexpr int kOverworldGraphicsPos1 = 0x4F80;
|
||||||
constexpr int kOverworldGraphicsPos2 = 0x505F;
|
constexpr int kOverworldGraphicsPos2 = 0x505F;
|
||||||
constexpr int kOverworldGraphicsPos3 = 0x513E;
|
constexpr int kOverworldGraphicsPos3 = 0x513E;
|
||||||
@@ -113,6 +191,16 @@ class ROM {
|
|||||||
WriteShort(address, bgr);
|
WriteShort(address, bgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VersionConstants GetVersionConstants() const {
|
||||||
|
return kVersionConstantsMap.at(version_);
|
||||||
|
}
|
||||||
|
int GetGraphicsAddress(const uchar* data, uint8_t addr) const {
|
||||||
|
auto part_one = data[GetVersionConstants().kOverworldGfxPtr1 + addr] << 16;
|
||||||
|
auto part_two = data[GetVersionConstants().kOverworldGfxPtr2 + addr] << 8;
|
||||||
|
auto part_three = data[GetVersionConstants().kOverworldGfxPtr3 + addr];
|
||||||
|
auto snes_addr = (part_one | part_two | part_three);
|
||||||
|
return core::SnesToPc(snes_addr);
|
||||||
|
}
|
||||||
uint32_t GetPaletteAddress(const std::string& groupName, size_t paletteIndex,
|
uint32_t GetPaletteAddress(const std::string& groupName, size_t paletteIndex,
|
||||||
size_t colorIndex) const;
|
size_t colorIndex) const;
|
||||||
gfx::PaletteGroup GetPaletteGroup(const std::string& group) {
|
gfx::PaletteGroup GetPaletteGroup(const std::string& group) {
|
||||||
@@ -182,13 +270,14 @@ class ROM {
|
|||||||
private:
|
private:
|
||||||
long size_ = 0;
|
long size_ = 0;
|
||||||
bool is_loaded_ = false;
|
bool is_loaded_ = false;
|
||||||
|
bool has_header_ = false;
|
||||||
uchar title_[21] = "ROM Not Loaded";
|
uchar title_[21] = "ROM Not Loaded";
|
||||||
std::string filename_;
|
std::string filename_;
|
||||||
|
|
||||||
Bytes rom_data_;
|
Bytes rom_data_;
|
||||||
Bytes graphics_buffer_;
|
Bytes graphics_buffer_;
|
||||||
|
|
||||||
core::Z3_Version version_;
|
Z3_Version version_ = Z3_Version::US;
|
||||||
gfx::BitmapTable graphics_bin_;
|
gfx::BitmapTable graphics_bin_;
|
||||||
|
|
||||||
std::shared_ptr<SDL_Renderer> renderer_;
|
std::shared_ptr<SDL_Renderer> renderer_;
|
||||||
@@ -211,7 +300,7 @@ class SharedROM {
|
|||||||
if (!shared_rom_) {
|
if (!shared_rom_) {
|
||||||
shared_rom_ = std::make_shared<ROM>();
|
shared_rom_ = std::make_shared<ROM>();
|
||||||
}
|
}
|
||||||
ROM *rom = shared_rom_.get();
|
ROM* rom = shared_rom_.get();
|
||||||
return rom;
|
return rom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,16 +21,14 @@ namespace zelda3 {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
uint GetOwMapGfxHighPtr(const uchar *rom, int index) {
|
uint GetOwMapGfxHighPtr(const uchar *rom, int index, uint32_t map_high_ptr) {
|
||||||
int map_high_ptr = core::compressedAllMap32PointersHigh;
|
|
||||||
int p1 = (rom[map_high_ptr + 2 + (3 * index)] << 16) +
|
int p1 = (rom[map_high_ptr + 2 + (3 * index)] << 16) +
|
||||||
(rom[map_high_ptr + 1 + (3 * index)] << 8) +
|
(rom[map_high_ptr + 1 + (3 * index)] << 8) +
|
||||||
(rom[map_high_ptr + (3 * index)]);
|
(rom[map_high_ptr + (3 * index)]);
|
||||||
return core::SnesToPc(p1);
|
return core::SnesToPc(p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint GetOwMapGfxLowPtr(const uchar *rom, int index) {
|
uint GetOwMapGfxLowPtr(const uchar *rom, int index, uint32_t map_low_ptr) {
|
||||||
int map_low_ptr = core::compressedAllMap32PointersLow;
|
|
||||||
int p2 = (rom[map_low_ptr + 2 + (3 * index)] << 16) +
|
int p2 = (rom[map_low_ptr + 2 + (3 * index)] << 16) +
|
||||||
(rom[map_low_ptr + 1 + (3 * index)] << 8) +
|
(rom[map_low_ptr + 1 + (3 * index)] << 8) +
|
||||||
(rom[map_low_ptr + (3 * index)]);
|
(rom[map_low_ptr + (3 * index)]);
|
||||||
@@ -321,13 +319,13 @@ void Overworld::SaveMap32Tiles() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
write_tiles(core::map32TilesTL,
|
write_tiles(rom_.GetVersionConstants().kMap32TileTL,
|
||||||
[&](int i) { return tiles32_unique_[i].tile0_; });
|
[&](int i) { return tiles32_unique_[i].tile0_; });
|
||||||
write_tiles(core::map32TilesTR,
|
write_tiles(rom_.GetVersionConstants().kMap32TileTR,
|
||||||
[&](int i) { return tiles32_unique_[i].tile1_; });
|
[&](int i) { return tiles32_unique_[i].tile1_; });
|
||||||
write_tiles(core::map32TilesBL,
|
write_tiles(rom_.GetVersionConstants().kMap32TileBL,
|
||||||
[&](int i) { return tiles32_unique_[i].tile2_; });
|
[&](int i) { return tiles32_unique_[i].tile2_; });
|
||||||
write_tiles(core::map32TilesBR,
|
write_tiles(rom_.GetVersionConstants().kMap32TileBR,
|
||||||
[&](int i) { return tiles32_unique_[i].tile3_; });
|
[&](int i) { return tiles32_unique_[i].tile3_; });
|
||||||
|
|
||||||
if (unique_size > max_tiles) {
|
if (unique_size > max_tiles) {
|
||||||
@@ -338,6 +336,11 @@ void Overworld::SaveMap32Tiles() {
|
|||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
ushort Overworld::GenerateTile32(int i, int k, int dimension) {
|
ushort Overworld::GenerateTile32(int i, int k, int dimension) {
|
||||||
|
const uint32_t map32address[4] = {rom_.GetVersionConstants().kMap32TileTL,
|
||||||
|
rom_.GetVersionConstants().kMap32TileTR,
|
||||||
|
rom_.GetVersionConstants().kMap32TileBL,
|
||||||
|
rom_.GetVersionConstants().kMap32TileBR};
|
||||||
|
|
||||||
return (ushort)(rom_[map32address[dimension] + k + (i)] +
|
return (ushort)(rom_[map32address[dimension] + k + (i)] +
|
||||||
(((rom_[map32address[dimension] + (i) + (k <= 1 ? 4 : 5)] >>
|
(((rom_[map32address[dimension] + (i) + (k <= 1 ? 4 : 5)] >>
|
||||||
(k % 2 == 0 ? 4 : 0)) &
|
(k % 2 == 0 ? 4 : 0)) &
|
||||||
@@ -428,8 +431,12 @@ absl::Status Overworld::DecompressAllMapTiles() {
|
|||||||
int sy = 0;
|
int sy = 0;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
for (int i = 0; i < 160; i++) {
|
for (int i = 0; i < 160; i++) {
|
||||||
auto p1 = GetOwMapGfxHighPtr(rom_.data(), i);
|
auto p1 = GetOwMapGfxHighPtr(
|
||||||
auto p2 = GetOwMapGfxLowPtr(rom_.data(), i);
|
rom_.data(), i,
|
||||||
|
rom_.GetVersionConstants().compressedAllMap32PointersHigh);
|
||||||
|
auto p2 = GetOwMapGfxLowPtr(
|
||||||
|
rom_.data(), i,
|
||||||
|
rom_.GetVersionConstants().compressedAllMap32PointersLow);
|
||||||
int ttpos = 0;
|
int ttpos = 0;
|
||||||
|
|
||||||
if (p1 >= highest) {
|
if (p1 >= highest) {
|
||||||
@@ -627,6 +634,51 @@ void Overworld::LoadSpritesFromMap(int spriteStart, int spriteCount,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
absl::Status Overworld::LoadPrototype(ROM &rom, std::vector<uint8_t> &tilemap,
|
||||||
|
std::vector<uint8_t> tile32) {
|
||||||
|
rom_ = rom;
|
||||||
|
|
||||||
|
AssembleMap32Tiles();
|
||||||
|
AssembleMap16Tiles();
|
||||||
|
RETURN_IF_ERROR(DecompressAllMapTiles())
|
||||||
|
|
||||||
|
for (int map_index = 0; map_index < core::kNumOverworldMaps; ++map_index)
|
||||||
|
overworld_maps_.emplace_back(map_index, rom_, tiles16);
|
||||||
|
|
||||||
|
FetchLargeMaps();
|
||||||
|
LoadEntrances();
|
||||||
|
|
||||||
|
auto size = tiles16.size();
|
||||||
|
std::vector<std::future<absl::Status>> futures;
|
||||||
|
for (int i = 0; i < core::kNumOverworldMaps; ++i) {
|
||||||
|
futures.push_back(std::async(std::launch::async, [this, i, size]() {
|
||||||
|
if (i < 64) {
|
||||||
|
return overworld_maps_[i].BuildMap(size, game_state_, 0, map_parent_,
|
||||||
|
map_tiles_.light_world);
|
||||||
|
} else if (i < 0x80 && i >= 0x40) {
|
||||||
|
return overworld_maps_[i].BuildMap(size, game_state_, 1, map_parent_,
|
||||||
|
map_tiles_.dark_world);
|
||||||
|
} else {
|
||||||
|
return overworld_maps_[i].BuildMap(size, game_state_, 2, map_parent_,
|
||||||
|
map_tiles_.special_world);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all tasks to complete and check their results
|
||||||
|
for (auto &future : futures) {
|
||||||
|
absl::Status status = future.get();
|
||||||
|
if (!status.ok()) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadSprites();
|
||||||
|
|
||||||
|
is_loaded_ = true;
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace zelda3
|
} // namespace zelda3
|
||||||
} // namespace app
|
} // namespace app
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -94,9 +94,10 @@ class Overworld {
|
|||||||
auto isLoaded() const { return is_loaded_; }
|
auto isLoaded() const { return is_loaded_; }
|
||||||
void SetCurrentMap(int i) { current_map_ = i; }
|
void SetCurrentMap(int i) { current_map_ = i; }
|
||||||
|
|
||||||
|
absl::Status LoadPrototype(ROM &rom_, std::vector<uint8_t> &tilemap,
|
||||||
|
std::vector<uint8_t> tile32);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int map32address[4] = {core::map32TilesTL, core::map32TilesTR,
|
|
||||||
core::map32TilesBL, core::map32TilesBR};
|
|
||||||
enum Dimension {
|
enum Dimension {
|
||||||
map32TilesTL = 0,
|
map32TilesTL = 0,
|
||||||
map32TilesTR = 1,
|
map32TilesTR = 1,
|
||||||
|
|||||||
@@ -285,22 +285,24 @@ void OverworldMap::LoadSpritesBlocksets() {
|
|||||||
static_graphics_[11] = static_graphics_base + 0x07;
|
static_graphics_[11] = static_graphics_base + 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] =
|
||||||
(sprite_graphics_[game_state_] * 4) + i] +
|
(rom_[rom_.GetVersionConstants().kSpriteBlocksetPointer +
|
||||||
static_graphics_base);
|
(sprite_graphics_[game_state_] * 4) + i] +
|
||||||
|
static_graphics_base);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverworldMap::LoadMainBlocksets() {
|
void OverworldMap::LoadMainBlocksets() {
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
static_graphics_[i] =
|
static_graphics_[i] = rom_[rom_.GetVersionConstants().kOverworldGfxGroups2 +
|
||||||
rom_[core::overworldgfxGroups2 + (world_index_ * 8) + i];
|
(world_index_ * 8) + i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverworldMap::LoadAreaGraphicsBlocksets() {
|
void OverworldMap::LoadAreaGraphicsBlocksets() {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
uchar value = rom_[core::overworldgfxGroups + (area_graphics_ * 4) + i];
|
uchar value = rom_[rom_.GetVersionConstants().kOverworldGfxGroups1 +
|
||||||
|
(area_graphics_ * 4) + i];
|
||||||
if (value != 0) {
|
if (value != 0) {
|
||||||
static_graphics_[3 + i] = value;
|
static_graphics_[3 + i] = value;
|
||||||
}
|
}
|
||||||
@@ -328,7 +330,8 @@ void OverworldMap::LoadAreaGraphics() {
|
|||||||
gfx::SNESPalette OverworldMap::GetPalette(const std::string& group, int index,
|
gfx::SNESPalette OverworldMap::GetPalette(const std::string& group, int index,
|
||||||
int previousIndex, int limit) {
|
int previousIndex, int limit) {
|
||||||
if (index == 255) {
|
if (index == 255) {
|
||||||
index = rom_[core::overworldMapPaletteGroup + (previousIndex * 4)];
|
index = rom_[rom_.GetVersionConstants().overworldMapPaletteGroup +
|
||||||
|
(previousIndex * 4)];
|
||||||
}
|
}
|
||||||
if (index != 255) {
|
if (index != 255) {
|
||||||
if (index >= limit) {
|
if (index >= limit) {
|
||||||
@@ -349,9 +352,12 @@ void OverworldMap::LoadPalette() {
|
|||||||
area_palette_ = std::min(area_palette_, 0xA3);
|
area_palette_ = std::min(area_palette_, 0xA3);
|
||||||
|
|
||||||
uchar pal0 = 0;
|
uchar pal0 = 0;
|
||||||
uchar pal1 = rom_[core::overworldMapPaletteGroup + (area_palette_ * 4)];
|
uchar pal1 = rom_[rom_.GetVersionConstants().overworldMapPaletteGroup +
|
||||||
uchar pal2 = rom_[core::overworldMapPaletteGroup + (area_palette_ * 4) + 1];
|
(area_palette_ * 4)];
|
||||||
uchar pal3 = rom_[core::overworldMapPaletteGroup + (area_palette_ * 4) + 2];
|
uchar pal2 = rom_[rom_.GetVersionConstants().overworldMapPaletteGroup +
|
||||||
|
(area_palette_ * 4) + 1];
|
||||||
|
uchar pal3 = rom_[rom_.GetVersionConstants().overworldMapPaletteGroup +
|
||||||
|
(area_palette_ * 4) + 2];
|
||||||
uchar pal4 = rom_[core::overworldSpritePaletteGroup +
|
uchar pal4 = rom_[core::overworldSpritePaletteGroup +
|
||||||
(sprite_palette_[game_state_] * 2)];
|
(sprite_palette_[game_state_] * 2)];
|
||||||
uchar pal5 = rom_[core::overworldSpritePaletteGroup +
|
uchar pal5 = rom_[core::overworldSpritePaletteGroup +
|
||||||
@@ -364,7 +370,8 @@ void OverworldMap::LoadPalette() {
|
|||||||
|
|
||||||
// Additional handling of `pal3` and `parent_`
|
// Additional handling of `pal3` and `parent_`
|
||||||
if (pal3 == 255) {
|
if (pal3 == 255) {
|
||||||
pal3 = rom_[core::overworldMapPaletteGroup + (previousPalId * 4) + 2];
|
pal3 = rom_[rom_.GetVersionConstants().overworldMapPaletteGroup +
|
||||||
|
(previousPalId * 4) + 2];
|
||||||
}
|
}
|
||||||
if (parent_ < 0x40) {
|
if (parent_ < 0x40) {
|
||||||
pal0 = parent_ == 0x03 || parent_ == 0x05 || parent_ == 0x07 ? 2 : 0;
|
pal0 = parent_ == 0x03 || parent_ == 0x05 || parent_ == 0x07 ? 2 : 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user