Importing a bunch of code from Skarsnik sneshacking repo
This commit is contained in:
@@ -27,11 +27,15 @@ void Editor::UpdateScreen() {
|
|||||||
overworld_texture = &overworld.owactualMapTexture;
|
overworld_texture = &overworld.owactualMapTexture;
|
||||||
doneLoaded = true;
|
doneLoaded = true;
|
||||||
}
|
}
|
||||||
ImGui::Image((void*)(intptr_t)overworld_texture, ImVec2(overworld.overworldMapBitmap->GetWidth(), overworld.overworldMapBitmap->GetHeight()));
|
// ImGui::Image((void*)(intptr_t)overworld_texture,
|
||||||
|
// ImVec2(overworld.overworldMapBitmap->GetWidth(),
|
||||||
|
// overworld.overworldMapBitmap->GetHeight()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginTabBar("##TabBar")) {
|
if (ImGui::BeginTabBar("##TabBar")) {
|
||||||
DrawOverworldEditor();
|
DrawOverworldEditor();
|
||||||
|
DrawDungeonEditor();
|
||||||
|
DrawROMInfo();
|
||||||
ImGui::EndTabBar();
|
ImGui::EndTabBar();
|
||||||
}
|
}
|
||||||
// ImGui::ShowDemoWindow();
|
// ImGui::ShowDemoWindow();
|
||||||
@@ -155,12 +159,8 @@ void Editor::DrawOverworldEditor() {
|
|||||||
|
|
||||||
ImGui::Checkbox("Enable grid", &opt_enable_grid);
|
ImGui::Checkbox("Enable grid", &opt_enable_grid);
|
||||||
|
|
||||||
ImVec2 canvas_p0 =
|
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos();
|
||||||
ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
|
ImVec2 canvas_sz = ImGui::GetContentRegionAvail();
|
||||||
ImVec2 canvas_sz =
|
|
||||||
ImGui::GetContentRegionAvail(); // Resize canvas to what's available
|
|
||||||
if (canvas_sz.x < 50.0f) canvas_sz.x = 50.0f;
|
|
||||||
if (canvas_sz.y < 50.0f) canvas_sz.y = 50.0f;
|
|
||||||
ImVec2 canvas_p1 =
|
ImVec2 canvas_p1 =
|
||||||
ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
|
ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
|
||||||
|
|
||||||
@@ -194,8 +194,6 @@ void Editor::DrawOverworldEditor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pan (we use a zero mouse threshold when there's no context menu)
|
// Pan (we use a zero mouse threshold when there's no context menu)
|
||||||
// You may decide to make that threshold dynamic based on whether the mouse
|
|
||||||
// is hovering something etc.
|
|
||||||
const float mouse_threshold_for_pan =
|
const float mouse_threshold_for_pan =
|
||||||
opt_enable_context_menu ? -1.0f : 0.0f;
|
opt_enable_context_menu ? -1.0f : 0.0f;
|
||||||
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right,
|
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right,
|
||||||
@@ -247,6 +245,23 @@ void Editor::DrawOverworldEditor() {
|
|||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void DrawDungeonEditor() {
|
||||||
|
if (ImGui::BeginTabItem("Dungeon")) {
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Editor::DrawROMInfo() {
|
||||||
|
if (ImGui::BeginTabItem("ROM Info")) {
|
||||||
|
if (isLoaded) {
|
||||||
|
ImGui::Text("Title: %s", rom.getTitle());
|
||||||
|
ImGui::Text("Version: %d", rom.getVersion());
|
||||||
|
ImGui::Text("ROM Size: %ld", rom.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndTabItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace View
|
} // namespace View
|
||||||
} // namespace Application
|
} // namespace Application
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ class Editor {
|
|||||||
void DrawEditMenu() const;
|
void DrawEditMenu() const;
|
||||||
|
|
||||||
void DrawOverworldEditor();
|
void DrawOverworldEditor();
|
||||||
|
void DrawDungeonEditor();
|
||||||
|
void DrawROMInfo();
|
||||||
|
|
||||||
bool isLoaded = false;
|
bool isLoaded = false;
|
||||||
bool doneLoaded = false;
|
bool doneLoaded = false;
|
||||||
|
|||||||
83
src/Application/Graphics/Palette.cc
Normal file
83
src/Application/Graphics/Palette.cc
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#include "Palette.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace Application {
|
||||||
|
namespace Graphics {
|
||||||
|
|
||||||
|
r_palette* palette_create(const unsigned int size, const unsigned int id)
|
||||||
|
{
|
||||||
|
r_palette *new_pal = (r_palette*) malloc(sizeof(r_palette));
|
||||||
|
new_pal->colors = (m_color*) malloc(sizeof(m_color) * size);
|
||||||
|
new_pal->id = id;
|
||||||
|
new_pal->size = size;
|
||||||
|
return new_pal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void palette_free(r_palette* tofree)
|
||||||
|
{
|
||||||
|
free(tofree->colors);
|
||||||
|
free(tofree);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
r_palette *palette_extract(const char* data, const unsigned int offset, const unsigned int palette_size)
|
||||||
|
{
|
||||||
|
r_palette* toret = palette_create(palette_size, 0);
|
||||||
|
unsigned colnum = 0;
|
||||||
|
for (int i = 0; i < palette_size * 2; i += 2)
|
||||||
|
{
|
||||||
|
unsigned short snes_color;
|
||||||
|
snes_color = ((uchar) data[offset + i + 1]) << 8;
|
||||||
|
snes_color = snes_color | ((uchar) data[offset + i]);
|
||||||
|
toret->colors[colnum] = convertcolor_snes_to_rgb(snes_color);
|
||||||
|
colnum++;
|
||||||
|
}
|
||||||
|
return toret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* palette_convert(const r_palette pal)
|
||||||
|
{
|
||||||
|
char* toret = (char*) malloc(pal.size * 2);
|
||||||
|
for (unsigned int i = 0; i < pal.size; i++)
|
||||||
|
{
|
||||||
|
unsigned short snes_data = convertcolor_rgb_to_snes(pal.colors[i]);
|
||||||
|
toret[i * 2] = snes_data & 0xFF;
|
||||||
|
toret[i * 2 + 1] = snes_data >> 8;
|
||||||
|
}
|
||||||
|
return toret;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_color convertcolor_snes_to_rgb(const unsigned short snes_color)
|
||||||
|
{
|
||||||
|
m_color toret;
|
||||||
|
|
||||||
|
toret.red = ((snes_color ) % 32) * 8;
|
||||||
|
toret.green = ((snes_color / 32) % 32) * 8;
|
||||||
|
toret.blue = ((snes_color / 1024) % 32) * 8;
|
||||||
|
|
||||||
|
toret.red = toret.red + toret.red / 32;
|
||||||
|
toret.green = toret.green + toret.green / 32;
|
||||||
|
toret.blue = toret.blue + toret.blue / 32;
|
||||||
|
return toret;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short convertcolor_rgb_to_snes(const m_color color)
|
||||||
|
{
|
||||||
|
return convertcolor_rgb_to_snes2(color.red, color.green, color.blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short convertcolor_rgb_to_snes2(const uchar red, const uchar green, const uchar blue)
|
||||||
|
{
|
||||||
|
uchar R = red / 8;
|
||||||
|
uchar G = green / 8;
|
||||||
|
uchar B = blue / 8;
|
||||||
|
|
||||||
|
return B * 1024 + G * 32 + R;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/Application/Graphics/Palette.h
Normal file
42
src/Application/Graphics/Palette.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#ifndef YAZE_APPLICATION_GRAPHICS_PALETTE_H
|
||||||
|
#define YAZE_APPLICATION_GRAPHICS_PALETTE_H
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace Application {
|
||||||
|
namespace Graphics {
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char red;
|
||||||
|
unsigned char green;
|
||||||
|
unsigned char blue;
|
||||||
|
} m_color;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int id;
|
||||||
|
unsigned int size;
|
||||||
|
m_color* colors;
|
||||||
|
} r_palette;
|
||||||
|
|
||||||
|
r_palette* palette_create(const unsigned int size, const unsigned int id);
|
||||||
|
void palette_free(r_palette* tofree);
|
||||||
|
|
||||||
|
r_palette* palette_extract(const char* data, const unsigned int offset,
|
||||||
|
const unsigned int palette_size);
|
||||||
|
|
||||||
|
char* palette_convert(const r_palette pal);
|
||||||
|
|
||||||
|
m_color convertcolor_snes_to_rgb(const unsigned short snes_color);
|
||||||
|
unsigned short convertcolor_rgb_to_snes(const m_color color);
|
||||||
|
unsigned short convertcolor_rgb_to_snes2(const uchar red, const uchar green,
|
||||||
|
const uchar blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Graphics
|
||||||
|
} // namespace Application
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APPLICATION_GRAPHICS_PALETTE_H
|
||||||
@@ -1,5 +1,12 @@
|
|||||||
#include "Tile.h"
|
#include "Tile.h"
|
||||||
|
|
||||||
|
#include <png.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace Application {
|
namespace Application {
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
@@ -21,6 +28,191 @@ ushort TileInfo::toShort() {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Data
|
char* hexString(const char* str, const unsigned int size) {
|
||||||
|
char* toret = (char*)malloc(size * 3 + 1);
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
sprintf(toret + i * 3, "%02X ", (unsigned char)str[i]);
|
||||||
|
}
|
||||||
|
toret[size * 3] = 0;
|
||||||
|
return toret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void export_tile_to_png(tile8 rawtile, const r_palette pal,
|
||||||
|
const char* filename) {
|
||||||
|
FILE* fp = fopen(filename, "wb");
|
||||||
|
png_structp png_ptr =
|
||||||
|
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||||
|
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||||
|
png_init_io(png_ptr, fp);
|
||||||
|
png_set_strip_alpha(png_ptr);
|
||||||
|
png_read_update_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
|
png_color* png_palette =
|
||||||
|
(png_color*)png_malloc(png_ptr, pal.size * sizeof(png_color));
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < pal.size; i++) {
|
||||||
|
png_palette[i].blue = pal.colors[i].blue;
|
||||||
|
png_palette[i].green = pal.colors[i].green;
|
||||||
|
png_palette[i].red = pal.colors[i].red;
|
||||||
|
}
|
||||||
|
png_set_IHDR(png_ptr, info_ptr, 8, 8, 8, PNG_COLOR_TYPE_PALETTE,
|
||||||
|
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
|
||||||
|
PNG_FILTER_TYPE_BASE);
|
||||||
|
png_set_PLTE(png_ptr, info_ptr, png_palette, pal.size);
|
||||||
|
|
||||||
|
png_write_info(png_ptr, info_ptr);
|
||||||
|
png_set_packing(png_ptr);
|
||||||
|
|
||||||
|
png_byte* row_pointers[8];
|
||||||
|
for (unsigned int i = 0; i < 8; i++) {
|
||||||
|
row_pointers[i] = (png_byte*)png_malloc(png_ptr, sizeof(png_byte));
|
||||||
|
memcpy(row_pointers[i], rawtile.data + i * 8, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
png_write_image(png_ptr, row_pointers);
|
||||||
|
|
||||||
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||||
|
|
||||||
|
png_free(png_ptr, png_palette);
|
||||||
|
png_free(png_ptr, row_pointers);
|
||||||
|
}
|
||||||
|
|
||||||
|
tile8 unpack_bpp1_tile(const char* data, const unsigned int offset) {
|
||||||
|
return (unpack_bpp_tile(data, offset, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
tile8 unpack_bpp2_tile(const char* data, const unsigned int offset) {
|
||||||
|
return (unpack_bpp_tile(data, offset, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
tile8 unpack_bpp3_tile(const char* data, const unsigned int offset) {
|
||||||
|
return (unpack_bpp_tile(data, offset, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
tile8 unpack_bpp4_tile(const char* data, const unsigned int offset) {
|
||||||
|
return (unpack_bpp_tile(data, offset, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
tile8 unpack_bpp8_tile(const char* data, const unsigned int offset) {
|
||||||
|
return (unpack_bpp_tile(data, offset, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
tile8 unpack_mode7_tile(const char* data, const unsigned int offset) {
|
||||||
|
tile8 tile;
|
||||||
|
memcpy(tile.data, data + offset, 64);
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile8 unpack_bpp_tile(const char* data, const unsigned int offset,
|
||||||
|
const unsigned bpp) {
|
||||||
|
tile8 tile;
|
||||||
|
assert(bpp >= 1 && bpp <= 8);
|
||||||
|
unsigned int bpp_pos[8]; // More for conveniance and readibility
|
||||||
|
for (int col = 0; col < 8; col++) {
|
||||||
|
for (int row = 0; row < 8; row++) {
|
||||||
|
if (bpp == 1) {
|
||||||
|
tile.data[col * 8 + row] = (data[offset + col] >> (7 - row)) & 0x01;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* SNES bpp format interlace each byte of the first 2 bitplanes.
|
||||||
|
* | byte 1 of first bitplane | byte 1 of the second bitplane | byte 2 of
|
||||||
|
* first bitplane | byte 2 of second bitplane | ..
|
||||||
|
*/
|
||||||
|
bpp_pos[0] = offset + col * 2;
|
||||||
|
bpp_pos[1] = offset + col * 2 + 1;
|
||||||
|
char mask = 1 << (7 - row);
|
||||||
|
tile.data[col * 8 + row] = (data[bpp_pos[0]] & mask) == mask;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[1]] & mask) == mask) << 1;
|
||||||
|
if (bpp == 3) {
|
||||||
|
// When we have 3 bitplanes, the bytes for the third bitplane are after
|
||||||
|
// the 16 bytes of the 2 bitplanes.
|
||||||
|
bpp_pos[2] = offset + 16 + col;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[2]] & mask) == mask) << 2;
|
||||||
|
}
|
||||||
|
if (bpp >= 4) {
|
||||||
|
// For 4 bitplanes, the 2 added bitplanes are interlaced like the first
|
||||||
|
// two.
|
||||||
|
bpp_pos[2] = offset + 16 + col * 2;
|
||||||
|
bpp_pos[3] = offset + 16 + col * 2 + 1;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[2]] & mask) == mask) << 2;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[3]] & mask) == mask) << 3;
|
||||||
|
}
|
||||||
|
if (bpp == 8) {
|
||||||
|
bpp_pos[4] = offset + 32 + col * 2;
|
||||||
|
bpp_pos[5] = offset + 32 + col * 2 + 1;
|
||||||
|
bpp_pos[6] = offset + 48 + col * 2;
|
||||||
|
bpp_pos[7] = offset + 48 + col * 2 + 1;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[4]] & mask) == mask) << 4;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[5]] & mask) == mask) << 5;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[6]] & mask) == mask) << 6;
|
||||||
|
tile.data[col * 8 + row] |= ((data[bpp_pos[7]] & mask) == mask) << 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tile;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte* pack_bpp1_tile(const tile8 tile) {
|
||||||
|
unsigned int p = 1;
|
||||||
|
return pack_bpp_tile(tile, 1, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte* pack_bpp2_tile(const tile8 tile) {
|
||||||
|
unsigned int p = 1;
|
||||||
|
return pack_bpp_tile(tile, 2, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte* pack_bpp3_tile(const tile8 tile) {
|
||||||
|
unsigned int p = 1;
|
||||||
|
return pack_bpp_tile(tile, 3, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte* pack_bpp4_tile(const tile8 tile) {
|
||||||
|
unsigned int p = 1;
|
||||||
|
return pack_bpp_tile(tile, 4, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte* pack_bpp8_tile(const tile8 tile) {
|
||||||
|
unsigned int p = 1;
|
||||||
|
return pack_bpp_tile(tile, 8, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte* pack_bpp_tile(tile8 tile, const unsigned int bpp, unsigned int* size) {
|
||||||
|
byte* output = (byte*)malloc(bpp * 8);
|
||||||
|
memset(output, 0, bpp * 8);
|
||||||
|
unsigned maxcolor = 2 << bpp;
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
|
for (unsigned int col = 0; col < 8; col++) {
|
||||||
|
for (unsigned int row = 0; row < 8; row++) {
|
||||||
|
byte color = tile.data[col * 8 + row];
|
||||||
|
if (color > maxcolor) return NULL;
|
||||||
|
|
||||||
|
if (bpp == 1) output[col] += (byte)((color & 1) << (7 - row));
|
||||||
|
if (bpp >= 2) {
|
||||||
|
output[col * 2] += (byte)((color & 1) << (7 - row));
|
||||||
|
output[col * 2 + 1] += (byte)(((color & 2) == 2) << (7 - row));
|
||||||
|
}
|
||||||
|
if (bpp == 3) output[16 + col] += (byte)(((color & 4) == 4) << (7 - row));
|
||||||
|
if (bpp >= 4) {
|
||||||
|
output[16 + col * 2] += (byte)(((color & 4) == 4) << (7 - row));
|
||||||
|
output[16 + col * 2 + 1] += (byte)(((color & 8) == 8) << (7 - row));
|
||||||
|
}
|
||||||
|
if (bpp == 8) {
|
||||||
|
output[32 + col * 2] += (byte)(((color & 16) == 16) << (7 - row));
|
||||||
|
output[32 + col * 2 + 1] += (byte)(((color & 32) == 32) << (7 - row));
|
||||||
|
output[48 + col * 2] += (byte)(((color & 64) == 64) << (7 - row));
|
||||||
|
output[48 + col * 2 + 1] += (byte)(((color & 128) == 128) << (7 - row));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*size = bpp * 8;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Graphics
|
||||||
} // namespace Application
|
} // namespace Application
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -3,13 +3,48 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Palette.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace Application {
|
namespace Application {
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
using byte = unsigned char;
|
using byte = unsigned char;
|
||||||
using ushort = unsigned short;
|
using ushort = unsigned short;
|
||||||
|
using uint = unsigned int;
|
||||||
|
|
||||||
|
// SkarAlttp project code
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int id;
|
||||||
|
char data[64];
|
||||||
|
unsigned int palette_id;
|
||||||
|
} tile8;
|
||||||
|
|
||||||
|
tile8 unpack_bpp8_tile(const char* data, const unsigned int offset);
|
||||||
|
tile8 unpack_bpp4_tile(const char* data, const unsigned int offset);
|
||||||
|
tile8 unpack_bpp3_tile(const char* data, const unsigned int offset);
|
||||||
|
tile8 unpack_bpp2_tile(const char* data, const unsigned int offset);
|
||||||
|
tile8 unpack_bpp1_tile(const char* data, const unsigned int offset);
|
||||||
|
|
||||||
|
tile8 unpack_bpp_tile(const char* data, const unsigned int offset,
|
||||||
|
const unsigned int bpp);
|
||||||
|
|
||||||
|
byte* pack_bpp1_tile(const tile8 tile);
|
||||||
|
byte* pack_bpp2_tile(const tile8 tile);
|
||||||
|
byte* pack_bpp3_tile(const tile8 tile);
|
||||||
|
byte* pack_bpp4_tile(const tile8 tile);
|
||||||
|
byte* pack_bpp8_tile(const tile8 tile);
|
||||||
|
|
||||||
|
byte* pack_bpp_tile(const tile8 tile, const unsigned int bpp,
|
||||||
|
unsigned int* size);
|
||||||
|
|
||||||
|
void export_tile_to_png(tile8 rawtile, const r_palette pal,
|
||||||
|
const char* filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// End SkarAlttp project code
|
||||||
class TileInfo {
|
class TileInfo {
|
||||||
public:
|
public:
|
||||||
ushort id_;
|
ushort id_;
|
||||||
@@ -84,7 +119,8 @@ class Tile16 {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace Data
|
|
||||||
|
} // namespace Graphics
|
||||||
} // namespace Application
|
} // namespace Application
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,270 @@
|
|||||||
#include "ROM.h"
|
#include "ROM.h"
|
||||||
|
|
||||||
|
#define ROMMAPPING_LOCATION_SNES_RESERVED -1
|
||||||
|
#define ROMMAPPING_LOCATION_SRAM -2
|
||||||
|
#define ROMMAPPING_LOCATION_WRAM -3
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace Application {
|
namespace Application {
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
using namespace Graphics;
|
using namespace Graphics;
|
||||||
|
|
||||||
|
char *rommapping_error_text;
|
||||||
|
/*
|
||||||
|
* LoRoM is quite easy
|
||||||
|
*/
|
||||||
|
int lorom_snes_to_pc(const unsigned int snes_addr, char** info)
|
||||||
|
{
|
||||||
|
unsigned char bank = snes_addr >> 16;
|
||||||
|
unsigned int offset = snes_addr & 0x00FFFF;
|
||||||
|
//printf("snes_addr: %X - Bank: %X - Offset: %X\n", snes_addr, bank, offset);
|
||||||
|
|
||||||
|
// 80-FD is a mirror to the start
|
||||||
|
if (bank >= 0x80 && bank <= 0xFD)
|
||||||
|
bank -= 0x80;
|
||||||
|
if (bank >= 0x00 && bank <= 0x3F && offset < 0x8000 && offset >= 0x2000)
|
||||||
|
{
|
||||||
|
*info = "SNES Reserved";
|
||||||
|
return ROMMAPPING_LOCATION_SNES_RESERVED;
|
||||||
|
}
|
||||||
|
if ((((bank >= 0x70 && bank <= 0x7D) || bank == 0xFE || bank == 0xFF) && offset < 0x8000))
|
||||||
|
{
|
||||||
|
*info = "SRAM";
|
||||||
|
return ROMMAPPING_LOCATION_SRAM;
|
||||||
|
}
|
||||||
|
if (bank == 0x7E || bank == 0x7F ||
|
||||||
|
(bank >= 0x00 && bank <= 0x3F && offset < 0x2000)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*info = "WRAM section";
|
||||||
|
return ROMMAPPING_LOCATION_WRAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bank >= 0x40 && bank <= 0x6F && offset < 0x8000)
|
||||||
|
return bank * 0x8000 + offset;
|
||||||
|
if (bank == 0xFE || bank == 0xFF) // this work as if 7E was regular bank
|
||||||
|
bank -= 0xFE - 0x7E;
|
||||||
|
return bank * 0x8000 + (offset - 0x8000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hirom_snes_to_pc(const unsigned int snes_addr, char **info)
|
||||||
|
{
|
||||||
|
unsigned char bank = snes_addr >> 16;
|
||||||
|
unsigned int offset = snes_addr & 0x00FFFF;
|
||||||
|
|
||||||
|
// 80-FD is a mirror to the start
|
||||||
|
if (bank >= 0x80 && bank <= 0xFD)
|
||||||
|
bank -= 0x80;
|
||||||
|
|
||||||
|
if ((bank >= 0x00 && bank <= 0x1F && offset < 0x8000 && offset >= 0x2000) ||
|
||||||
|
(bank >= 0x20 && bank <= 0x3F && offset < 0x6000 && offset >= 0x2000)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
*info = "SNES Reserved";
|
||||||
|
return ROMMAPPING_LOCATION_SNES_RESERVED;
|
||||||
|
}
|
||||||
|
if (bank >= 0x20 && bank <= 0x3F && offset >= 0x6000 && offset < 0x8000)
|
||||||
|
{
|
||||||
|
*info = "SRAM";
|
||||||
|
return ROMMAPPING_LOCATION_SRAM;
|
||||||
|
}
|
||||||
|
if ((bank == 0x7E || bank == 0x7F) ||
|
||||||
|
(bank >= 0x00 && bank <= 0x3F && offset < 0x2000))
|
||||||
|
{
|
||||||
|
*info = "WRAM Section";
|
||||||
|
return ROMMAPPING_LOCATION_WRAM;
|
||||||
|
}
|
||||||
|
/*#include <stdio.h>
|
||||||
|
printf("%02X:%04X\n", bank, offset);*/
|
||||||
|
if (bank >= 0xFE)
|
||||||
|
bank -= 0xFE - 0x3E;
|
||||||
|
if (bank >= 0x40 && bank <= 0x7D)
|
||||||
|
bank -= 0x40;
|
||||||
|
return (bank << 16) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hirom_pc_to_snes(const unsigned int pc_addr)
|
||||||
|
{
|
||||||
|
unsigned int bank = pc_addr >> 16;
|
||||||
|
unsigned int offset = pc_addr & 0x00FFFF;
|
||||||
|
|
||||||
|
//printf("%02X:%04X\n", bank, offset);
|
||||||
|
if (bank <= 0x3F && offset >= 0x8000)
|
||||||
|
return pc_addr;
|
||||||
|
if (bank <= 0x3D)
|
||||||
|
return pc_addr + 0x400000;
|
||||||
|
return pc_addr + 0xFE0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hirom_sram_snes_to_pc(const unsigned int snes_addr)
|
||||||
|
{
|
||||||
|
unsigned int bank = snes_addr >> 16;
|
||||||
|
unsigned int offset = snes_addr & 0x00FFFF;
|
||||||
|
|
||||||
|
if (bank >= 0x20 && bank <= 0x3F && offset >= 0x6000 && offset < 0x8000)
|
||||||
|
return (bank - 0x20) * 0x2000 + (offset - 0x6000);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int hirom_sram_pc_to_snes(const unsigned int pc_addr)
|
||||||
|
{
|
||||||
|
unsigned int chuck_nb = pc_addr / 0x2000;
|
||||||
|
unsigned int rest = pc_addr % 0x2000;
|
||||||
|
|
||||||
|
return ((0x20 + chuck_nb) << 16) + 0x6000 + rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lorom_pc_to_snes(const unsigned int pc_addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
unsigned int bank = pc_addr / 0x8000;
|
||||||
|
unsigned int offset = pc_addr % 0x8000 + 0x8000;
|
||||||
|
|
||||||
|
//printf("pc_addr: %X - Bank: %X - Offset: %X\n", pc_addr, bank, offset);
|
||||||
|
|
||||||
|
return (bank << 16) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lorom_sram_pc_to_snes(const unsigned int pc_addr)
|
||||||
|
{
|
||||||
|
int chuck_nb = pc_addr / 0x8000;
|
||||||
|
int rest = pc_addr % 0x8000;
|
||||||
|
|
||||||
|
if (chuck_nb <= 0xD)
|
||||||
|
return ((0x70 + chuck_nb) << 16) + rest;
|
||||||
|
if (chuck_nb == 0xE || chuck_nb == 0xF)
|
||||||
|
return ((0xF0 + chuck_nb) << 16) + rest;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lorom_sram_snes_to_pc(const unsigned int snes_addr)
|
||||||
|
{
|
||||||
|
unsigned char bank = snes_addr >> 16;
|
||||||
|
unsigned int offset = snes_addr & 0x00FFFF;
|
||||||
|
|
||||||
|
// F0-FD are mirror of 70-7D
|
||||||
|
if (bank >= 0xF0 && bank <= 0xFD)
|
||||||
|
bank -= 0x80;
|
||||||
|
if (bank >= 0x70 && bank <= 0x7D && offset < 0x8000)
|
||||||
|
return (bank - 0x70) * 0x8000 + offset;
|
||||||
|
if ((bank == 0xFE || bank == 0xFF) && offset < 0x8000)
|
||||||
|
return ((bank - 0xFE) + 0xE) * 0x8000 + offset;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rommapping_snes_to_pc(const unsigned int snes_addr, enum rom_type rom_type, bool header)
|
||||||
|
{
|
||||||
|
int pc_addr;
|
||||||
|
char *info;
|
||||||
|
switch (rom_type)
|
||||||
|
{
|
||||||
|
case LoROM:
|
||||||
|
pc_addr = lorom_snes_to_pc(snes_addr, &info);
|
||||||
|
break;
|
||||||
|
case HiROM:
|
||||||
|
pc_addr = hirom_snes_to_pc(snes_addr, &info);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pc_addr < 0) {
|
||||||
|
rommapping_error_text = (char *) malloc(strlen(info) + 1);
|
||||||
|
strcpy(rommapping_error_text, info);
|
||||||
|
return pc_addr;
|
||||||
|
}
|
||||||
|
if (header)
|
||||||
|
pc_addr += 0x200;
|
||||||
|
return pc_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rommapping_pc_to_snes(const unsigned int pc_addr, enum rom_type rom_type, bool header)
|
||||||
|
{
|
||||||
|
int snes_addr;
|
||||||
|
|
||||||
|
switch (rom_type)
|
||||||
|
{
|
||||||
|
case LoROM:
|
||||||
|
snes_addr = lorom_pc_to_snes(header ? pc_addr - 0x200 : pc_addr);
|
||||||
|
break;
|
||||||
|
case HiROM:
|
||||||
|
snes_addr = hirom_pc_to_snes(header ? pc_addr - 0x200 : pc_addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return snes_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int rommapping_sram_snes_to_pc(const unsigned int snes_addr, enum rom_type rom_type, bool header)
|
||||||
|
{
|
||||||
|
int pc_addr;
|
||||||
|
switch (rom_type)
|
||||||
|
{
|
||||||
|
case LoROM:
|
||||||
|
pc_addr = lorom_sram_snes_to_pc(snes_addr);
|
||||||
|
break;
|
||||||
|
case HiROM:
|
||||||
|
pc_addr = hirom_sram_snes_to_pc(snes_addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (header)
|
||||||
|
pc_addr += 0x200;
|
||||||
|
return pc_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rommapping_sram_pc_to_snes(const unsigned int pc_addr, enum rom_type rom_type, bool header)
|
||||||
|
{
|
||||||
|
int snes_addr;
|
||||||
|
|
||||||
|
switch (rom_type)
|
||||||
|
{
|
||||||
|
case LoROM:
|
||||||
|
snes_addr = lorom_sram_pc_to_snes(header ? pc_addr - 0x200 : pc_addr);
|
||||||
|
break;
|
||||||
|
case HiROM:
|
||||||
|
snes_addr = hirom_sram_pc_to_snes(header ? pc_addr - 0x200 : pc_addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return snes_addr;
|
||||||
|
}
|
||||||
|
|
||||||
void ROM::LoadFromFile(const std::string& path) {
|
void ROM::LoadFromFile(const std::string& path) {
|
||||||
|
|
||||||
FILE * file = fopen(path.c_str(), "r+");
|
FILE * file = fopen(path.c_str(), "r+");
|
||||||
if (file == NULL) return;
|
if (file == NULL) return;
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
long int size = ftell(file);
|
size = ftell(file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
std::cout << "size: " << size << std::endl;
|
|
||||||
|
|
||||||
// Reading data to array of unsigned chars
|
// Reading data to array of unsigned chars
|
||||||
file = fopen(path.c_str(), "r+");
|
file = fopen(path.c_str(), "r+");
|
||||||
current_rom_ = (unsigned char *) malloc(size);
|
current_rom_ = (unsigned char *) malloc(size);
|
||||||
int bytes_read = fread(current_rom_, sizeof(unsigned char), size, file);
|
int bytes_read = fread(current_rom_, sizeof(unsigned char), size, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
memcpy(title, current_rom_, 21);
|
||||||
|
type = LoROM;
|
||||||
|
fastrom = (current_rom_[21] & 0b00110000) == 0b00110000;
|
||||||
|
if (current_rom_[21] & 1)
|
||||||
|
type = HiROM;
|
||||||
|
if ((current_rom_[21] & 0b00000111) == 0b00000111)
|
||||||
|
type = ExHiROM;
|
||||||
|
|
||||||
|
sram_size = 0x400 << current_rom_[24];
|
||||||
|
creator_id = (current_rom_[26] << 8) | current_rom_[25];
|
||||||
|
version = current_rom_[27];
|
||||||
|
checksum_comp = (current_rom_[29] << 8) | current_rom_[28];
|
||||||
|
checksum = (current_rom_[31] << 8) | current_rom_[30];
|
||||||
|
make_sense = false;
|
||||||
|
if ((checksum ^ checksum_comp) == 0xFFFF)
|
||||||
|
make_sense = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ROM::SnesToPc(int addr) {
|
int ROM::SnesToPc(int addr) {
|
||||||
@@ -76,14 +319,6 @@ int ROM::ReadLong(int addr) {
|
|||||||
current_rom_[addr]);
|
current_rom_[addr]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Tile16 ROM::ReadTile16(int addr) {
|
|
||||||
ushort t1 = (ushort)((current_rom_[addr + 1] << 8) + current_rom_[addr]);
|
|
||||||
ushort t2 = (ushort)((current_rom_[addr + 3] << 8) + current_rom_[addr + 2]);
|
|
||||||
ushort t3 = (ushort)((current_rom_[addr + 5] << 8) + current_rom_[addr + 4]);
|
|
||||||
ushort t4 = (ushort)((current_rom_[addr + 7] << 8) + current_rom_[addr + 6]);
|
|
||||||
return Tile16((unsigned long)((t1 << 48) + (t2 << 32) + (t3 << 16) + t4));
|
|
||||||
}
|
|
||||||
|
|
||||||
ushort ROM::ReadShort(int addr) {
|
ushort ROM::ReadShort(int addr) {
|
||||||
return (ushort)((current_rom_[addr + 1] << 8) + current_rom_[addr]);
|
return (ushort)((current_rom_[addr + 1] << 8) + current_rom_[addr]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <bits/postypes.h>
|
#include <bits/postypes.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -20,6 +21,33 @@ namespace Utils {
|
|||||||
using byte = unsigned char;
|
using byte = unsigned char;
|
||||||
using ushort = unsigned short;
|
using ushort = unsigned short;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
enum rom_type { LoROM, HiROM, ExLoROM, ExHiROM };
|
||||||
|
|
||||||
|
extern char* rommapping_error_text;
|
||||||
|
|
||||||
|
int rommapping_snes_to_pc(const unsigned int snes_addr, enum rom_type rom_type,
|
||||||
|
bool header);
|
||||||
|
int rommapping_pc_to_snes(const unsigned int pc_addr, enum rom_type rom_type,
|
||||||
|
bool header);
|
||||||
|
|
||||||
|
int rommapping_sram_snes_to_pc(const unsigned int snes_addr,
|
||||||
|
enum rom_type rom_type, bool header);
|
||||||
|
int rommapping_sram_pc_to_snes(const unsigned int pc_addr,
|
||||||
|
enum rom_type rom_type, bool header);
|
||||||
|
|
||||||
|
int lorom_snes_to_pc(const unsigned int snes_addr, char** info);
|
||||||
|
int lorom_sram_snes_to_pc(const unsigned int snes_addr);
|
||||||
|
int lorom_pc_to_snes(const unsigned int pc_addr);
|
||||||
|
int lorom_sram_pc_to_snes(const unsigned int pc_addr);
|
||||||
|
|
||||||
|
int hirom_snes_to_pc(const unsigned int snes_addr, char** info);
|
||||||
|
int hirom_sram_snes_to_pc(const unsigned int snes_addr);
|
||||||
|
int hirom_pc_to_snes(const unsigned int pc_addr);
|
||||||
|
int hirom_sram_pc_to_snes(const unsigned int pc_addr);
|
||||||
|
}
|
||||||
|
|
||||||
class ROM {
|
class ROM {
|
||||||
public:
|
public:
|
||||||
int SnesToPc(int addr);
|
int SnesToPc(int addr);
|
||||||
@@ -31,18 +59,32 @@ class ROM {
|
|||||||
short ReadReverseShort(int addr);
|
short ReadReverseShort(int addr);
|
||||||
ushort ReadByte(int addr);
|
ushort ReadByte(int addr);
|
||||||
short ReadRealShort(int addr);
|
short ReadRealShort(int addr);
|
||||||
Graphics::Tile16 ReadTile16(int addr);
|
|
||||||
void WriteShort(int addr, int value);
|
void WriteShort(int addr, int value);
|
||||||
int ReadLong(int addr);
|
int ReadLong(int addr);
|
||||||
void WriteLong(int addr, int value);
|
void WriteLong(int addr, int value);
|
||||||
void LoadFromFile(const std::string& path);
|
void LoadFromFile(const std::string& path);
|
||||||
inline byte * GetRawData() { return current_rom_; }
|
inline byte* GetRawData() { return current_rom_; }
|
||||||
|
|
||||||
|
const unsigned char* getTitle() const { return title; }
|
||||||
|
unsigned int getSize() const { return size; }
|
||||||
|
char getVersion() const { return version; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<char> original_rom_;
|
std::vector<char> original_rom_;
|
||||||
std::vector<char> working_rom_;
|
std::vector<char> working_rom_;
|
||||||
|
|
||||||
byte* current_rom_;
|
byte* current_rom_;
|
||||||
|
|
||||||
|
enum rom_type type;
|
||||||
|
bool fastrom;
|
||||||
|
bool make_sense;
|
||||||
|
unsigned char title[21];
|
||||||
|
long int size;
|
||||||
|
unsigned int sram_size;
|
||||||
|
uint16_t creator_id;
|
||||||
|
unsigned char version;
|
||||||
|
unsigned char checksum_comp;
|
||||||
|
unsigned char checksum;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|||||||
Reference in New Issue
Block a user