diff --git a/src/app/editor/graphics_editor.cc b/src/app/editor/graphics_editor.cc index cb9433d5..e78ec9b8 100644 --- a/src/app/editor/graphics_editor.cc +++ b/src/app/editor/graphics_editor.cc @@ -50,8 +50,9 @@ absl::Status GraphicsEditor::Update() { status_ = DrawPaletteControls(); NEXT_COLUMN() - core::BitmapCanvasPipeline(0x200, 0x200, 0x20, scr_loaded_, cgx_bitmap_, + core::BitmapCanvasPipeline(0x200, 0x200, 0x20, scr_loaded_, scr_bitmap_, false, 0); + status_ = DrawScrImport(); NEXT_COLUMN() if (super_donkey_) { @@ -105,6 +106,7 @@ absl::Status GraphicsEditor::DrawToolset() { absl::Status GraphicsEditor::DrawCgxImport() { gui::TextWithSeparators("Cgx Import"); + ImGui::InputInt("BPP", ¤t_bpp_); ImGui::InputText("##CGXFile", cgx_file_name_, sizeof(cgx_file_name_)); ImGui::SameLine(); @@ -116,10 +118,6 @@ 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_ = 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; }); @@ -127,18 +125,10 @@ 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_surface_ = gfx::CreateCgxPreviewImage(current_palette_index_, - // cgx_data_, - // extra_cgx_data_, decoded_col_); - // cgx_bitmap_.CreateFromSurface(cgx_surface_); - + status_ = gfx::LoadCgx(current_bpp_, cgx_file_path_, cgx_data_, + decoded_cgx_, extra_cgx_data_); cgx_bitmap_.Create(0x80, 0x200, 8, decoded_cgx_); if (col_file_) { - // cgx_bitmap_.ApplyPalette(col_file_palette_); cgx_bitmap_.ApplyPalette(decoded_col_); rom_.RenderBitmap(&cgx_bitmap_); } @@ -147,6 +137,39 @@ absl::Status GraphicsEditor::DrawCgxImport() { return absl::OkStatus(); } +absl::Status GraphicsEditor::DrawScrImport() { + ImGui::InputText("##ScrFile", scr_file_name_, sizeof(scr_file_name_)); + + core::FileDialogPipeline("ImportScrKey", ".SCR,.scr\0", "Open SCR", [this]() { + strncpy(scr_file_path_, + ImGuiFileDialog::Instance()->GetFilePathName().c_str(), + sizeof(scr_file_path_)); + strncpy(scr_file_name_, + ImGuiFileDialog::Instance()->GetCurrentFileName().c_str(), + sizeof(scr_file_name_)); + is_open_ = true; + scr_loaded_ = true; + }); + + ImGui::InputInt("SCR Mod", &scr_mod_value_); + + core::ButtonPipe("Load Scr Data", [this]() { + status_ = gfx::LoadScr(scr_file_path_, scr_mod_value_, scr_data_); + + decoded_scr_data_.resize(0x100 * 0x100); + status_ = gfx::DrawScrWithCgx(current_bpp_, scr_data_, decoded_scr_data_, + decoded_cgx_); + + scr_bitmap_.Create(0x100, 0x100, 8, decoded_scr_data_); + if (scr_loaded_) { + scr_bitmap_.ApplyPalette(decoded_col_); + rom_.RenderBitmap(&scr_bitmap_); + } + }); + + return absl::OkStatus(); +} + absl::Status GraphicsEditor::DrawPaletteControls() { gui::TextWithSeparators("COL Import"); ImGui::InputText("##ColFile", col_file_name_, sizeof(col_file_name_)); diff --git a/src/app/editor/graphics_editor.h b/src/app/editor/graphics_editor.h index 2aec4420..3c8dafe9 100644 --- a/src/app/editor/graphics_editor.h +++ b/src/app/editor/graphics_editor.h @@ -68,6 +68,7 @@ class GraphicsEditor { private: absl::Status DrawToolset(); absl::Status DrawCgxImport(); + absl::Status DrawScrImport(); absl::Status DrawFileImport(); absl::Status DrawPaletteControls(); absl::Status DrawClipboardImport(); @@ -83,6 +84,10 @@ class GraphicsEditor { int current_palette_ = 0; uint64_t current_palette_index_ = 0; + int current_bpp_ = 0; + + int scr_mod_value_ = 0; + uint64_t num_sheets_to_load_ = 1; uint64_t bin_size_ = 0; @@ -106,6 +111,9 @@ class GraphicsEditor { char cgx_file_path_[256] = ""; char cgx_file_name_[256] = ""; + char scr_file_path_[256] = ""; + char scr_file_name_[256] = ""; + ROM rom_; ROM temp_rom_; Bytes import_data_; @@ -116,7 +124,8 @@ class GraphicsEditor { std::vector extra_cgx_data_; std::vector decoded_col_; - SDL_Surface* cgx_surface_; + std::vector scr_data_; + std::vector decoded_scr_data_; MemoryEditor cgx_memory_editor_; MemoryEditor col_memory_editor_; @@ -124,6 +133,7 @@ class GraphicsEditor { PaletteEditor palette_editor_; gfx::Bitmap cgx_bitmap_; + gfx::Bitmap scr_bitmap_; gfx::Bitmap bitmap_; gui::Canvas import_canvas_; diff --git a/src/app/gfx/scad_format.cc b/src/app/gfx/scad_format.cc index 8d272fda..a8883046 100644 --- a/src/app/gfx/scad_format.cc +++ b/src/app/gfx/scad_format.cc @@ -9,6 +9,7 @@ #include "absl/status/status.h" #include "app/core/constants.h" +#include "app/gfx/snes_tile.h" namespace yaze { namespace app { @@ -19,48 +20,90 @@ CgxHeader ExtractCgxHeader(std::vector& cgx_header) { memcpy(&header, cgx_header.data(), sizeof(CgxHeader)); return header; } +absl::Status LoadScr(std::string_view filename, uint8_t input_value, + std::vector& map_data) { + std::ifstream file(filename, std::ios::binary); + if (!file.is_open()) { + return absl::NotFoundError("SCR/PNL/MAP file not found."); + } -absl::Status DecodeCgxFile(std::string_view filename, - std::vector& cgx_data, - std::vector& extra_cgx_data, - std::vector& decoded_cgx) { + // Check if file extension is PNL + bool pnl = false; + if (pnl) { + std::vector scr_data; + map_data.resize(0x8000); + scr_data.resize(0x8000); + + // Read from file for 0x8000 bytes + std::vector file_content((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + scr_data = std::vector(file_content.begin(), file_content.end()); + + int md = 0x100; + + for (int i = input_value * 0x400; i < 0x1000 + input_value * 0x400; + i += 2) { + auto b1_pos = (i - (input_value * 0x400)); + map_data[b1_pos] = gfx::TileInfoToShort( + gfx::GetTilesInfo((ushort)scr_data[md + (i * 2)])); + + // new Tile((scrdata[md + (i * 2) + 1]), (scrdata[md + (i * 2)])) + // .getshortileinfo(); + + auto b2_pos = (i - (input_value * 0x400) + 1); + map_data[b2_pos] = gfx::TileInfoToShort( + gfx::GetTilesInfo((ushort)scr_data[md + (i * 2) + 2])); + + // new Tile((scrdata[md + (i * 2) + 3]), (scrdata[md + (i * 2) + 2])) + // .getshortileinfo(); + } + // 0x900 + + } else { + int offset = 0; + std::vector scr_data; + map_data.resize(0x2000); + scr_data.resize(0x2000); + + // read from file for 0x2000 bytes + std::vector file_content((std::istreambuf_iterator(file)), + std::istreambuf_iterator()); + scr_data = std::vector(file_content.begin(), file_content.end()); + + for (int i = 0; i < 0x1000 - offset; i++) { + map_data[i] = gfx::TileInfoToShort( + gfx::GetTilesInfo((ushort)scr_data[((i + offset) * 2)])); + + // new Tile(scrdata[((i + offset) * 2)], + // scrdata[((i + offset) * 2) + 1]) + // .getshortileinfo(); + } + } + return absl::OkStatus(); +} + +absl::Status LoadCgx(uint8_t bpp, std::string_view filename, + std::vector& cgx_data, + std::vector& cgx_loaded, + std::vector& cgx_header) { 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()); + cgx_header = 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" + if (bpp > 8) { + cgx_loaded = gfx::BPP8SNESToIndexed(cgx_data, 40); + return absl::OkStatus(); } + cgx_loaded = gfx::BPP8SNESToIndexed(cgx_data, bpp); return absl::OkStatus(); } @@ -148,6 +191,48 @@ absl::Status DecodeObjFile( return absl::OkStatus(); } +absl::Status DrawScrWithCgx(uint8_t bpp, std::vector& map_data, + std::vector& map_bitmap_data, + std::vector& cgx_loaded) { + const std::vector dimensions = {0x000, 0x400, 0x800, 0xC00}; + uint8_t p = 0; + for (const auto each_dimension : dimensions) { + p = each_dimension; + // for each tile on the tile buffer + for (int i = 0; i < 0x400; i++) { + if (cgx_loaded[i + p] != 0xFFFF) { + auto t = gfx::GetTilesInfo(cgx_loaded[i + p]); + + for (auto yl = 0; yl < 8; yl++) { + for (auto xl = 0; xl < 8; xl++) { + int mx = xl * (1 - t.horizontal_mirror_) + + (7 - xl) * (t.horizontal_mirror_); + int my = + yl * (1 - t.vertical_mirror_) + (7 - yl) * (t.vertical_mirror_); + + int ty = (t.id_ / 16) * 1024; + int tx = (t.id_ % 16) * 8; + auto pixel = cgx_loaded[(tx + ty) + (yl * 128) + xl]; + + int index = + (((i % 32) * 8) + ((i / 32) * 2048) + (mx) + (my * 256)); + + if (bpp != 8) { + map_bitmap_data[index] = + (uchar)(((pixel)&0xFF) + t.palette_ * 16); + } else { + map_bitmap_data[index] = (uchar)(((pixel)&0xFF)); + } + + // + t.palette * 16 + } + } + } + } + } + return absl::OkStatus(); +} + std::vector DecodeColFile(const std::string& filename) { std::vector decoded_col; std::ifstream file(filename, std::ios::binary | std::ios::ate); @@ -183,80 +268,6 @@ std::vector DecodeColFile(const std::string& filename) { 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 index 314dd91a..b8b651da 100644 --- a/src/app/gfx/scad_format.h +++ b/src/app/gfx/scad_format.h @@ -22,16 +22,18 @@ 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 +// キャラクタ(.SCH)ファイル +// ヘッダー情報 +// アドレス 説明 +// 00000 - 00003 ファイルタイプ "SCH" +// 00004 - 00008 ビットモード "?BIT" +// 00009 - 00013 バージョンナンバー "Ver-????\n" +// 00014 - 00017 ヘッダーサイズ +// 00018 - 0001B ハード名 "SFC" or "CGB" or "GB" +// 0001C - 0001C BG/OBJフラグ(AGBの時) +// 0001D - 0001D Color Pallette Number +// 0001D - 000FF 予約 +// 00100 - 001FF Color Path struct CgxHeader { char file_type[4]; char bit_mode[5]; @@ -46,10 +48,17 @@ struct CgxHeader { 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); +absl::Status LoadScr(std::string_view filename, uint8_t input_value, + std::vector& map_data); + +absl::Status LoadCgx(uint8_t bpp, std::string_view filename, + std::vector& cgx_data, + std::vector& cgx_loaded, + std::vector& cgx_header); + +absl::Status DrawScrWithCgx(uint8_t bpp, std::vector& map_bitmap_data, + std::vector& map_data, + std::vector& cgx_loaded); std::vector DecodeColFile(const std::string& filename); @@ -59,11 +68,6 @@ absl::Status DecodeObjFile( 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 diff --git a/src/app/gfx/snes_tile.cc b/src/app/gfx/snes_tile.cc index 2c408cc7..f053607a 100644 --- a/src/app/gfx/snes_tile.cc +++ b/src/app/gfx/snes_tile.cc @@ -180,20 +180,22 @@ Bytes SnesTo8bppSheet(Bytes sheet, int bpp) { Bytes BPP8SNESToIndexed(Bytes data, uint64_t bpp) { // 3BPP - //[r0, bp1], [r0, bp2], [r1, bp1], [r1, bp2], [r2, bp1], [r2, bp2], [r3, bp1], - //[r3, bp2] [r4, bp1], [r4, bp2], [r5, bp1], [r5, bp2], [r6, bp1], [r6, bp2], - //[r7, bp1], [r7, bp2] [r0, bp3], [r0, bp4], [r1, bp3], [r1, bp4], [r2, bp3], - //[r2, bp4], [r3, bp3], [r3, bp4] [r4, bp3], [r4, bp4], [r5, bp3], [r5, bp4], - //[r6, bp3], [r6, bp4], [r7, bp3], [r7, bp4] [r0, bp5], [r0, bp6], [r1, bp5], - //[r1, bp6], [r2, bp5], [r2, bp6], [r3, bp5], [r3, bp6] [r4, bp5], [r4, bp6], - //[r5, bp5], [r5, bp6], [r6, bp5], [r6, bp6], [r7, bp5], [r7, bp6] [r0, bp7], - //[r0, bp8], [r1, bp7], [r1, bp8], [r2, bp7], [r2, bp8], [r3, bp7], [r3, bp8] - //[r4, bp7], [r4, bp8], [r5, bp7], [r5, bp8], [r6, bp7], [r6, bp8], [r7, bp7], - //[r7, bp8] + // [r0,bp1],[r0,bp2],[r1,bp1],[r1,bp2],[r2,bp1],[r2,bp2],[r3,bp1],[r3,bp2] + // [r4,bp1],[r4,bp2],[r5,bp1],[r5,bp2],[r6,bp1],[r6,bp2],[r7,bp1],[r7,bp2] + // [r0,bp3],[r0,bp4],[r1,bp3],[r1,bp4],[r2,bp3],[r2,bp4],[r3,bp3],[r3,bp4] + // [r4,bp3],[r4,bp4],[r5,bp3],[r5,bp4],[r6,bp3],[r6,bp4],[r7,bp3],[r7,bp4] + // [r0,bp5],[r0,bp6],[r1,bp5],[r1,bp6],[r2,bp5],[r2,bp6],[r3,bp5],[r3,bp6] + // [r4,bp5],[r4,bp6],[r5,bp5],[r5,bp6],[r6,bp5],[r6,bp6],[r7,bp5],[r7,bp6] + // [r0,bp7],[r0,bp8],[r1,bp7],[r1,bp8],[r2,bp7],[r2,bp8],[r3,bp7],[r3,bp8] + // [r4,bp7],[r4,bp8],[r5,bp7],[r5,bp8],[r6,bp7],[r6,bp8],[r7,bp7],[r7,bp8] // 16 tiles = 1024 bytes auto buffer = Bytes(data.size()); - auto bitmap_data = Bytes(0x80 * 0x800); + std::vector> bitmap_data; + bitmap_data.resize(0x80); + for (auto& each : bitmap_data) { + each.reserve(0x800); + } int yy = 0; int xx = 0; int pos = 0; @@ -249,7 +251,8 @@ Bytes BPP8SNESToIndexed(Bytes data, uint64_t bpp) { b |= 0x80; } } - bitmap_data[((x + xx) * sheet_width) + y + (yy * 8)] = b; + // bitmap_data[((x + xx) * sheet_width) + y + (yy * 8)] = b; + bitmap_data[x + xx][y + (yy * 8)] = b; } } pos++; @@ -267,7 +270,8 @@ Bytes BPP8SNESToIndexed(Bytes data, uint64_t bpp) { for (int y = 0; y < (data.size() / 64); y++) { for (int x = 0; x < sheet_width; x++) { // 128 assumption if (n < data.size()) { - buffer[n] = bitmap_data[(x * sheet_width) + y]; + // buffer[n] = bitmap_data[(x * sheet_width) + y]; + buffer[n] = bitmap_data[x][y]; n++; } }