From c336c6006632d1c91fc510af01f77eba4298c745 Mon Sep 17 00:00:00 2001 From: scawful Date: Wed, 9 Aug 2023 00:19:07 -0400 Subject: [PATCH] Add scad_format for CGX, COL, OBJ files --- src/CMakeLists.txt | 1 + src/app/editor/graphics_editor.cc | 110 +++++++------ src/app/editor/graphics_editor.h | 7 + src/app/editor/palette_editor.cc | 9 +- src/app/editor/palette_editor.h | 2 +- src/app/gfx/bitmap.cc | 29 ++++ src/app/gfx/bitmap.h | 5 + src/app/gfx/scad_format.cc | 262 ++++++++++++++++++++++++++++++ src/app/gfx/scad_format.h | 71 ++++++++ src/app/gfx/snes_tile.cc | 18 +- src/app/viewer/cgx_viewer.cc | 60 +++---- src/app/viewer/cgx_viewer.h | 2 + 12 files changed, 485 insertions(+), 91 deletions(-) create mode 100644 src/app/gfx/scad_format.cc create mode 100644 src/app/gfx/scad_format.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 52924a5a..084ccfc6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,6 +23,7 @@ set( YAZE_APP_GFX_SRC app/gfx/bitmap.cc app/gfx/compression.cc + app/gfx/scad_format.cc app/gfx/snes_palette.cc app/gfx/snes_tile.cc ) diff --git a/src/app/editor/graphics_editor.cc b/src/app/editor/graphics_editor.cc index 1a5c2c4a..cb9433d5 100644 --- a/src/app/editor/graphics_editor.cc +++ b/src/app/editor/graphics_editor.cc @@ -11,6 +11,8 @@ #include "app/editor/palette_editor.h" #include "app/gfx/bitmap.h" #include "app/gfx/compression.h" +#include "app/gfx/scad_format.h" +#include "app/gfx/snes_palette.h" #include "app/gfx/snes_tile.h" #include "app/gui/canvas.h" #include "app/gui/input.h" @@ -114,7 +116,10 @@ absl::Status GraphicsEditor::DrawCgxImport() { strncpy(cgx_file_name_, ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(), sizeof(cgx_file_name_)); - status_ = temp_rom_.LoadFromFile(cgx_file_path_, /*z3_load=*/false); + // status_ = temp_rom_.LoadFromFile(cgx_file_path_, /*z3_load=*/false); + status_ = gfx::DecodeCgxFile(cgx_file_path_, cgx_data_, extra_cgx_data_, + decoded_cgx_); + auto cgx_header = gfx::ExtractCgxHeader(extra_cgx_data_); is_open_ = true; cgx_loaded_ = true; }); @@ -122,17 +127,69 @@ absl::Status GraphicsEditor::DrawCgxImport() { [this]() { ImGui::SetClipboardText(cgx_file_path_); }); core::ButtonPipe("Decompress CGX Data", [this]() { + /* 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()); + */ + // cgx_surface_ = gfx::CreateCgxPreviewImage(current_palette_index_, + // cgx_data_, + // extra_cgx_data_, decoded_col_); + // cgx_bitmap_.CreateFromSurface(cgx_surface_); + + cgx_bitmap_.Create(0x80, 0x200, 8, decoded_cgx_); if (col_file_) { - cgx_bitmap_.ApplyPalette(col_file_palette_); + // cgx_bitmap_.ApplyPalette(col_file_palette_); + cgx_bitmap_.ApplyPalette(decoded_col_); rom_.RenderBitmap(&cgx_bitmap_); } }); - CLEAR_AND_RETURN_STATUS(status_) + return absl::OkStatus(); +} + +absl::Status GraphicsEditor::DrawPaletteControls() { + gui::TextWithSeparators("COL Import"); + ImGui::InputText("##ColFile", col_file_name_, sizeof(col_file_name_)); + ImGui::SameLine(); + + core::FileDialogPipeline( + "ImportColKey", ".COL,.col,.BAK,.bak\0", "Open COL", [this]() { + strncpy(col_file_path_, + ImGuiFileDialog::Instance()->GetFilePathName().c_str(), + sizeof(col_file_path_)); + strncpy(col_file_name_, + ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(), + sizeof(col_file_name_)); + status_ = temp_rom_.LoadFromFile(col_file_path_, + /*z3_load=*/false); + auto col_data_ = gfx::GetColFileData(temp_rom_.data()); + if (col_file_palette_group_.size() != 0) { + col_file_palette_group_.Clear(); + } + col_file_palette_group_ = gfx::CreatePaletteGroupFromColFile(col_data_); + col_file_palette_ = gfx::SNESPalette(col_data_); + + // gigaleak dev format based code + decoded_col_ = gfx::DecodeColFile(col_file_path_); + col_file_ = true; + is_open_ = true; + }); + + core::ButtonPipe("Copy COL Path", + [this]() { ImGui::SetClipboardText(col_file_path_); }); + + if (rom_.isLoaded()) { + gui::TextWithSeparators("ROM Palette"); + gui::InputHex("Palette Index", ¤t_palette_index_); + ImGui::Combo("Palette", ¤t_palette_, kPaletteGroupAddressesKeys, + IM_ARRAYSIZE(kPaletteGroupAddressesKeys)); + } + + if (col_file_palette_.size() != 0) { + core::SelectablePalettePipeline(current_palette_index_, refresh_graphics_, + col_file_palette_); + } + return absl::OkStatus(); } @@ -167,49 +224,6 @@ absl::Status GraphicsEditor::DrawFileImport() { return absl::OkStatus(); } -absl::Status GraphicsEditor::DrawPaletteControls() { - gui::TextWithSeparators("COL Import"); - ImGui::InputText("##ColFile", col_file_name_, sizeof(col_file_name_)); - ImGui::SameLine(); - - core::FileDialogPipeline( - "ImportColKey", ".COL,.col,.BAK,.bak\0", "Open COL", [this]() { - strncpy(col_file_path_, - ImGuiFileDialog::Instance()->GetFilePathName().c_str(), - sizeof(col_file_path_)); - strncpy(col_file_name_, - ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(), - sizeof(col_file_name_)); - status_ = temp_rom_.LoadFromFile(col_file_path_, - /*z3_load=*/false); - auto col_data_ = gfx::GetColFileData(temp_rom_.data()); - if (col_file_palette_group_.size() != 0) { - col_file_palette_group_.Clear(); - } - col_file_palette_group_ = gfx::CreatePaletteGroupFromColFile(col_data_); - col_file_palette_ = gfx::SNESPalette(col_data_); - col_file_ = true; - is_open_ = true; - }); - - core::ButtonPipe("Copy COL Path", - [this]() { ImGui::SetClipboardText(col_file_path_); }); - - if (rom_.isLoaded()) { - gui::TextWithSeparators("ROM Palette"); - gui::InputHex("Palette Index", ¤t_palette_index_); - ImGui::Combo("Palette", ¤t_palette_, kPaletteGroupAddressesKeys, - IM_ARRAYSIZE(kPaletteGroupAddressesKeys)); - } - - if (col_file_palette_.size() != 0) { - core::SelectablePalettePipeline(current_palette_index_, refresh_graphics_, - col_file_palette_); - } - - return absl::OkStatus(); -} - absl::Status GraphicsEditor::DrawClipboardImport() { gui::TextWithSeparators("Clipboard Import"); core::ButtonPipe("Paste from Clipboard", [this]() { diff --git a/src/app/editor/graphics_editor.h b/src/app/editor/graphics_editor.h index 3224ae0f..2aec4420 100644 --- a/src/app/editor/graphics_editor.h +++ b/src/app/editor/graphics_editor.h @@ -111,6 +111,13 @@ class GraphicsEditor { Bytes import_data_; Bytes graphics_buffer_; + std::vector decoded_cgx_; + std::vector cgx_data_; + std::vector extra_cgx_data_; + std::vector decoded_col_; + + SDL_Surface* cgx_surface_; + MemoryEditor cgx_memory_editor_; MemoryEditor col_memory_editor_; diff --git a/src/app/editor/palette_editor.cc b/src/app/editor/palette_editor.cc index 1628c525..80a38db9 100644 --- a/src/app/editor/palette_editor.cc +++ b/src/app/editor/palette_editor.cc @@ -36,14 +36,14 @@ namespace editor { absl::Status PaletteEditor::Update() { for (int i = 0; i < kNumPalettes; ++i) { if (ImGui::TreeNode(kPaletteCategoryNames[i].data())) { - DrawPaletteGroup(i); + RETURN_IF_ERROR(DrawPaletteGroup(i)) ImGui::TreePop(); } } return absl::OkStatus(); } -void PaletteEditor::DrawPaletteGroup(int i) { +absl::Status PaletteEditor::DrawPaletteGroup(int i) { auto size = rom_.GetPaletteGroup(kPaletteGroupNames[i].data()).size(); auto palettes = rom_.GetPaletteGroup(kPaletteGroupNames[i].data()); for (int j = 0; j < size; j++) { @@ -73,8 +73,8 @@ void PaletteEditor::DrawPaletteGroup(int i) { if (ImGui::ColorEdit4( "Edit Color", col.data(), ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoAlpha)) { - rom_.UpdatePaletteColor(kPaletteGroupNames[i].data(), j, n, - palette[n]); + RETURN_IF_ERROR(rom_.UpdatePaletteColor(kPaletteGroupNames[i].data(), + j, n, palette[n])) } if (ImGui::Button("Copy as..", ImVec2(-1, 0))) ImGui::OpenPopup("Copy"); if (ImGui::BeginPopup("Copy")) { @@ -99,6 +99,7 @@ void PaletteEditor::DrawPaletteGroup(int i) { ImGui::PopID(); } } + return absl::OkStatus(); } void PaletteEditor::DisplayPalette(gfx::SNESPalette& palette, bool loaded) { diff --git a/src/app/editor/palette_editor.h b/src/app/editor/palette_editor.h index 1022cf6c..4c755883 100644 --- a/src/app/editor/palette_editor.h +++ b/src/app/editor/palette_editor.h @@ -36,7 +36,7 @@ class PaletteEditor { auto SetupROM(ROM& rom) { rom_ = rom; } private: - void DrawPaletteGroup(int i); + absl::Status DrawPaletteGroup(int i); ImVec4 saved_palette_[256] = {}; ImVec4 current_color_; diff --git a/src/app/gfx/bitmap.cc b/src/app/gfx/bitmap.cc index cda07eaa..b5ce5f0e 100644 --- a/src/app/gfx/bitmap.cc +++ b/src/app/gfx/bitmap.cc @@ -104,6 +104,19 @@ void Bitmap::Create(int width, int height, int depth, Bytes data) { GrayscalePalette(surface_->format->palette); } +void Bitmap::CreateFromSurface(SDL_Surface *surface) { + active_ = true; + width_ = surface->w; + height_ = surface->h; + depth_ = 8; + pixel_data_ = static_cast(surface->pixels); + surface_ = std::unique_ptr( + SDL_CreateRGBSurfaceWithFormat(0, width_, height_, depth_, + SDL_PIXELFORMAT_INDEX8), + SDL_Surface_Deleter()); + surface_->pixels = pixel_data_; +} + void Bitmap::Apply(Bytes data) { pixel_data_ = data.data(); data_ = data; @@ -124,6 +137,11 @@ void Bitmap::UpdateTexture(std::shared_ptr renderer) { SDL_Texture_Deleter{}}; } +void Bitmap::SetSurface(SDL_Surface *surface) { + surface_ = std::unique_ptr( + surface, SDL_Surface_Deleter()); +} + // Convert SNESPalette to SDL_Palette for surface. void Bitmap::ApplyPalette(const SNESPalette &palette) { palette_ = palette; @@ -144,6 +162,17 @@ void Bitmap::ApplyPalette(const SNESPalette &palette) { SDL_LockSurface(surface_.get()); } +void Bitmap::ApplyPalette(const std::vector &palette) { + SDL_UnlockSurface(surface_.get()); + for (int i = 0; i < palette.size(); ++i) { + surface_->format->palette->colors[i].r = palette[i].r; + surface_->format->palette->colors[i].g = palette[i].g; + surface_->format->palette->colors[i].b = palette[i].b; + surface_->format->palette->colors[i].a = palette[i].a; + } + SDL_LockSurface(surface_.get()); +} + } // namespace gfx } // namespace app } // namespace yaze diff --git a/src/app/gfx/bitmap.h b/src/app/gfx/bitmap.h index ad209bb5..ea46622e 100644 --- a/src/app/gfx/bitmap.h +++ b/src/app/gfx/bitmap.h @@ -28,13 +28,18 @@ class Bitmap { void Create(int width, int height, int depth, int data_size); void Create(int width, int height, int depth, uchar *data, int data_size); void Create(int width, int height, int depth, Bytes data); + + void CreateFromSurface(SDL_Surface *surface); void Apply(Bytes data); void CreateTexture(std::shared_ptr renderer); void UpdateTexture(std::shared_ptr renderer); + void SetSurface(SDL_Surface *surface); + void ApplyPalette(const SNESPalette &palette); + void ApplyPalette(const std::vector &palette); void WriteToPixel(int position, uchar value) { this->pixel_data_[position] = value; diff --git a/src/app/gfx/scad_format.cc b/src/app/gfx/scad_format.cc new file mode 100644 index 00000000..8d272fda --- /dev/null +++ b/src/app/gfx/scad_format.cc @@ -0,0 +1,262 @@ +#include "scad_format.h" + +#include +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "app/core/constants.h" + +namespace yaze { +namespace app { +namespace gfx { + +CgxHeader ExtractCgxHeader(std::vector& cgx_header) { + CgxHeader header; + memcpy(&header, cgx_header.data(), sizeof(CgxHeader)); + return header; +} + +absl::Status DecodeCgxFile(std::string_view filename, + std::vector& cgx_data, + std::vector& extra_cgx_data, + std::vector& decoded_cgx) { + std::ifstream file(filename, std::ios::binary); + if (!file.is_open()) { + return absl::NotFoundError("CGX file not found."); + } + + std::vector file_content((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + cgx_data = + std::vector(file_content.begin(), file_content.end() - 0x500); + file.seekg(cgx_data.size() + 0x100); + extra_cgx_data = std::vector((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + file.close(); + + decoded_cgx.clear(); + const uint16_t num_tiles = cgx_data.size() >> 5; + for (size_t i = 0; i < num_tiles; i++) { + for (int j = 0; j < 8; j++) { + for (int h = 0; h < 8; h++) { + uint8_t pixel = 0; + for (int l = 0; l < 2; l++) { + for (int k = 0; k < 2; k++) { + if (cgx_data[(i * 0x20) + (l * 0x10) + (j * 2) + k] & + (1 << (7 - h))) { + pixel = pixel | (1 << (l * 2 + k)); + } + } + } + decoded_cgx.push_back(pixel); + } + } + } + + if (decoded_cgx.size() < 0x10000) { + std::cout << "Resetting VRAM Offset to not be out of bounds." << std::endl; + //// default_offset "0" + } + return absl::OkStatus(); +} + +absl::Status DecodeObjFile( + std::string_view filename, std::vector& obj_data, + std::vector actual_obj_data, + std::unordered_map> decoded_obj, + std::vector& decoded_extra_obj, int& obj_loaded) { + std::vector header_obj; + int obj_range; + int expected_cut; + if (obj_loaded == 0) { + obj_range = 0x180; + expected_cut = 0x500; + } else { + obj_range = 0x300; + expected_cut = 0x900; + } + + std::ifstream file(filename, std::ios::binary); + if (!file.is_open()) { + return absl::NotFoundError("OBJ file not found."); + } + + std::vector file_content((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + obj_data = file_content; + file.close(); + + int cut = obj_data.size() & 0x0FFF; + actual_obj_data = + std::vector(obj_data.begin(), obj_data.end() - cut); + decoded_extra_obj = + std::vector(obj_data.begin() + actual_obj_data.size(), + obj_data.begin() + actual_obj_data.size() + 0x100); + header_obj = std::vector( + actual_obj_data.begin() + actual_obj_data.size(), actual_obj_data.end()); + + if (cut > expected_cut) { + std::vector scad_data; + int j = 0; + int k = (obj_loaded == 0) ? 63 : 127; + + for (size_t i = 0; i < (actual_obj_data.size() / 6); i++) { + std::vector data = { + actual_obj_data[k * 6 + 0 + j], // display + actual_obj_data[k * 6 + 1 + j], // unknown + actual_obj_data[k * 6 + 2 + j], // y-disp + actual_obj_data[k * 6 + 3 + j], // x-disp + actual_obj_data[k * 6 + 5 + j], // props + actual_obj_data[k * 6 + 4 + j] // tile + }; + scad_data.insert(scad_data.end(), data.begin(), data.end()); + + k = k - 1; + if (k == -1) { + k = (obj_loaded == 0) ? 63 : 127; + j = j + ((k + 1) * 6); + } + } + + int extra_data_range = 0x400 * (obj_loaded + 1) + 0x100; + for (int i = 0; i < extra_data_range; i++) { + scad_data.push_back(header_obj[i]); + } + + obj_data = scad_data; + actual_obj_data = + std::vector(obj_data.begin(), obj_data.end() - cut); + } + + decoded_obj.clear(); + for (int k = 0; k < 128; k++) { + decoded_obj["frame " + std::to_string(k)] = std::vector(obj_range); + for (int i = 0; i < obj_range; i++) { + try { + decoded_obj["frame " + std::to_string(k)][i] = + obj_data[i + (obj_range * k)]; + } catch (...) { + decoded_obj["frame " + std::to_string(k)][i] = 0; + } + } + } + + return absl::OkStatus(); +} + +std::vector DecodeColFile(const std::string& filename) { + std::vector decoded_col; + std::ifstream file(filename, std::ios::binary | std::ios::ate); + + if (!file.is_open()) { + return decoded_col; // Return an empty vector if the file couldn't be + // opened. + } + + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector buffer(size); + if (file.read(buffer.data(), size)) { + buffer.resize(size - 0x200); + + int k = 0; + for (size_t i = 0; i < buffer.size() / 2; i++) { + uint16_t current_color = static_cast(buffer[k]) | + (static_cast(buffer[k + 1]) << 8); + + SDL_Color color; + color.r = (current_color & 31) << 3; + color.g = ((current_color >> 5) & 31) << 3; + color.b = ((current_color >> 10) & 31) << 3; + color.a = (i & 0xF) == 0 ? 0 : 255; + + decoded_col.push_back(color); + k += 2; + } + } + + return decoded_col; +} + +SDL_Surface* CreateCgxPreviewImage(int default_cgram, + const std::vector& cgx_data, + const std::vector& extra_cgx_data, + std::vector decoded_col) { + std::vector>> tiles; + + const int target_width = 16; + const int target_height = 64; + int num_tiles = cgx_data.size() >> 5; + + int set_height = std::floor(num_tiles / target_width); + + for (int tile = 0; tile < num_tiles; tile++) { + std::vector> single_tile; + for (int row = 0; row < 8; row++) { + std::vector single_row; + for (int col = 0; col < 8; col++) { + int palette_num = 0; + for (int pair = 0; pair < 2; pair++) { + for (int bitplane = 0; bitplane < 2; bitplane++) { + if (cgx_data[(tile * 0x20) + (pair * 0x10) + (row * 2) + bitplane] & + (1 << (7 - col))) { + palette_num |= (1 << (pair * 2 + bitplane)); + } + } + } + single_row.push_back(palette_num); + } + single_tile.push_back(single_row); + } + tiles.push_back(single_tile); + } + + std::vector pixmap; + int row_i = 0; + for (int line = 0; line < set_height; line++) { + for (int row = 0; row < 8; row++) { + for (int i = 0; i < target_width; i++) { + for (int color : tiles[row_i + i][row]) { + pixmap.push_back(color); + } + } + } + row_i += target_width; + } + + int cols = target_width * 8; + int rows = target_height * 8; + + SDL_Surface* cgx_image = SDL_CreateRGBSurface(0, cols, rows, 32, 0, 0, 0, 0); + + int use_palette = default_cgram; + + for (int row = 0; row < rows; row++) { + for (int col = 0; col < cols; col++) { + int extra_data_index = (col >> 3) | (row & 0xFF8) << 1; + int palette_row = extra_cgx_data[extra_data_index]; + int index = (row * cols) + col; + + if (index >= 0 && index < pixmap.size() && + (pixmap[index] + use_palette + palette_row * 16) < + decoded_col.size()) { + SDL_Color color = + decoded_col[pixmap[index] + use_palette + palette_row * 16]; + uint32_t pixel = + SDL_MapRGBA(cgx_image->format, color.r, color.g, color.b, color.a); + ((uint32_t*)cgx_image->pixels)[(row * cols) + col] = pixel; + } + } + } + + return cgx_image; +} + +} // namespace gfx +} // namespace app +} // namespace yaze \ No newline at end of file diff --git a/src/app/gfx/scad_format.h b/src/app/gfx/scad_format.h new file mode 100644 index 00000000..314dd91a --- /dev/null +++ b/src/app/gfx/scad_format.h @@ -0,0 +1,71 @@ +#ifndef YAZE_APP_GFX_scad_format_H +#define YAZE_APP_GFX_scad_format_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/status/status.h" +#include "absl/status/statusor.h" +#include "app/core/constants.h" + +namespace yaze { +namespace app { +namespace gfx { + +// Address Description +// 00000 - 00003 File type "SCH" +// 00004 - 00008 Bit mode "?BIT" +// 00009 - 00013 Version number "Ver-????\n" +// 00014 - 00017 Header size +// 00018 - 0001B Hardware name "SFC" or "CGB" or "GB" +// 0001C - 0001C BG/OBJ flag (for AGB) +// 0001D - 0001D Color Pallette Number +// 0001D - 000FF Reserved +// 00100 - 001FF Color Path +struct CgxHeader { + char file_type[4]; + char bit_mode[5]; + char version_number[9]; + uint32_t header_size; + char hardware_name[4]; + uint8_t bg_obj_flag; + uint8_t color_palette_number; + uint8_t reserved[0xE3]; + uint8_t color_path[0x100]; +}; + +CgxHeader ExtractCgxHeader(std::vector& cgx_header); + +absl::Status DecodeCgxFile(std::string_view filename, + std::vector& cgx_data, + std::vector& extra_cgx_data, + std::vector& decoded_cgx); + +std::vector DecodeColFile(const std::string& filename); + +absl::Status DecodeObjFile( + std::string_view filename, std::vector& obj_data, + std::vector actual_obj_data, + std::unordered_map> decoded_obj, + std::vector& decoded_extra_obj, int& obj_loaded); + +SDL_Surface* CreateCgxPreviewImage(int default_cgram, + const std::vector& cgx_data, + const std::vector& extra_cgx_data, + std::vector decoded_col); + +} // namespace gfx +} // namespace app +} // namespace yaze + +#endif // YAZE_APP_GFX_scad_format_H \ No newline at end of file diff --git a/src/app/gfx/snes_tile.cc b/src/app/gfx/snes_tile.cc index 35b98d6a..b3b9fbf6 100644 --- a/src/app/gfx/snes_tile.cc +++ b/src/app/gfx/snes_tile.cc @@ -71,7 +71,7 @@ Bytes BPP8SNESToIndexed(Bytes data, uint64_t bpp) { // 16 tiles = 1024 bytes auto buffer = Bytes(data.size()); - auto bitmap_data = Bytes(128 * 128 + 2048); + auto bitmap_data = Bytes(0x80 * 0x800); int yy = 0; int xx = 0; int pos = 0; @@ -101,31 +101,31 @@ Bytes BPP8SNESToIndexed(Bytes data, uint64_t bpp) { auto b = 0; if (b1 != 0) { b |= 1; - }; + } if (b2 != 0) { b |= 2; - }; + } if (bpp >= 4) { if (b3 != 0) { b |= 4; - }; + } if (b4 != 0) { b |= 8; - }; + } } if (bpp >= 8) { if (b5 != 0) { b |= 0x10; - }; + } if (b6 != 0) { b |= 0x20; - }; + } if (b7 != 0) { b |= 0x40; - }; + } if (b8 != 0) { b |= 0x80; - }; + } } bitmap_data[((x + xx) * sheet_width) + y + (yy * 8)] = b; } diff --git a/src/app/viewer/cgx_viewer.cc b/src/app/viewer/cgx_viewer.cc index 80616d3b..5320f6d0 100644 --- a/src/app/viewer/cgx_viewer.cc +++ b/src/app/viewer/cgx_viewer.cc @@ -1,5 +1,6 @@ #include "cgx_viewer.h" +#include #include #include #include @@ -13,12 +14,13 @@ namespace yaze { namespace app { namespace viewer { -constexpr int kMatchedBytes[] = {0x4E, 0x41, 0x4B, 0x31, 0x39, 0x38, 0x39}; -constexpr int kOffsetFromMatchedBytesEnd = 0x1D; +constexpr uint16_t kMatchedBytes[] = {0x4E, 0x41, 0x4B, 0x31, 0x39, 0x38, 0x39}; +constexpr uint16_t kOffsetFromMatchedBytesEnd = 0x1D; -void CgxViewer::LoadCgx(ROM &cgx_rom) { +void CgxViewer::LoadCgx(ROM& cgx_rom) { int matching_position = -1; bool matched = false; + for (int i = 0; i < cgx_rom.size() - sizeof(kMatchedBytes) - kOffsetFromMatchedBytesEnd; i++) { @@ -48,8 +50,33 @@ void CgxViewer::LoadCgx(ROM &cgx_rom) { LoadGfx(current_selection_); } +void CgxViewer::LoadGfx(int combo_bpp) { + if (combo_bpp == 0) { + bpp_ = 4; + } else if (combo_bpp == 1) { + bpp_ = 2; + } else if (combo_bpp == 2) { + bpp_ = 8; + } else if (combo_bpp == 3) { + bpp_ = 40; + for (int i = 0; i < raw_data_.size(); i++) { + all_tiles_data_[i] = raw_data_[i]; + } + // Refresh palettes and "picture box" aka canvas + RefreshPalettes(); + return; + } + + Bytes decomp_sheet = gfx::BPP8SNESToIndexed(raw_data_.vector(), bpp_); + for (int i = 0; i < decomp_sheet.size(); i++) { + all_tiles_data_.push_back(decomp_sheet[i]); + } + + RefreshPalettes(); +} + void CgxViewer::DrawBG1(int p, int bpp) { - auto *ptr = (uchar *)screen_bitmap_.data(); + auto* ptr = (uchar*)screen_bitmap_.data(); // for each tile on the tile buffer for (int i = 0; i < 0x400; i++) { if (room_bg1_bitmap_.data()[i + p] != 0xFFFF) { @@ -85,31 +112,6 @@ void CgxViewer::DrawBG2() {} void CgxViewer::DrawOAM(int bpp, int drawmode, gfx::OAMTile data, int frame) {} -void CgxViewer::LoadGfx(int combo_bpp) { - if (combo_bpp == 0) { - bpp_ = 4; - } else if (combo_bpp == 1) { - bpp_ = 2; - } else if (combo_bpp == 2) { - bpp_ = 8; - } else if (combo_bpp == 3) { - bpp_ = 40; - for (int i = 0; i < raw_data_.size(); i++) { - all_tiles_data_[i] = raw_data_[i]; - } - // Refresh palettes and "picture box" aka canvas - RefreshPalettes(); - return; - } - - Bytes decomp_sheet = gfx::BPP8SNESToIndexed(raw_data_.vector(), bpp_); - for (int i = 0; i < decomp_sheet.size(); i++) { - all_tiles_data_.push_back(decomp_sheet[i]); - } - - RefreshPalettes(); -} - void CgxViewer::LoadScr() {} void CgxViewer::RefreshPalettes() {} diff --git a/src/app/viewer/cgx_viewer.h b/src/app/viewer/cgx_viewer.h index d250d590..96c9e872 100644 --- a/src/app/viewer/cgx_viewer.h +++ b/src/app/viewer/cgx_viewer.h @@ -2,6 +2,7 @@ #define YAZE_APP_VIEWER_CGX_VIEWER_H #include #include +#include #include #include "app/core/pipeline.h" @@ -14,6 +15,7 @@ namespace yaze { namespace app { namespace viewer { + class CgxViewer { public: void LoadCgx(ROM&);