implemented zarbys decompression and conversion code to get a graphics sheet on the screen finally
This commit is contained in:
@@ -115,15 +115,7 @@ uint32_t ROM::GetRomPosition(int direct_addr, uint snes_addr) const {
|
||||
return filePos;
|
||||
}
|
||||
|
||||
uchar* ROM::LoadGraphicsSheet(int offset) {
|
||||
auto tilesheet_position = Core::Constants::gfx_1_pointer +
|
||||
(offset * Core::Constants::UncompressedSheetSize);
|
||||
auto data = Decompress(tilesheet_position);
|
||||
return SNES3bppTo8bppSheet((uchar*)data);
|
||||
}
|
||||
|
||||
// char *buffer = new char[0x800] AKA sheet_buffer_in 3bpp
|
||||
uchar *ROM::SNES3bppTo8bppSheet(uchar *sheet_buffer_in) // 128x32
|
||||
uchar *ROM::SNES3bppTo8bppSheet(uchar *buffer_in, int sheet_id) // 128x32
|
||||
{
|
||||
// 8bpp sheet out
|
||||
const uchar bitmask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
||||
@@ -132,6 +124,11 @@ uchar *ROM::SNES3bppTo8bppSheet(uchar *sheet_buffer_in) // 128x32
|
||||
int yy = 0;
|
||||
int pos = 0;
|
||||
int ypos = 0;
|
||||
|
||||
if (sheet_id != 0) {
|
||||
yy = sheet_id;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 64; i++) // for each tiles //16 per lines
|
||||
{
|
||||
for (int y = 0; y < 8; y++) // for each lines
|
||||
@@ -139,12 +136,12 @@ uchar *ROM::SNES3bppTo8bppSheet(uchar *sheet_buffer_in) // 128x32
|
||||
//[0] + [1] + [16]
|
||||
for (int x = 0; x < 8; x++) {
|
||||
unsigned char b1 = (unsigned char)((
|
||||
sheet_buffer_in[(y * 2) + (24 * pos)] & (bitmask[x])));
|
||||
buffer_in[(y * 2) + (24 * pos)] & (bitmask[x])));
|
||||
unsigned char b2 =
|
||||
(unsigned char)(sheet_buffer_in[((y * 2) + (24 * pos)) + 1] &
|
||||
(unsigned char)(buffer_in[((y * 2) + (24 * pos)) + 1] &
|
||||
(bitmask[x]));
|
||||
unsigned char b3 =
|
||||
(unsigned char)(sheet_buffer_in[(16 + y) + (24 * pos)] &
|
||||
(unsigned char)(buffer_in[(16 + y) + (24 * pos)] &
|
||||
(bitmask[x]));
|
||||
unsigned char b = 0;
|
||||
if (b1 != 0) {
|
||||
@@ -180,7 +177,7 @@ char *ROM::Decompress(int pos, bool reversed) {
|
||||
unsigned char cmd = 0;
|
||||
unsigned int length = 0;
|
||||
|
||||
unsigned char databyte = (unsigned char)current_rom_[pos];
|
||||
uchar databyte = current_rom_[pos];
|
||||
while (true) {
|
||||
databyte = (unsigned char)current_rom_[pos];
|
||||
if (databyte == 0xFF) // End of decompression
|
||||
@@ -246,6 +243,40 @@ char *ROM::Decompress(int pos, bool reversed) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
SDL_Surface* ROM::GetGraphicsSheet(int num_sheets) {
|
||||
int height = 32 * num_sheets;
|
||||
SDL_Surface *surface =
|
||||
SDL_CreateRGBSurfaceWithFormat(0, 128, height, 8, SDL_PIXELFORMAT_INDEX8);
|
||||
std::cout << "Drawing surface" << std::endl;
|
||||
uchar *sheet_buffer = nullptr;
|
||||
// int sheet_buffer_pos = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
surface->format->palette->colors[i].r = (unsigned char)(i * 31);
|
||||
surface->format->palette->colors[i].g = (unsigned char)(i * 31);
|
||||
surface->format->palette->colors[i].b = (unsigned char)(i * 31);
|
||||
}
|
||||
|
||||
unsigned int snesAddr = 0;
|
||||
unsigned int pcAddr = 0;
|
||||
for (int i = 0; i < num_sheets; i++) {
|
||||
snesAddr =
|
||||
(unsigned int)((((unsigned char)(current_rom_[0x4F80 + i]) <<
|
||||
16) |
|
||||
((unsigned char)(current_rom_[0x505F + i]) << 8)
|
||||
|
|
||||
((unsigned char)(current_rom_[0x513E]))));
|
||||
pcAddr = SnesToPc(snesAddr);
|
||||
std::cout << "Decompressing..." << std::endl;
|
||||
char *decomp = Decompress(pcAddr);
|
||||
std::cout << "Converting to 8bpp sheet..." << std::endl;
|
||||
sheet_buffer = SNES3bppTo8bppSheet((uchar *)decomp, i);
|
||||
std::cout << "Assigning pixel data..." << std::endl;
|
||||
}
|
||||
|
||||
surface->pixels = sheet_buffer;
|
||||
return surface;
|
||||
}
|
||||
|
||||
int AddressFromBytes(uchar addr1, uchar addr2, uchar addr3) {
|
||||
return (addr1 << 16) | (addr2 << 8) | addr3;
|
||||
}
|
||||
|
||||
@@ -35,11 +35,20 @@ class ROM {
|
||||
const uchar* getTitle() const { return title; }
|
||||
long int getSize() const { return size_; }
|
||||
char getVersion() const { return version_; }
|
||||
bool isLoaded() const { return loaded; }
|
||||
|
||||
uchar* LoadGraphicsSheet(int offset);
|
||||
uchar* SNES3bppTo8bppSheet(uchar *sheet_buffer_in);
|
||||
bool isLoaded() const { return loaded; }
|
||||
|
||||
|
||||
uchar* SNES3bppTo8bppSheet(uchar* buffer_in, int sheet_id = 0);
|
||||
char* Decompress(int pos, bool reversed = false);
|
||||
SDL_Surface* GetGraphicsSheet(int num_sheets);
|
||||
|
||||
unsigned int SnesToPc(unsigned int addr) {
|
||||
if (addr >= 0x808000) {
|
||||
addr -= 0x808000;
|
||||
}
|
||||
unsigned int temp = (addr & 0x7FFF) + ((addr / 2) & 0xFF8000);
|
||||
return (temp + 0x0);
|
||||
}
|
||||
|
||||
private:
|
||||
bool loaded = false;
|
||||
@@ -54,8 +63,7 @@ class ROM {
|
||||
enum rom_type type_ = LoROM;
|
||||
|
||||
std::shared_ptr<uchar> rom_ptr_;
|
||||
std::unordered_map<unsigned int, std::shared_ptr<uchar[2048]>>
|
||||
decompressed_sheets;
|
||||
std::vector<SDL_Surface> surfaces_;
|
||||
};
|
||||
|
||||
} // namespace Data
|
||||
|
||||
@@ -290,49 +290,77 @@ void Editor::DrawSurface() {
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawGraphicsSheet(int offset) {
|
||||
SDL_Surface *surface =
|
||||
SDL_CreateRGBSurfaceWithFormat(0, 128, 32, 8, SDL_PIXELFORMAT_INDEX8);
|
||||
std::cout << "Drawing surface" << std::endl;
|
||||
uchar *sheet_buffer = nullptr;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
surface->format->palette->colors[i].r = (unsigned char)(i * 31);
|
||||
surface->format->palette->colors[i].g = (unsigned char)(i * 31);
|
||||
surface->format->palette->colors[i].b = (unsigned char)(i * 31);
|
||||
}
|
||||
|
||||
unsigned int snesAddr = 0;
|
||||
unsigned int pcAddr = 0;
|
||||
snesAddr = (unsigned int)((
|
||||
((unsigned char)(rom_.GetRawData()[0x4F80 + offset]) << 16) |
|
||||
((unsigned char)(rom_.GetRawData()[0x505F + offset]) << 8) |
|
||||
((unsigned char)(rom_.GetRawData()[0x513E]))));
|
||||
pcAddr = rom_.SnesToPc(snesAddr);
|
||||
std::cout << "Decompressing..." << std::endl;
|
||||
char *decomp = rom_.Decompress(pcAddr);
|
||||
std::cout << "Converting to 8bpp sheet..." << std::endl;
|
||||
sheet_buffer = rom_.SNES3bppTo8bppSheet((uchar *)decomp);
|
||||
std::cout << "Assigning pixel data..." << std::endl;
|
||||
surface->pixels = sheet_buffer;
|
||||
std::cout << "Creating texture from surface..." << std::endl;
|
||||
sheet_texture = SDL_CreateTextureFromSurface(sdl_renderer_.get(), surface);
|
||||
if (sheet_texture == nullptr) {
|
||||
std::cout << "Error: " << SDL_GetError() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawProjectEditor() {
|
||||
if (ImGui::BeginTabItem("Project")) {
|
||||
if (ImGui::BeginTable("##projectTable", 2,
|
||||
ImGuiTableFlags_SizingStretchSame)) {
|
||||
ImGui::TableSetupColumn("##inputs");
|
||||
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable)) {
|
||||
ImGui::TableSetupColumn("##inputs", ImGuiTableColumnFlags_WidthStretch);
|
||||
ImGui::TableSetupColumn("##outputs");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Title: %s", rom_.getTitle());
|
||||
ImGui::Text("Version: %d", rom_.getVersion());
|
||||
ImGui::Text("ROM Size: %ld", rom_.getSize());
|
||||
ImGui::Separator();
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
static bool loaded_image = false;
|
||||
static int tilesheet_offset = 0;
|
||||
ImGui::InputInt("Tilesheet Offset", &tilesheet_offset);
|
||||
|
||||
ImGui::Text("Zarby Retrieval Code");
|
||||
BASIC_BUTTON("Retrieve Graphics") {
|
||||
if (rom_.isLoaded()) {
|
||||
DrawGraphicsSheet(tilesheet_offset);
|
||||
loaded_image = true;
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
ImGui::InputInt("Bits per Pixel", ¤t_set_.bits_per_pixel_);
|
||||
|
||||
yaze::Gui::InputHex("PC Tile Location", ¤t_set_.pc_tiles_location_);
|
||||
|
||||
yaze::Gui::InputHex("SNES Tile Location",
|
||||
¤t_set_.SNESTilesLocation);
|
||||
|
||||
ImGui::InputInt("Tile Preset Length", ¤t_set_.length_);
|
||||
|
||||
ImGui::InputInt("PC Palette Location",
|
||||
¤t_set_.pc_palette_location_);
|
||||
|
||||
yaze::Gui::InputHex("SNES Palette Location",
|
||||
¤t_set_.SNESPaletteLocation);
|
||||
|
||||
static bool loaded_image = false;
|
||||
static uchar* image_data = nullptr;
|
||||
ImGui::Text("Zarby Retrieval Code");
|
||||
BASIC_BUTTON("Retrieve Graphics") {
|
||||
if (rom_.isLoaded()) {
|
||||
if (!loaded_image) {
|
||||
image_data = rom_.LoadGraphicsSheet(current_set_.pc_tiles_location_);
|
||||
loaded_image = true;
|
||||
} else {
|
||||
// TODO: build the sdl surface from the tilesheet data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Skarsnik Retrieval Code");
|
||||
BASIC_BUTTON("ExtractTiles") {
|
||||
if (rom_.isLoaded()) {
|
||||
@@ -370,7 +398,8 @@ void Editor::DrawProjectEditor() {
|
||||
static bool opt_enable_context_menu = true;
|
||||
static bool opt_enable_grid = true;
|
||||
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 canvas_sz = ImGui::GetContentRegionAvail();
|
||||
// ImVec2 canvas_sz = ImGui::GetContentRegionAvail();
|
||||
ImVec2 canvas_sz = ImVec2(512 + 1, ImGui::GetContentRegionAvail().y);
|
||||
ImVec2 canvas_p1 =
|
||||
ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
|
||||
|
||||
@@ -414,7 +443,7 @@ void Editor::DrawProjectEditor() {
|
||||
// Draw grid + all lines in the canvas
|
||||
draw_list->PushClipRect(canvas_p0, canvas_p1, true);
|
||||
if (opt_enable_grid) {
|
||||
const float GRID_STEP = 64.0f;
|
||||
const float GRID_STEP = 32.0f;
|
||||
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x;
|
||||
x += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y),
|
||||
@@ -427,20 +456,10 @@ void Editor::DrawProjectEditor() {
|
||||
IM_COL32(200, 200, 200, 40));
|
||||
}
|
||||
|
||||
if (current_scene_.imagesCache.size() != 0) {
|
||||
for (const auto &[key, value] : current_scene_.imagesCache) {
|
||||
const float GRID_STEP = 8.0f;
|
||||
float x = fmodf(scrolling.x, GRID_STEP);
|
||||
float y = fmodf(scrolling.y, GRID_STEP);
|
||||
draw_list->AddImage((void *)(SDL_Surface *)value,
|
||||
ImVec2(canvas_p0.x + x, canvas_p0.y),
|
||||
ImVec2(canvas_p0.x + x, canvas_p1.y));
|
||||
x += GRID_STEP;
|
||||
if (x == 128) {
|
||||
x = 0;
|
||||
y += GRID_STEP;
|
||||
}
|
||||
}
|
||||
if (loaded_image) {
|
||||
draw_list->AddImage((void *)(SDL_Texture *)sheet_texture,
|
||||
ImVec2(canvas_p0.x + 2, canvas_p0.y + 2),
|
||||
ImVec2(canvas_p0.x + 512, canvas_p0.y + 128));
|
||||
}
|
||||
|
||||
draw_list->PopClipRect();
|
||||
|
||||
@@ -32,6 +32,9 @@ class Editor {
|
||||
void DrawHelpMenu() const;
|
||||
|
||||
void DrawSurface();
|
||||
|
||||
void DrawGraphicsSheet(int offset = 0);
|
||||
|
||||
void DrawProjectEditor();
|
||||
void DrawOverworldEditor();
|
||||
void DrawDungeonEditor();
|
||||
@@ -46,6 +49,7 @@ class Editor {
|
||||
std::vector<std::vector<tile8>> arranged_tiles_;
|
||||
std::unordered_map<unsigned int, std::shared_ptr<SDL_Texture>> texture_cache_;
|
||||
std::unordered_map<unsigned int, SDL_Texture *> imagesCache;
|
||||
SDL_Texture *sheet_texture = nullptr;
|
||||
std::shared_ptr<SDL_Renderer> sdl_renderer_;
|
||||
|
||||
Data::ROM rom_;
|
||||
@@ -53,7 +57,6 @@ class Editor {
|
||||
TextEditor::LanguageDefinition language_65816_;
|
||||
OverworldEditor overworld_editor_;
|
||||
|
||||
Graphics::Scene current_scene_;
|
||||
Graphics::SNESPalette current_palette_;
|
||||
Graphics::TilePreset current_set_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user