housekeeping and inventory menu
This commit is contained in:
@@ -36,12 +36,35 @@ set(
|
||||
|
||||
# Asar Assembly ---------------------------------------------------------------
|
||||
add_subdirectory(lib/asar/src)
|
||||
set(ASAR_GEN_EXE OFF)
|
||||
set(ASAR_GEN_DLL ON)
|
||||
set(ASAR_GEN_LIB OFF)
|
||||
get_target_property(ASAR_INCLUDE_DIR asar-static INCLUDE_DIRECTORIES)
|
||||
target_include_directories(asar-static PRIVATE ${ASAR_INCLUDE_DIR})
|
||||
set(ASAR_GEN_EXE OFF)
|
||||
set(ASAR_GEN_DLL ON)
|
||||
set(ASAR_GEN_LIB ON)
|
||||
set(ASAR_GEN_EXE_TEST OFF)
|
||||
set(ASAR_GEN_DLL_TEST OFF)
|
||||
|
||||
set(ASAR_STATIC_SRC
|
||||
"lib/asar/src/asar/interface-lib.cpp"
|
||||
"lib/asar/src/asar/addr2line.cpp"
|
||||
"lib/asar/src/asar/arch-65816.cpp"
|
||||
"lib/asar/src/asar/arch-spc700.cpp"
|
||||
"lib/asar/src/asar/arch-superfx.cpp"
|
||||
"lib/asar/src/asar/assembleblock.cpp"
|
||||
"lib/asar/src/asar/crc32.cpp"
|
||||
"lib/asar/src/asar/libcon.cpp"
|
||||
"lib/asar/src/asar/libsmw.cpp"
|
||||
"lib/asar/src/asar/libstr.cpp"
|
||||
"lib/asar/src/asar/macro.cpp"
|
||||
"lib/asar/src/asar/main.cpp"
|
||||
"lib/asar/src/asar/asar_math.cpp"
|
||||
"lib/asar/src/asar/virtualfile.cpp"
|
||||
"lib/asar/src/asar/warnings.cpp"
|
||||
"lib/asar/src/asar/errors.cpp"
|
||||
"lib/asar/src/asar/platform/file-helpers.cpp"
|
||||
"lib/asar/src/asar/platform/linux/file-helpers-linux.cpp"
|
||||
)
|
||||
|
||||
# yaze source files -----------------------------------------------------------
|
||||
set(
|
||||
YAZE_APP_CORE_SRC
|
||||
@@ -86,6 +109,7 @@ set(
|
||||
gui/input.cc
|
||||
gui/style.cc
|
||||
gui/widgets.cc
|
||||
gui/color.cc
|
||||
)
|
||||
|
||||
add_executable(
|
||||
@@ -99,7 +123,7 @@ add_executable(
|
||||
${YAZE_APP_ZELDA3_SRC}
|
||||
${YAZE_GUI_SRC}
|
||||
${IMGUI_SRC}
|
||||
lib/asar/src/asar-dll-bindings/c/asardll.c
|
||||
${ASAR_STATIC_SRC}
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
@@ -111,7 +135,7 @@ target_include_directories(
|
||||
${PNG_INCLUDE_DIRS}
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${GLEW_INCLUDE_DIRS}
|
||||
lib/asar/src/asar-dll-bindings/c
|
||||
lib/asar/src/
|
||||
)
|
||||
|
||||
set(SDL_TARGETS SDL2::SDL2)
|
||||
@@ -130,7 +154,10 @@ target_link_libraries(
|
||||
${OPENGL_LIBRARIES}
|
||||
${CMAKE_DL_LIBS}
|
||||
ImGui
|
||||
asar-static
|
||||
)
|
||||
target_compile_definitions(yaze PRIVATE "linux")
|
||||
target_compile_definitions(yaze PRIVATE "stricmp=strcasecmp")
|
||||
|
||||
set_target_properties(yaze
|
||||
PROPERTIES
|
||||
@@ -155,7 +182,6 @@ add_executable(
|
||||
${YAZE_APP_ZELDA3_SRC}
|
||||
${YAZE_GUI_SRC}
|
||||
${IMGUI_SRC}
|
||||
lib/asar/src/asar-dll-bindings/c/asardll.c
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
@@ -167,7 +193,7 @@ target_include_directories(
|
||||
${PNG_INCLUDE_DIRS}
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${GLEW_INCLUDE_DIRS}
|
||||
lib/asar/src/asar-dll-bindings/c
|
||||
${ASAR_STATIC_SRC}
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@@ -179,6 +205,7 @@ target_link_libraries(
|
||||
${OPENGL_LIBRARIES}
|
||||
${CMAKE_DL_LIBS}
|
||||
delta-service
|
||||
asar-static
|
||||
ImGui
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "script.h"
|
||||
|
||||
#include <asardll.h>
|
||||
#include <asar/interface-lib.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -20,49 +20,13 @@ namespace yaze {
|
||||
namespace app {
|
||||
namespace snes_asm {
|
||||
|
||||
std::string GenerateBytePool(char mosaic_tiles[core::kNumOverworldMaps]) {
|
||||
std::string to_return = "";
|
||||
int column = 0;
|
||||
for (int i = 0; i < core::kNumOverworldMaps; ++i) {
|
||||
std::string to_add = "";
|
||||
|
||||
// if start of line, define byte
|
||||
if (i == 0 || i % 8 == 0) {
|
||||
to_add += " db ";
|
||||
}
|
||||
|
||||
// set byte
|
||||
to_add += "$00";
|
||||
if (mosaic_tiles[i] > 0) {
|
||||
if (i == 0 || i % 8 == 0) {
|
||||
to_add = " db $01";
|
||||
} else {
|
||||
to_add = "$01";
|
||||
}
|
||||
}
|
||||
|
||||
// newline or comma separated
|
||||
if (column == 7) {
|
||||
column = 0;
|
||||
to_add += " \n";
|
||||
} else {
|
||||
column++;
|
||||
to_add += ", ";
|
||||
}
|
||||
|
||||
to_return += to_add;
|
||||
}
|
||||
return to_return;
|
||||
}
|
||||
|
||||
absl::Status Script::ApplyPatchToROM(ROM &rom) {
|
||||
if (patch_contents_.empty() || patch_filename_.empty()) {
|
||||
return absl::InvalidArgumentError("No patch loaded!");
|
||||
}
|
||||
|
||||
char *data = (char *)rom.data();
|
||||
int size = rom.GetSize();
|
||||
int count = 0;
|
||||
auto data = (char *)rom.data();
|
||||
int size = rom.size();
|
||||
if (!asar_patch(patch_filename_.c_str(), data, patch_size_, &size)) {
|
||||
auto asar_error = asar_geterrors(&count);
|
||||
auto full_error = asar_error->fullerrdata;
|
||||
@@ -71,43 +35,37 @@ absl::Status Script::ApplyPatchToROM(ROM &rom) {
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Script::GenerateMosaicChangeAssembly(
|
||||
absl::Status Script::PatchOverworldMosaic(
|
||||
ROM &rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset,
|
||||
int hook_offset) {
|
||||
for (int i = 0; i < core::kNumOverworldMaps; i++) {
|
||||
if (mosaic_tiles[i]) {
|
||||
rom[core::overworldCustomMosaicArray + i] = 0x01;
|
||||
} else {
|
||||
rom[core::overworldCustomMosaicArray + i] = 0x00;
|
||||
}
|
||||
}
|
||||
std::fstream file("assets/asm/mosaic_change.asm",
|
||||
std::ios::out | std::ios::in);
|
||||
if (!file.is_open()) {
|
||||
return absl::InvalidArgumentError(
|
||||
"Couldn't open mosaic change template file");
|
||||
"Unable to open mosaic change assembly source");
|
||||
}
|
||||
|
||||
std::stringstream assembly;
|
||||
assembly << file.rdbuf();
|
||||
file.close();
|
||||
|
||||
auto assembly_string = assembly.str();
|
||||
|
||||
if (!core::StringReplace(assembly_string, "<HOOK>", kMosaicChangeOffset)) {
|
||||
return absl::InternalError(
|
||||
"Mosaic template did not have proper `<HOOK>` to replace.");
|
||||
}
|
||||
|
||||
if (!core::StringReplace(
|
||||
assembly_string, "<EXPANDED_SPACE>",
|
||||
absl::StrFormat("$%x", routine_offset + kSNESToPCOffset))) {
|
||||
return absl::InternalError(
|
||||
"Mosaic template did not have proper `<EXPANDED_SPACE>` to replace.");
|
||||
}
|
||||
|
||||
assembly_string += GenerateBytePool(mosaic_tiles);
|
||||
patch_contents_ = assembly_string;
|
||||
patch_filename_ = "assets/asm/mosaic_change_generated.asm";
|
||||
std::ofstream new_file(patch_filename_, std::ios::out);
|
||||
if (new_file.is_open()) {
|
||||
new_file.write(assembly_string.c_str(), assembly_string.size());
|
||||
new_file.close();
|
||||
}
|
||||
|
||||
return ApplyPatchToROM(rom);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef YAZE_APP_ASM_SCRIPT_H
|
||||
#define YAZE_APP_ASM_SCRIPT_H
|
||||
|
||||
#include <asardll.h>
|
||||
#include <asar/interface-lib.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
@@ -27,17 +27,15 @@ class ScriptTemplate {
|
||||
public:
|
||||
virtual ~ScriptTemplate() = default;
|
||||
virtual absl::Status ApplyPatchToROM(ROM& rom) = 0;
|
||||
virtual absl::Status GenerateMosaicChangeAssembly(
|
||||
virtual absl::Status PatchOverworldMosaic(
|
||||
ROM& rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset,
|
||||
int hook_offset = 0) = 0;
|
||||
};
|
||||
|
||||
class Script : public ScriptTemplate {
|
||||
public:
|
||||
Script() { asar_init_with_dll_path("assets/libasar.dll"); }
|
||||
|
||||
absl::Status ApplyPatchToROM(ROM& rom) override;
|
||||
absl::Status GenerateMosaicChangeAssembly(
|
||||
absl::Status PatchOverworldMosaic(
|
||||
ROM& rom, char mosaic_tiles[core::kNumOverworldMaps], int routine_offset,
|
||||
int hook_offset = 0) override;
|
||||
|
||||
|
||||
@@ -482,7 +482,7 @@ constexpr int customAreaSpecificBGPalette =
|
||||
constexpr int customAreaSpecificBGASM = 0x140150;
|
||||
constexpr int customAreaSpecificBGEnabled =
|
||||
0x140140; // 1 byte, not 0 if enabled
|
||||
|
||||
constexpr int overworldCustomMosaicArray = 0x1301F0;
|
||||
// ============================================================================
|
||||
// Dungeon Map Related Variables
|
||||
// ============================================================================
|
||||
|
||||
@@ -127,7 +127,7 @@ void Viewer::DrawViewMenu() {
|
||||
|
||||
if (show_memory_editor) {
|
||||
static MemoryEditor mem_edit;
|
||||
mem_edit.DrawWindow("Memory Editor", (void*)&rom_, rom_.GetSize());
|
||||
mem_edit.DrawWindow("Memory Editor", (void*)&rom_, rom_.size());
|
||||
}
|
||||
|
||||
if (show_imgui_demo) {
|
||||
|
||||
@@ -138,7 +138,7 @@ void MasterEditor::DrawInfoPopup() {
|
||||
if (ImGui::BeginPopupModal("ROM Information", nullptr,
|
||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::Text("Title: %s", rom_.GetTitle());
|
||||
ImGui::Text("ROM Size: %ld", rom_.GetSize());
|
||||
ImGui::Text("ROM Size: %ld", rom_.size());
|
||||
|
||||
if (ImGui::Button("Close", ImVec2(200, 0))) {
|
||||
rom_info_ = false;
|
||||
@@ -216,7 +216,7 @@ void MasterEditor::DrawViewMenu() {
|
||||
|
||||
if (show_memory_editor) {
|
||||
static MemoryEditor mem_edit;
|
||||
mem_edit.DrawWindow("Memory Editor", (void *)&rom_, rom_.GetSize());
|
||||
mem_edit.DrawWindow("Memory Editor", (void *)&rom_, rom_.size());
|
||||
}
|
||||
|
||||
if (show_imgui_demo) {
|
||||
|
||||
@@ -107,7 +107,7 @@ absl::Status OverworldEditor::DrawToolset() {
|
||||
BUTTON_COLUMN(ICON_MD_ZOOM_OUT) // Zoom Out
|
||||
BUTTON_COLUMN(ICON_MD_ZOOM_IN) // Zoom In
|
||||
TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator
|
||||
BUTTON_COLUMN(ICON_MD_DRAW); // Draw Tile
|
||||
BUTTON_COLUMN(ICON_MD_DRAW) // Draw Tile
|
||||
BUTTON_COLUMN(ICON_MD_DOOR_FRONT) // Entrances
|
||||
BUTTON_COLUMN(ICON_MD_DOOR_BACK) // Exits
|
||||
BUTTON_COLUMN(ICON_MD_GRASS) // Items
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gfx/snes_tile.h"
|
||||
#include "gui/canvas.h"
|
||||
#include "gui/icons.h"
|
||||
#include "gui/input.h"
|
||||
|
||||
namespace yaze {
|
||||
@@ -63,37 +64,40 @@ void ScreenEditor::DrawInventoryMenuEditor() {
|
||||
TAB_ITEM("Inventory Menu")
|
||||
|
||||
static bool create = false;
|
||||
if (!create) {
|
||||
PRINT_IF_ERROR(rom_.LoadAllGraphicsData())
|
||||
all_gfx_ = rom_.GetGraphicsBuffer();
|
||||
inventory_.Create(all_gfx_);
|
||||
if (!create && rom_.isLoaded()) {
|
||||
inventory_.Create();
|
||||
palette_ =inventory_.Palette();
|
||||
create = true;
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("InventoryScreen", 2, ImGuiTableFlags_Resizable)) {
|
||||
DrawInventoryToolset();
|
||||
|
||||
if (ImGui::BeginTable("InventoryScreen", 3, ImGuiTableFlags_Resizable)) {
|
||||
ImGui::TableSetupColumn("Canvas");
|
||||
ImGui::TableSetupColumn("Tiles");
|
||||
ImGui::TableSetupColumn("Palette");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
screen_canvas_.DrawBackground();
|
||||
screen_canvas_.DrawContextMenu();
|
||||
screen_canvas_.DrawBitmap(inventory_.Bitmap(), 2, create);
|
||||
screen_canvas_.DrawGrid();
|
||||
screen_canvas_.DrawGrid(32.0f);
|
||||
screen_canvas_.DrawOverlay();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, 192 * 2 + 2));
|
||||
tilesheet_canvas_.DrawBackground(ImVec2(128 * 2 + 2, (192 * 2) + 4));
|
||||
tilesheet_canvas_.DrawContextMenu();
|
||||
tilesheet_canvas_.DrawBitmap(inventory_.Tilesheet(), 2, create);
|
||||
tilesheet_canvas_.DrawGrid(16.0f);
|
||||
tilesheet_canvas_.DrawOverlay();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
gui::DisplayPalette(palette_, create);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::Separator();
|
||||
END_TAB_ITEM()
|
||||
}
|
||||
|
||||
@@ -138,7 +142,7 @@ void ScreenEditor::DrawMosaicEditor() {
|
||||
gui::InputHex("Routine Location", &overworldCustomMosaicASM);
|
||||
|
||||
if (ImGui::Button("Generate Mosaic Assembly")) {
|
||||
auto mosaic = mosaic_script_.GenerateMosaicChangeAssembly(
|
||||
auto mosaic = mosaic_script_.PatchOverworldMosaic(
|
||||
rom_, mosaic_tiles_, overworldCustomMosaicASM);
|
||||
if (!mosaic.ok()) {
|
||||
std::cout << mosaic;
|
||||
@@ -168,6 +172,30 @@ void ScreenEditor::DrawToolset() {
|
||||
ImGui::Checkbox("Draw BG3", &drawing_bg3);
|
||||
}
|
||||
|
||||
void ScreenEditor::DrawInventoryToolset() {
|
||||
if (ImGui::BeginTable("InventoryToolset", 8, ImGuiTableFlags_SizingFixedFit, ImVec2(0, 0))) {
|
||||
ImGui::TableSetupColumn("#drawTool");
|
||||
ImGui::TableSetupColumn("#sep1");
|
||||
ImGui::TableSetupColumn("#zoomOut");
|
||||
ImGui::TableSetupColumn("#zoomIN");
|
||||
ImGui::TableSetupColumn("#sep2");
|
||||
ImGui::TableSetupColumn("#bg2Tool");
|
||||
ImGui::TableSetupColumn("#bg3Tool");
|
||||
ImGui::TableSetupColumn("#itemTool");
|
||||
|
||||
BUTTON_COLUMN(ICON_MD_UNDO)
|
||||
BUTTON_COLUMN(ICON_MD_REDO)
|
||||
TEXT_COLUMN(ICON_MD_MORE_VERT)
|
||||
BUTTON_COLUMN(ICON_MD_ZOOM_OUT)
|
||||
BUTTON_COLUMN(ICON_MD_ZOOM_IN)
|
||||
TEXT_COLUMN(ICON_MD_MORE_VERT)
|
||||
BUTTON_COLUMN(ICON_MD_DRAW)
|
||||
BUTTON_COLUMN(ICON_MD_BUILD)
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace editor
|
||||
} // namespace app
|
||||
} // namespace yaze
|
||||
@@ -9,9 +9,12 @@
|
||||
#include "app/core/constants.h"
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gfx/snes_tile.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
#include "app/rom.h"
|
||||
#include "app/zelda3/inventory.h"
|
||||
#include "gui/canvas.h"
|
||||
#include "gui/icons.h"
|
||||
#include "gui/color.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace app {
|
||||
@@ -19,7 +22,6 @@ namespace editor {
|
||||
|
||||
using MosaicArray = std::array<int, core::kNumOverworldMaps>;
|
||||
static int overworldCustomMosaicASM = 0x1301D0;
|
||||
static int overworldCustomMosaicArray = 0x1301F0;
|
||||
|
||||
class ScreenEditor {
|
||||
public:
|
||||
@@ -39,6 +41,7 @@ class ScreenEditor {
|
||||
void DrawInventoryMenuEditor();
|
||||
|
||||
void DrawToolset();
|
||||
void DrawInventoryToolset();
|
||||
void DrawWorldGrid(int world, int h = 8, int w = 8);
|
||||
|
||||
char mosaic_tiles_[core::kNumOverworldMaps];
|
||||
@@ -46,6 +49,7 @@ class ScreenEditor {
|
||||
ROM rom_;
|
||||
Bytes all_gfx_;
|
||||
zelda3::Inventory inventory_;
|
||||
gfx::SNESPalette palette_;
|
||||
snes_asm::Script mosaic_script_;
|
||||
gui::Canvas screen_canvas_;
|
||||
gui::Canvas tilesheet_canvas_;
|
||||
|
||||
@@ -302,7 +302,7 @@ absl::Status ValidateCompressionResult(
|
||||
RETURN_IF_ERROR(temp_rom.LoadFromBytes(
|
||||
CreateCompressionString(compressed_chain_start->next, mode)))
|
||||
ASSIGN_OR_RETURN(auto decomp_data,
|
||||
temp_rom.Decompress(0, temp_rom.GetSize()))
|
||||
temp_rom.Decompress(0, temp_rom.size()))
|
||||
if (!std::equal(decomp_data.begin() + start, decomp_data.end(),
|
||||
temp_rom.begin())) {
|
||||
return absl::InternalError(absl::StrFormat(
|
||||
@@ -352,7 +352,7 @@ int GetGraphicsAddress(const uchar* data, uint8_t offset) {
|
||||
return core::SnesToPc(snes_addr);
|
||||
}
|
||||
|
||||
Bytes SNES3bppTo8bppSheet(Bytes sheet, int bpp) {
|
||||
Bytes SnesTo8bppSheet(Bytes sheet, int bpp) {
|
||||
int xx = 0; // positions where we are at on the sheet
|
||||
int yy = 0;
|
||||
int pos = 0;
|
||||
@@ -368,12 +368,9 @@ Bytes SNES3bppTo8bppSheet(Bytes sheet, int bpp) {
|
||||
}
|
||||
Bytes sheet_buffer_out(buffer_size);
|
||||
|
||||
// for each tiles, 16 per line
|
||||
for (int i = 0; i < num_tiles; i++) {
|
||||
// for each line
|
||||
for (int y = 0; y < 8; y++) {
|
||||
//[0] + [1] + [16]
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int i = 0; i < num_tiles; i++) { // for each tiles, 16 per line
|
||||
for (int y = 0; y < 8; y++) { // for each line
|
||||
for (int x = 0; x < 8; x++) { //[0] + [1] + [16]
|
||||
auto b1 = ((sheet[(y * 2) + (bpp * pos)] & (kGraphicsBitmap[x])));
|
||||
auto b2 = (sheet[((y * 2) + (bpp * pos)) + 1] & (kGraphicsBitmap[x]));
|
||||
auto b3 = (sheet[(16 + y) + (bpp * pos)] & (kGraphicsBitmap[x]));
|
||||
@@ -457,7 +454,6 @@ absl::StatusOr<Bytes> ROM::Compress(const int start, const int length, int mode,
|
||||
comp_accumulator = 0;
|
||||
}
|
||||
} else {
|
||||
// Anything is better than directly copying bytes...
|
||||
lc_lz2::CompressionCommandAlternative(
|
||||
rom_data_.data(), compressed_chain, cmd_size, cmd_args, src_data_pos,
|
||||
comp_accumulator, cmd_with_max, max_win);
|
||||
@@ -474,8 +470,8 @@ absl::StatusOr<Bytes> ROM::Compress(const int start, const int length, int mode,
|
||||
}
|
||||
}
|
||||
|
||||
lc_lz2::MergeCopy(
|
||||
compressed_chain_start->next); // Skipping compression chain header
|
||||
// Skipping compression chain header
|
||||
lc_lz2::MergeCopy(compressed_chain_start->next);
|
||||
lc_lz2::PrintCompressionChain(compressed_chain_start);
|
||||
return lc_lz2::CreateCompressionString(compressed_chain_start->next, mode);
|
||||
}
|
||||
@@ -515,10 +511,8 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, int mode) {
|
||||
offset += length;
|
||||
break;
|
||||
case kCommandByteFill:
|
||||
for (int i = 0; i < length; i++) {
|
||||
buffer[buffer_pos] = rom_data_[offset];
|
||||
buffer_pos++;
|
||||
}
|
||||
memset(buffer.data() + buffer_pos, (int)(rom_data_[offset]), length);
|
||||
buffer_pos += length;
|
||||
offset += 1; // Advances 1 byte in the ROM
|
||||
break;
|
||||
case kCommandWordFill: {
|
||||
@@ -543,35 +537,23 @@ absl::StatusOr<Bytes> ROM::Decompress(int offset, int size, int mode) {
|
||||
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
|
||||
// addr = (s2 | s1);
|
||||
addr = (rom_data_[offset + 1] & kSnesByteMax) |
|
||||
((rom_data_[offset] & kSnesByteMax) << 8);
|
||||
if (addr > offset) {
|
||||
return absl::InternalError(absl::StrFormat(
|
||||
"Decompress: Offset for command copy exceeds current position "
|
||||
"(Offset : %#04x | Pos : %#06x)\n",
|
||||
addr, offset));
|
||||
}
|
||||
|
||||
if (buffer_pos + length >= size) {
|
||||
size *= 2;
|
||||
buffer.resize(size);
|
||||
}
|
||||
|
||||
memcpy(buffer.data() + buffer_pos, buffer.data() + addr, length);
|
||||
buffer_pos += length;
|
||||
offset += 2;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
buffer[buffer_pos] = buffer[addr + i];
|
||||
buffer_pos++;
|
||||
if (addr > offset) {
|
||||
return absl::InternalError(absl::StrFormat(
|
||||
"Decompress: Offset for command copy exceeds current position "
|
||||
"(Offset : %#04x | Pos : %#06x)\n",
|
||||
addr, offset));
|
||||
}
|
||||
offset += 2; // Advance 2 bytes in the ROM
|
||||
|
||||
if (buffer_pos + length >= size) {
|
||||
size *= 2;
|
||||
buffer.resize(size);
|
||||
}
|
||||
memcpy(buffer.data() + buffer_pos, buffer.data() + addr, length);
|
||||
buffer_pos += length;
|
||||
offset += 2;
|
||||
} break;
|
||||
default: {
|
||||
std::cout << absl::StrFormat(
|
||||
@@ -598,12 +580,12 @@ absl::StatusOr<Bytes> ROM::Load2bppGraphics() {
|
||||
Bytes sheet;
|
||||
const uint8_t sheets[] = {113, 114, 218, 219, 220, 221};
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
auto offset = GetGraphicsAddress(rom_data_.data(), sheets[i]);
|
||||
for (const auto& sheet_id : sheets) {
|
||||
auto offset = GetGraphicsAddress(rom_data_.data(), sheet_id);
|
||||
ASSIGN_OR_RETURN(auto decomp_sheet, Decompress(offset))
|
||||
auto converted_sheet = SNES3bppTo8bppSheet(decomp_sheet, 2);
|
||||
for (int j = 0; j < converted_sheet.size(); ++j) {
|
||||
sheet.push_back(converted_sheet.at(j));
|
||||
auto converted_sheet = SnesTo8bppSheet(decomp_sheet, 2);
|
||||
for (const auto& each_pixel : converted_sheet) {
|
||||
sheet.push_back(each_pixel);
|
||||
}
|
||||
}
|
||||
return sheet;
|
||||
@@ -627,8 +609,6 @@ absl::Status ROM::LoadAllGraphicsData() {
|
||||
}
|
||||
bpp3 = true;
|
||||
} else if (i == 113 || i == 114 || i >= 218) {
|
||||
// auto offset = GetGraphicsAddress(rom_data_.data(), i);
|
||||
// ASSIGN_OR_RETURN(sheet, Decompress(offset))
|
||||
bpp3 = false;
|
||||
} else {
|
||||
auto offset = GetGraphicsAddress(rom_data_.data(), i);
|
||||
@@ -637,7 +617,7 @@ absl::Status ROM::LoadAllGraphicsData() {
|
||||
}
|
||||
|
||||
if (bpp3) {
|
||||
auto converted_sheet = SNES3bppTo8bppSheet(sheet, 3);
|
||||
auto converted_sheet = SnesTo8bppSheet(sheet, 3);
|
||||
graphics_bin_[i] =
|
||||
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
|
||||
core::kTilesheetDepth, converted_sheet.data(), 0x1000);
|
||||
@@ -647,15 +627,8 @@ absl::Status ROM::LoadAllGraphicsData() {
|
||||
graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
|
||||
}
|
||||
} else {
|
||||
// auto converted_sheet = SNES3bppTo8bppSheet(sheet, 2);
|
||||
// graphics_bin_[i] =
|
||||
// gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
|
||||
// core::kTilesheetDepth, converted_sheet.data(), 0x1000);
|
||||
// graphics_bin_.at(i).CreateTexture(renderer_);
|
||||
|
||||
for (int j = 0; j < graphics_bin_.at(0).GetSize(); ++j) {
|
||||
graphics_buffer_.push_back(0xFF);
|
||||
// graphics_buffer_.push_back(graphics_bin_.at(i).GetByte(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,6 @@ class ROM {
|
||||
|
||||
void RenderBitmap(gfx::Bitmap* bitmap) const;
|
||||
|
||||
auto GetSize() const { return size_; }
|
||||
auto GetTitle() const { return title; }
|
||||
auto GetGraphicsBin() const { return graphics_bin_; }
|
||||
auto GetGraphicsBuffer() const { return graphics_buffer_; }
|
||||
@@ -105,6 +104,7 @@ class ROM {
|
||||
auto begin() { return rom_data_.begin(); }
|
||||
auto end() { return rom_data_.end(); }
|
||||
auto data() { return rom_data_.data(); }
|
||||
auto size() const { return size_; }
|
||||
|
||||
uchar& operator[](int i) {
|
||||
if (i > size_) {
|
||||
|
||||
@@ -8,22 +8,18 @@
|
||||
namespace yaze {
|
||||
namespace app {
|
||||
namespace zelda3 {
|
||||
void Inventory::Create(Bytes& all_gfx) {
|
||||
void Inventory::Create() {
|
||||
data_.reserve(256 * 256);
|
||||
for (int i = 0; i < 256 * 256; i++) {
|
||||
data_.push_back(0xFF);
|
||||
}
|
||||
PRINT_IF_ERROR(BuildTileset(all_gfx))
|
||||
//tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kInventoryStart)));
|
||||
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos)));
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos + 0x02)));
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos + 0x04)));
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kBowItemPos + 0x08)));
|
||||
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos)));
|
||||
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos + 0x02)));
|
||||
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos + 0x04)));
|
||||
// tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(kLampItemPos + 0x08)));
|
||||
PRINT_IF_ERROR(BuildTileset())
|
||||
for (int i = 0; i < 0x400; i += 0x08) {
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos)));
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos + 0x02)));
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos + 0x04)));
|
||||
tiles_.push_back(gfx::GetTilesInfo(rom_.toint16(i + kBowItemPos + 0x08)));
|
||||
}
|
||||
const int offsets[] = {0x00, 0x08, 0x800, 0x808};
|
||||
auto xx = 0;
|
||||
auto yy = 0;
|
||||
@@ -49,15 +45,15 @@ void Inventory::Create(Bytes& all_gfx) {
|
||||
int source = ypos + xpos + (x + (y * 0x80));
|
||||
|
||||
auto destination = xx + yy + offset + (mx + (my * 0x100));
|
||||
data_[destination] = (tilesheets_[source] & 0x0F);
|
||||
data_[destination] = (test_[source] & 0x0F) + tile.palette_ * 0x08;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 4) {
|
||||
i = 0;
|
||||
xx += 0x10;
|
||||
if (xx >= 0x80) {
|
||||
yy += 0x800;
|
||||
if (xx >= 0x100) {
|
||||
yy += 0x1000;
|
||||
xx = 0;
|
||||
}
|
||||
} else {
|
||||
@@ -65,15 +61,24 @@ void Inventory::Create(Bytes& all_gfx) {
|
||||
}
|
||||
}
|
||||
bitmap_.Create(256, 256, 128, data_);
|
||||
// bitmap_.ApplyPalette(rom_.GetPaletteGroup("hud")[0]);
|
||||
bitmap_.ApplyPalette(palette_);
|
||||
rom_.RenderBitmap(&bitmap_);
|
||||
}
|
||||
|
||||
absl::Status Inventory::BuildTileset(Bytes& all_gfx) {
|
||||
absl::Status Inventory::BuildTileset() {
|
||||
tilesheets_.reserve(6 * 0x2000);
|
||||
for (int i = 0; i < 6 * 0x2000; i++) tilesheets_.push_back(0xFF);
|
||||
ASSIGN_OR_RETURN(tilesheets_, rom_.Load2bppGraphics())
|
||||
tilesheets_bmp_.Create(128, 192 + 96 + 48 - 16, 64, tilesheets_);
|
||||
Bytes test;
|
||||
for (int i = 0; i < 0x4000; i++) {
|
||||
test_.push_back(tilesheets_[i]);
|
||||
}
|
||||
for (int i = 0x8000; i < + 0x8000 + 0x2000; i++) {
|
||||
test_.push_back(tilesheets_[i]);
|
||||
}
|
||||
tilesheets_bmp_.Create(128, 0x130, 64, test_);
|
||||
palette_ = rom_.GetPaletteGroup("hud")[0];
|
||||
tilesheets_bmp_.ApplyPalette(palette_);
|
||||
rom_.RenderBitmap(&tilesheets_bmp_);
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gfx/snes_tile.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
#include "app/rom.h"
|
||||
#include "gui/canvas.h"
|
||||
|
||||
@@ -11,7 +12,6 @@ namespace app {
|
||||
namespace zelda3 {
|
||||
|
||||
constexpr int kInventoryStart = 0x6564A;
|
||||
constexpr int kLampItemPos = 0x6F6F9;
|
||||
constexpr int kBowItemPos = 0x6F631;
|
||||
|
||||
class Inventory {
|
||||
@@ -19,11 +19,12 @@ class Inventory {
|
||||
void SetupROM(ROM& rom) { rom_ = rom; }
|
||||
auto Bitmap() const { return bitmap_; }
|
||||
auto Tilesheet() const { return tilesheets_bmp_; }
|
||||
auto Palette() const { return palette_; }
|
||||
|
||||
void Create(Bytes& all_gfx);
|
||||
void Create();
|
||||
|
||||
private:
|
||||
absl::Status BuildTileset(Bytes& all_gfx);
|
||||
absl::Status BuildTileset();
|
||||
|
||||
ROM rom_;
|
||||
|
||||
@@ -31,7 +32,9 @@ class Inventory {
|
||||
gfx::Bitmap bitmap_;
|
||||
|
||||
Bytes tilesheets_;
|
||||
Bytes test_;
|
||||
gfx::Bitmap tilesheets_bmp_;
|
||||
gfx::SNESPalette palette_;
|
||||
|
||||
gui::Canvas canvas_;
|
||||
std::vector<gfx::TileInfo> tiles_;
|
||||
|
||||
@@ -64,6 +64,7 @@ void Canvas::DrawContextMenu() {
|
||||
ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
|
||||
|
||||
if (ImGui::BeginPopup("context")) {
|
||||
ImGui::MenuItem("Show Grid", nullptr, &enable_grid_);
|
||||
if (ImGui::MenuItem("Reset Position", nullptr, false)) {
|
||||
scrolling_.x = 0;
|
||||
scrolling_.y = 0;
|
||||
|
||||
84
src/gui/color.cc
Normal file
84
src/gui/color.cc
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "color.h"
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gui {
|
||||
void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded) {
|
||||
static ImVec4 color = ImVec4(0, 0, 0, 255.f);
|
||||
ImGuiColorEditFlags misc_flags = ImGuiColorEditFlags_AlphaPreview |
|
||||
ImGuiColorEditFlags_NoDragDrop |
|
||||
ImGuiColorEditFlags_NoOptions;
|
||||
|
||||
// Generate a default palette. The palette will persist and can be edited.
|
||||
static bool init = false;
|
||||
static ImVec4 saved_palette[32] = {};
|
||||
if (loaded && !init) {
|
||||
for (int n = 0; n < palette.size_; n++) {
|
||||
saved_palette[n].x = palette.GetColor(n).rgb.x / 255;
|
||||
saved_palette[n].y = palette.GetColor(n).rgb.y / 255;
|
||||
saved_palette[n].z = palette.GetColor(n).rgb.z / 255;
|
||||
saved_palette[n].w = 255; // Alpha
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
|
||||
static ImVec4 backup_color;
|
||||
ImGui::Text("Current ==>");
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Previous");
|
||||
|
||||
ImGui::ColorButton(
|
||||
"##current", color,
|
||||
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
|
||||
ImVec2(60, 40));
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::ColorButton(
|
||||
"##previous", backup_color,
|
||||
ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf,
|
||||
ImVec2(60, 40)))
|
||||
color = backup_color;
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::BeginGroup(); // Lock X position
|
||||
ImGui::Text("Palette");
|
||||
for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) {
|
||||
ImGui::PushID(n);
|
||||
if ((n % 4) != 0) ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y);
|
||||
|
||||
ImGuiColorEditFlags palette_button_flags = ImGuiColorEditFlags_NoAlpha |
|
||||
ImGuiColorEditFlags_NoPicker |
|
||||
ImGuiColorEditFlags_NoTooltip;
|
||||
if (ImGui::ColorButton("##palette", saved_palette[n], palette_button_flags,
|
||||
ImVec2(20, 20)))
|
||||
color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z,
|
||||
color.w); // Preserve alpha!
|
||||
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F))
|
||||
memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3);
|
||||
if (const ImGuiPayload* payload =
|
||||
ImGui::AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F))
|
||||
memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4);
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::EndGroup();
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::ColorPicker4("##picker", (float*)&color,
|
||||
misc_flags | ImGuiColorEditFlags_NoSidePreview |
|
||||
ImGuiColorEditFlags_NoSmallPreview);
|
||||
}
|
||||
} // namespace gui
|
||||
} // namespace yaze
|
||||
20
src/gui/color.h
Normal file
20
src/gui/color.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef YAZE_GUI_COLOR_H
|
||||
#define YAZE_GUI_COLOR_H
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
#include "app/gfx/bitmap.h"
|
||||
#include "app/gfx/snes_palette.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace gui {
|
||||
|
||||
void DisplayPalette(app::gfx::SNESPalette& palette, bool loaded);
|
||||
|
||||
} // namespace gui
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
@@ -30,7 +30,7 @@ using ::testing::Return;
|
||||
class MockScript : public Script {
|
||||
public:
|
||||
MOCK_METHOD(absl::Status, ApplyPatchToROM, (ROM & rom));
|
||||
MOCK_METHOD(absl::Status, GenerateMosaicChangeAssembly,
|
||||
MOCK_METHOD(absl::Status, PatchOverworldMosaic,
|
||||
(ROM & rom, char mosaic_tiles[yaze::app::core::kNumOverworldMaps],
|
||||
int routine_offset, int hook_offset));
|
||||
};
|
||||
@@ -40,15 +40,15 @@ TEST(ASMTest, ApplyMosaicChangePatchOk) {
|
||||
MockScript script;
|
||||
char mosaic_tiles[yaze::app::core::kNumOverworldMaps];
|
||||
|
||||
EXPECT_CALL(script, GenerateMosaicChangeAssembly(_, Eq(mosaic_tiles),
|
||||
Eq(0x1301D0 + 0x138000), 0))
|
||||
EXPECT_CALL(script, PatchOverworldMosaic(_, Eq(mosaic_tiles),
|
||||
Eq(0x1301D0 + 0x138000), 0))
|
||||
.WillOnce(Return(absl::OkStatus()));
|
||||
|
||||
EXPECT_CALL(script, ApplyPatchToROM(_)).WillOnce(Return(absl::OkStatus()));
|
||||
|
||||
EXPECT_THAT(script.GenerateMosaicChangeAssembly(rom, mosaic_tiles,
|
||||
0x1301D0 + 0x138000, 0),
|
||||
absl::OkStatus());
|
||||
EXPECT_THAT(
|
||||
script.PatchOverworldMosaic(rom, mosaic_tiles, 0x1301D0 + 0x138000, 0),
|
||||
absl::OkStatus());
|
||||
EXPECT_THAT(script.ApplyPatchToROM(rom), absl::OkStatus());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user