CgxViewer, GraphicsEditor updates
This commit is contained in:
@@ -39,6 +39,7 @@ absl::Status GraphicsEditor::Update() {
|
|||||||
NEXT_COLUMN()
|
NEXT_COLUMN()
|
||||||
|
|
||||||
status_ = DrawCgxImport();
|
status_ = DrawCgxImport();
|
||||||
|
status_ = DrawClipboardImport();
|
||||||
status_ = DrawFileImport();
|
status_ = DrawFileImport();
|
||||||
status_ = DrawExperimentalFeatures();
|
status_ = DrawExperimentalFeatures();
|
||||||
|
|
||||||
@@ -99,20 +100,23 @@ absl::Status GraphicsEditor::DrawCgxImport() {
|
|||||||
ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(),
|
ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(),
|
||||||
sizeof(cgx_file_name_));
|
sizeof(cgx_file_name_));
|
||||||
status_ = temp_rom_.LoadFromFile(cgx_file_path_, /*z3_load=*/false);
|
status_ = temp_rom_.LoadFromFile(cgx_file_path_, /*z3_load=*/false);
|
||||||
cgx_viewer_.LoadCgx(temp_rom_);
|
|
||||||
auto all_tiles_data = cgx_viewer_.GetCgxData();
|
|
||||||
cgx_bitmap_.Create(core::kTilesheetWidth, 8192, core::kTilesheetDepth,
|
|
||||||
all_tiles_data.data(), all_tiles_data.size());
|
|
||||||
if (col_file_) {
|
|
||||||
cgx_bitmap_.ApplyPalette(col_file_palette_);
|
|
||||||
rom_.RenderBitmap(&cgx_bitmap_);
|
|
||||||
}
|
|
||||||
is_open_ = true;
|
is_open_ = true;
|
||||||
cgx_loaded_ = true;
|
cgx_loaded_ = true;
|
||||||
});
|
});
|
||||||
core::ButtonPipe("Copy File Path",
|
core::ButtonPipe("Copy File Path",
|
||||||
[&]() -> auto { ImGui::SetClipboardText(cgx_file_path_); });
|
[&]() -> auto { ImGui::SetClipboardText(cgx_file_path_); });
|
||||||
|
|
||||||
|
core::ButtonPipe("Decompress CGX Data", [&]() -> auto {
|
||||||
|
cgx_viewer_.LoadCgx(temp_rom_);
|
||||||
|
auto all_tiles_data = cgx_viewer_.GetCgxData();
|
||||||
|
cgx_bitmap_.Create(core::kTilesheetWidth, 8192, core::kTilesheetDepth,
|
||||||
|
all_tiles_data.data(), all_tiles_data.size());
|
||||||
|
if (col_file_) {
|
||||||
|
cgx_bitmap_.ApplyPalette(col_file_palette_);
|
||||||
|
rom_.RenderBitmap(&cgx_bitmap_);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
CLEAR_AND_RETURN_STATUS(status_)
|
CLEAR_AND_RETURN_STATUS(status_)
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
@@ -120,9 +124,6 @@ absl::Status GraphicsEditor::DrawCgxImport() {
|
|||||||
absl::Status GraphicsEditor::DrawFileImport() {
|
absl::Status GraphicsEditor::DrawFileImport() {
|
||||||
static int size = 0;
|
static int size = 0;
|
||||||
|
|
||||||
gui::TextWithSeparators("Clipboard Import");
|
|
||||||
RETURN_IF_ERROR(DrawClipboardImport())
|
|
||||||
|
|
||||||
gui::TextWithSeparators("BIN Import");
|
gui::TextWithSeparators("BIN Import");
|
||||||
|
|
||||||
ImGui::InputText("##ROMFile", file_path_, sizeof(file_path_));
|
ImGui::InputText("##ROMFile", file_path_, sizeof(file_path_));
|
||||||
@@ -140,10 +141,10 @@ absl::Status GraphicsEditor::DrawFileImport() {
|
|||||||
core::ButtonPipe("Copy File Path",
|
core::ButtonPipe("Copy File Path",
|
||||||
[&]() -> auto { ImGui::SetClipboardText(file_path_); });
|
[&]() -> auto { ImGui::SetClipboardText(file_path_); });
|
||||||
|
|
||||||
gui::InputHex("Offset", ¤t_offset_);
|
gui::InputHex("BIN Offset", ¤t_offset_);
|
||||||
gui::InputHex("Size ", &size);
|
gui::InputHex("BIN Size", &size);
|
||||||
|
|
||||||
if (ImGui::Button("BIN Import")) {
|
if (ImGui::Button("Decompress BIN")) {
|
||||||
if (strlen(file_path_) > 0) {
|
if (strlen(file_path_) > 0) {
|
||||||
RETURN_IF_ERROR(DecompressImportData(size))
|
RETURN_IF_ERROR(DecompressImportData(size))
|
||||||
} else {
|
} else {
|
||||||
@@ -168,7 +169,8 @@ absl::Status GraphicsEditor::DrawPaletteControls() {
|
|||||||
strncpy(col_file_name_,
|
strncpy(col_file_name_,
|
||||||
ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(),
|
ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(),
|
||||||
sizeof(col_file_name_));
|
sizeof(col_file_name_));
|
||||||
status_ = temp_rom_.LoadFromFile(col_file_path_, /*z3_load=*/false);
|
status_ = temp_rom_.LoadFromFile(col_file_path_,
|
||||||
|
/*z3_load=*/false);
|
||||||
auto col_data_ = gfx::GetColFileData(temp_rom_.data());
|
auto col_data_ = gfx::GetColFileData(temp_rom_.data());
|
||||||
col_file_palette_ = gfx::SNESPalette(col_data_);
|
col_file_palette_ = gfx::SNESPalette(col_data_);
|
||||||
col_file_ = true;
|
col_file_ = true;
|
||||||
@@ -193,32 +195,52 @@ absl::Status GraphicsEditor::DrawPaletteControls() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
absl::Status GraphicsEditor::DrawClipboardImport() {
|
absl::Status GraphicsEditor::DrawClipboardImport() {
|
||||||
static Bytes clipboard_data;
|
gui::TextWithSeparators("Clipboard Import");
|
||||||
|
core::ButtonPipe("Paste from Clipboard", [&]() -> auto {
|
||||||
if (ImGui::Button("Paste from Clipboard")) {
|
|
||||||
const char* text = ImGui::GetClipboardText();
|
const char* text = ImGui::GetClipboardText();
|
||||||
if (text) {
|
if (text) {
|
||||||
clipboard_data = Bytes(text, text + strlen(text));
|
const auto clipboard_data = Bytes(text, text + strlen(text));
|
||||||
ImGui::MemFree((void*)text);
|
ImGui::MemFree((void*)text);
|
||||||
RETURN_IF_ERROR(temp_rom_.LoadFromBytes(clipboard_data))
|
status_ = temp_rom_.LoadFromBytes(clipboard_data);
|
||||||
is_open_ = true;
|
is_open_ = true;
|
||||||
open_memory_editor_ = true;
|
open_memory_editor_ = true;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
gui::InputHex("Offset", &clipboard_offset_);
|
||||||
|
gui::InputHex("Size", &clipboard_size_);
|
||||||
|
gui::InputHex("Num Sheets", &num_sheets_to_load_);
|
||||||
|
|
||||||
|
core::ButtonPipe("Decompress Clipboard Data", [&]() -> auto {
|
||||||
|
if (temp_rom_.isLoaded()) {
|
||||||
|
status_ = DecompressImportData(0x40000);
|
||||||
|
} else {
|
||||||
|
status_ = absl::InvalidArgumentError(
|
||||||
|
"Please paste data into the clipboard before "
|
||||||
|
"decompressing.");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int import_size = 0;
|
||||||
|
int num_sheets = 0;
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Status GraphicsEditor::DrawExperimentalFeatures() {
|
absl::Status GraphicsEditor::DrawExperimentalFeatures() {
|
||||||
gui::TextWithSeparators("Experimental");
|
gui::TextWithSeparators("Experimental");
|
||||||
if (ImGui::Button("Import Super Donkey Full")) {
|
if (ImGui::Button("Decompress Super Donkey Full")) {
|
||||||
if (strlen(file_path_) > 0) {
|
if (strlen(file_path_) > 0) {
|
||||||
RETURN_IF_ERROR(DecompressSuperDonkey())
|
RETURN_IF_ERROR(DecompressSuperDonkey())
|
||||||
} else {
|
} else {
|
||||||
return absl::InvalidArgumentError(
|
return absl::InvalidArgumentError(
|
||||||
"Please select `super_donkey_1.bin` before importing.");
|
"Please select `super_donkey_1.bin` before "
|
||||||
|
"importing.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ImGui::SetItemTooltip(
|
||||||
|
"Requires `super_donkey_1.bin` to be imported under the "
|
||||||
|
"BIN import "
|
||||||
|
"section.");
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,7 +323,12 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
|
|||||||
graphics_bin_[i] =
|
graphics_bin_[i] =
|
||||||
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
|
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
|
||||||
core::kTilesheetDepth, converted_sheet.data(), 0x1000);
|
core::kTilesheetDepth, converted_sheet.data(), 0x1000);
|
||||||
graphics_bin_[i].ApplyPalette(palette_);
|
if (col_file_) {
|
||||||
|
graphics_bin_[i].ApplyPalette(col_file_palette_);
|
||||||
|
} else {
|
||||||
|
// ROM palette
|
||||||
|
graphics_bin_[i].ApplyPalette(palette_);
|
||||||
|
}
|
||||||
|
|
||||||
rom_.RenderBitmap(&graphics_bin_[i]);
|
rom_.RenderBitmap(&graphics_bin_[i]);
|
||||||
i++;
|
i++;
|
||||||
@@ -317,7 +344,12 @@ absl::Status GraphicsEditor::DecompressSuperDonkey() {
|
|||||||
graphics_bin_[i] =
|
graphics_bin_[i] =
|
||||||
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
|
gfx::Bitmap(core::kTilesheetWidth, core::kTilesheetHeight,
|
||||||
core::kTilesheetDepth, converted_sheet.data(), 0x1000);
|
core::kTilesheetDepth, converted_sheet.data(), 0x1000);
|
||||||
graphics_bin_[i].ApplyPalette(palette_);
|
if (col_file_) {
|
||||||
|
graphics_bin_[i].ApplyPalette(col_file_palette_);
|
||||||
|
} else {
|
||||||
|
// ROM palette
|
||||||
|
graphics_bin_[i].ApplyPalette(palette_);
|
||||||
|
}
|
||||||
|
|
||||||
rom_.RenderBitmap(&graphics_bin_[i]);
|
rom_.RenderBitmap(&graphics_bin_[i]);
|
||||||
i++;
|
i++;
|
||||||
|
|||||||
@@ -20,14 +20,17 @@
|
|||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace editor {
|
namespace editor {
|
||||||
|
// "99973","A3D80",
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
const std::string kSuperDonkeyTiles[] = {
|
const std::string kSuperDonkeyTiles[] = {
|
||||||
"97C05", "98219", "9871E", "98C00", "99084", "995AF", "99973",
|
"97C05", "98219", "9871E", "98C00", "99084", "995AF",
|
||||||
"99DE0", "9A27E", "9A741", "9AC31", "9B07E", "9B55C", "9B963",
|
"99DE0", "9A27E", "9A741", "9AC31", "9B07E", "9B55C", "9B963",
|
||||||
"9BB99", "9C009", "9C4B4", "9C92B", "9CDD6", "9D2C2", "9E037",
|
"9BB99", "9C009", "9C4B4", "9C92B", "9CDD6", "9D2C2", "9E037",
|
||||||
"9E527", "9EA56", "9EF65", "9FCD1", "A0193", "A059E", "A0B17",
|
"9E527", "9EA56", "9EF65", "9FCD1", "A0193", "A059E", "A0B17",
|
||||||
"A0FB6", "A14A5", "A1988", "A1E66", "A232B", "A27F0", "A2B6E",
|
"A0FB6", "A14A5", "A1988", "A1E66", "A232B", "A27F0", "A2B6E",
|
||||||
"A302C", "A3453", "A38CA", "A3D80", "A42BB", "A470C", "A4BA9",
|
"A302C", "A3453", "A38CA", "A42BB", "A470C", "A4BA9",
|
||||||
"A5089", "A5385", "A5742", "A5BCC", "A6017", "A6361", "A66F8"};
|
"A5089", "A5385", "A5742", "A5BCC", "A6017", "A6361", "A66F8"};
|
||||||
|
|
||||||
const std::string kSuperDonkeySprites[] = {
|
const std::string kSuperDonkeySprites[] = {
|
||||||
@@ -81,7 +84,12 @@ class GraphicsEditor {
|
|||||||
int current_size_ = 0;
|
int current_size_ = 0;
|
||||||
int current_palette_ = 0;
|
int current_palette_ = 0;
|
||||||
int current_palette_index_ = 0;
|
int current_palette_index_ = 0;
|
||||||
|
|
||||||
int num_sheets_to_load_ = 1;
|
int num_sheets_to_load_ = 1;
|
||||||
|
|
||||||
|
int clipboard_offset_ = 0;
|
||||||
|
int clipboard_size_ = 0;
|
||||||
|
|
||||||
bool open_memory_editor_ = false;
|
bool open_memory_editor_ = false;
|
||||||
bool gfx_loaded_ = false;
|
bool gfx_loaded_ = false;
|
||||||
bool is_open_ = false;
|
bool is_open_ = false;
|
||||||
@@ -102,7 +110,9 @@ class GraphicsEditor {
|
|||||||
Bytes import_data_;
|
Bytes import_data_;
|
||||||
Bytes graphics_buffer_;
|
Bytes graphics_buffer_;
|
||||||
|
|
||||||
MemoryEditor memory_editor_;
|
MemoryEditor cgx_memory_editor_;
|
||||||
|
MemoryEditor col_memory_editor_;
|
||||||
|
|
||||||
PaletteEditor palette_editor_;
|
PaletteEditor palette_editor_;
|
||||||
|
|
||||||
gfx::Bitmap cgx_bitmap_;
|
gfx::Bitmap cgx_bitmap_;
|
||||||
|
|||||||
@@ -291,10 +291,25 @@ void MasterEditor::DrawViewMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MasterEditor::DrawHelpMenu() {
|
void MasterEditor::DrawHelpMenu() {
|
||||||
|
static bool open_rom_help = false;
|
||||||
if (ImGui::BeginMenu("Help")) {
|
if (ImGui::BeginMenu("Help")) {
|
||||||
|
if (ImGui::MenuItem("How to open a ROM")) open_rom_help = true;
|
||||||
if (ImGui::MenuItem("About")) about_ = true;
|
if (ImGui::MenuItem("About")) about_ = true;
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (open_rom_help) ImGui::OpenPopup("Open a ROM");
|
||||||
|
if (ImGui::BeginPopupModal("Open a ROM", nullptr,
|
||||||
|
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::Text("The Legend of Zelda: A Link to the Past");
|
||||||
|
ImGui::Text("US Version 1.0");
|
||||||
|
|
||||||
|
if (ImGui::Button("Close", gui::kDefaultModalSize)) {
|
||||||
|
open_rom_help = false;
|
||||||
|
ImGui::CloseCurrentPopup();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MasterEditor::DrawOverworldEditor() {
|
void MasterEditor::DrawOverworldEditor() {
|
||||||
|
|||||||
@@ -307,11 +307,16 @@ absl::Status ROM::LoadFromFile(const absl::string_view& filename,
|
|||||||
absl::StrCat("Could not open ROM file: ", filename));
|
absl::StrCat("Could not open ROM file: ", filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_header = false;
|
||||||
|
int header_count = 0x200;
|
||||||
size_ = std::filesystem::file_size(filename);
|
size_ = std::filesystem::file_size(filename);
|
||||||
rom_data_.resize(size_);
|
rom_data_.resize(size_);
|
||||||
for (auto i = 0; i < size_; ++i) {
|
for (auto i = 0; i < size_; ++i) {
|
||||||
char byte_to_read = ' ';
|
char byte_to_read = ' ';
|
||||||
file.read(&byte_to_read, sizeof(char));
|
file.read(&byte_to_read, sizeof(char));
|
||||||
|
if (byte_to_read == 0x00) {
|
||||||
|
has_header = true;
|
||||||
|
}
|
||||||
rom_data_[i] = byte_to_read;
|
rom_data_[i] = byte_to_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace app {
|
|||||||
namespace viewer {
|
namespace viewer {
|
||||||
|
|
||||||
constexpr int kMatchedBytes[] = {0x4E, 0x41, 0x4B, 0x31, 0x39, 0x38, 0x39};
|
constexpr int kMatchedBytes[] = {0x4E, 0x41, 0x4B, 0x31, 0x39, 0x38, 0x39};
|
||||||
|
constexpr int kOffsetFromMatchedBytesEnd = 0x1D;
|
||||||
|
|
||||||
void CgxViewer::LoadCgx(ROM &cgx_rom) {
|
void CgxViewer::LoadCgx(ROM &cgx_rom) {
|
||||||
std::cout << "Loading CGX" << std::endl;
|
std::cout << "Loading CGX" << std::endl;
|
||||||
@@ -22,27 +23,32 @@ void CgxViewer::LoadCgx(ROM &cgx_rom) {
|
|||||||
|
|
||||||
int matching_position = -1;
|
int matching_position = -1;
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
for (int i = 0; i < cgx_rom.size(); i++) {
|
for (int i = 0;
|
||||||
if (matched) {
|
i < cgx_rom.size() - sizeof(kMatchedBytes) - kOffsetFromMatchedBytesEnd;
|
||||||
break;
|
i++) {
|
||||||
}
|
|
||||||
|
|
||||||
raw_data_[i] = cgx_rom[i];
|
raw_data_[i] = cgx_rom[i];
|
||||||
for (int j = 0; j < 7; j++) {
|
bool is_match = std::equal(std::begin(kMatchedBytes),
|
||||||
if (cgx_rom[i + j] == kMatchedBytes[j]) {
|
std::end(kMatchedBytes), &cgx_rom[i]);
|
||||||
if (j == 7 - 1) {
|
if (is_match) {
|
||||||
matching_position = i;
|
matching_position = i;
|
||||||
matched = true;
|
matched = true;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label1_text = absl::StrCat("CGX In Folder L : ",
|
if (matched) {
|
||||||
absl::StrFormat("%X4", matching_position));
|
int bpp_marker_position =
|
||||||
|
matching_position + sizeof(kMatchedBytes) + kOffsetFromMatchedBytesEnd;
|
||||||
|
int bpp_marker = cgx_rom[bpp_marker_position];
|
||||||
|
std::string bpp_type = (bpp_marker == 0x31) ? "8bpp" : "4bpp";
|
||||||
|
int current_selection_ = (bpp_type == "8bpp") ? 8 : 4;
|
||||||
|
label1_text = absl::StrCat(
|
||||||
|
"CGX In Folder L : ", absl::StrFormat("%X4", matching_position),
|
||||||
|
" BPP Type : ", bpp_type);
|
||||||
|
} else {
|
||||||
|
label1_text = "No match found in CGX";
|
||||||
|
}
|
||||||
|
|
||||||
LoadGfx(current_selection_);
|
LoadGfx(current_selection_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class CgxViewer {
|
|||||||
std::string label1_text;
|
std::string label1_text;
|
||||||
|
|
||||||
int bpp_;
|
int bpp_;
|
||||||
int current_selection_;
|
int current_selection_ = 2;
|
||||||
|
|
||||||
ROM all_tiles_data_;
|
ROM all_tiles_data_;
|
||||||
ROM raw_data_;
|
ROM raw_data_;
|
||||||
|
|||||||
Reference in New Issue
Block a user