Managed to get loading the ROM and graphics decompression/overworld tile building stuff to compile, now it's just a matter of translating that data into the Bitmap to display properly.
This commit is contained in:
@@ -9,6 +9,20 @@ namespace Data {
|
||||
using namespace Core;
|
||||
using namespace Graphics;
|
||||
|
||||
Overworld::~Overworld() {
|
||||
for (int i = 0; i < tiles32.size(); i++) {
|
||||
free(allmapsTilesLW[i]);
|
||||
free(allmapsTilesDW[i]);
|
||||
free(allmapsTilesSP[i]);
|
||||
}
|
||||
free(allmapsTilesLW);
|
||||
free(allmapsTilesDW);
|
||||
free(allmapsTilesSP);
|
||||
|
||||
delete overworldMapPointer;
|
||||
delete owactualMapPointer;
|
||||
}
|
||||
|
||||
static TileInfo GetTilesInfo(ushort tile) {
|
||||
// vhopppcc cccccccc
|
||||
ushort o = 0;
|
||||
@@ -24,12 +38,13 @@ static TileInfo GetTilesInfo(ushort tile) {
|
||||
return TileInfo(tid, p, v, h, o);
|
||||
}
|
||||
|
||||
Overworld::Overworld(Utils::ROM rom) : rom_(rom) {
|
||||
void Overworld::Load(Utils::ROM rom) {
|
||||
rom_ = rom;
|
||||
for (int i = 0; i < 0x2B; i++) {
|
||||
tileLeftEntrance[i] = (ushort)rom_.ReadShort(
|
||||
Constants::overworldEntranceAllowedTilesLeft + (i * 2));
|
||||
tileRightEntrance[i] = (ushort)rom_.ReadShort(
|
||||
Constants::overworldEntranceAllowedTilesRight + (i * 2));
|
||||
tileLeftEntrance.push_back(
|
||||
rom_.ReadShort(Constants::overworldEntranceAllowedTilesLeft + (i * 2)));
|
||||
tileRightEntrance.push_back(rom_.ReadShort(
|
||||
Constants::overworldEntranceAllowedTilesRight + (i * 2)));
|
||||
}
|
||||
|
||||
AssembleMap32Tiles();
|
||||
@@ -38,21 +53,20 @@ Overworld::Overworld(Utils::ROM rom) : rom_(rom) {
|
||||
|
||||
// Map Initialization :
|
||||
for (int i = 0; i < 160; i++) {
|
||||
allmaps.push_back(OverworldMap(rom_, (byte)i));
|
||||
allmaps.push_back(OverworldMap(rom_, tiles16, (byte)i));
|
||||
}
|
||||
FetchLargeMaps();
|
||||
LoadOverworldMap();
|
||||
|
||||
auto size = tiles16.size();
|
||||
for (int i = 0; i < 160; i++) {
|
||||
allmaps[i].BuildMap(mapParent, size, gameState);
|
||||
allmaps[i].BuildMap(mapParent, size, gameState, allmapsTilesLW,
|
||||
allmapsTilesDW, allmapsTilesSP);
|
||||
}
|
||||
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
void Overworld::Load(Utils::ROM rom) {}
|
||||
|
||||
ushort Overworld::GenerateTile32(int i, int k, int dimension) {
|
||||
return (ushort)(rom_.GetRawData()[map32address[dimension] + k + (i)] +
|
||||
(((rom_.GetRawData()[map32address[dimension] + (i) +
|
||||
@@ -73,6 +87,18 @@ void Overworld::AssembleMap32Tiles() {
|
||||
tiles32.push_back(Tile32(tl, tr, bl, br));
|
||||
}
|
||||
}
|
||||
|
||||
allmapsTilesLW = (ushort**)malloc(tiles32.size() * sizeof(ushort*));
|
||||
for (int i = 0; i < tiles32.size(); i++)
|
||||
allmapsTilesLW[i] = (ushort*)malloc(tiles32.size() * sizeof(ushort));
|
||||
|
||||
allmapsTilesDW = (ushort**)malloc(tiles32.size() * sizeof(ushort*));
|
||||
for (int i = 0; i < tiles32.size(); i++)
|
||||
allmapsTilesDW[i] = (ushort*)malloc(tiles32.size() * sizeof(ushort));
|
||||
|
||||
allmapsTilesSP = (ushort**)malloc(tiles32.size() * sizeof(ushort*));
|
||||
for (int i = 0; i < tiles32.size(); i++)
|
||||
allmapsTilesSP[i] = (ushort*)malloc(tiles32.size() * sizeof(ushort));
|
||||
}
|
||||
|
||||
void Overworld::AssembleMap16Tiles() {
|
||||
@@ -94,11 +120,9 @@ void Overworld::AssembleMap16Tiles() {
|
||||
void Overworld::DecompressAllMapTiles() {
|
||||
int lowest = 0x0FFFFF;
|
||||
int highest = 0x0F8000;
|
||||
// int npos = 0;
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int c = 0;
|
||||
// int furthestPtr = 0;
|
||||
for (int i = 0; i < 160; i++) {
|
||||
int p1 = (rom_.GetRawData()[(Constants::compressedAllMap32PointersHigh) +
|
||||
2 + (int)(3 * i)]
|
||||
@@ -155,9 +179,6 @@ void Overworld::DecompressAllMapTiles() {
|
||||
|
||||
int tpos = tidD;
|
||||
if (tpos < tiles32.size()) {
|
||||
// map16tiles[npos] = new Tile32(tiles32[tpos].tile0,
|
||||
// tiles32[tpos].tile1, tiles32[tpos].tile2, tiles32[tpos].tile3);
|
||||
|
||||
if (i < 64) {
|
||||
allmapsTilesLW[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] =
|
||||
tiles32[tpos].tile0_;
|
||||
@@ -268,13 +289,13 @@ void Overworld::FetchLargeMaps() {
|
||||
}
|
||||
|
||||
void Overworld::LoadOverworldMap() {
|
||||
// GFX.overworldMapBitmap = new Bitmap(
|
||||
// 128, 128, 128, PixelFormat.Format8bppIndexed, GFX.overworldMapPointer);
|
||||
// GFX.owactualMapBitmap = new Bitmap(
|
||||
// 512, 512, 512, PixelFormat.Format8bppIndexed, GFX.owactualMapPointer);
|
||||
overworldMapBitmap = new Bitmap(128, 128, overworldMapPointer);
|
||||
overworldMapBitmap->Create(&overworldMapTexture);
|
||||
owactualMapBitmap = new Bitmap(512, 512, owactualMapPointer);
|
||||
owactualMapBitmap->Create(&owactualMapTexture);
|
||||
|
||||
// Mode 7
|
||||
byte* ptr = (byte*)overworldMapPointer.get();
|
||||
byte* ptr = overworldMapPointer;
|
||||
|
||||
int pos = 0;
|
||||
for (int sy = 0; sy < 16; sy++) {
|
||||
|
||||
@@ -15,25 +15,33 @@ namespace yaze {
|
||||
namespace Application {
|
||||
namespace Data {
|
||||
|
||||
using ushort = ushort;
|
||||
using ushort = unsigned short;
|
||||
using byte = unsigned char;
|
||||
|
||||
class Overworld {
|
||||
public:
|
||||
Overworld() = default;
|
||||
Overworld(Utils::ROM rom);
|
||||
~Overworld();
|
||||
|
||||
void Load(Utils::ROM rom);
|
||||
|
||||
byte* overworldMapPointer = new byte[0x40000];
|
||||
Graphics::Bitmap* overworldMapBitmap;
|
||||
GLuint overworldMapTexture;
|
||||
|
||||
byte* owactualMapPointer = new byte[0x40000];
|
||||
Graphics::Bitmap* owactualMapBitmap;
|
||||
GLuint owactualMapTexture;
|
||||
|
||||
private:
|
||||
Utils::ROM rom_;
|
||||
Utils::ALTTPCompression alttp_compressor_;
|
||||
int gameState = 1;
|
||||
byte mapParent[160];
|
||||
|
||||
unsigned short **allmapsTilesLW;
|
||||
std::vector<std::vector<ushort>> allmapsTilesDW; // 64 maps * (32*32 tiles)
|
||||
std::vector<std::vector<ushort>> allmapsTilesSP; // 32 maps * (32*32 tiles)
|
||||
ushort **allmapsTilesLW; // 64 maps * (32*32 tiles)
|
||||
ushort **allmapsTilesDW; // 64 maps * (32*32 tiles)
|
||||
ushort **allmapsTilesSP; // 32 maps * (32*32 tiles)
|
||||
|
||||
std::vector<Graphics::Tile16> tiles16;
|
||||
std::vector<Graphics::Tile32> tiles32;
|
||||
@@ -50,11 +58,6 @@ class Overworld {
|
||||
Core::Constants::map32TilesTL, Core::Constants::map32TilesTR,
|
||||
Core::Constants::map32TilesBL, Core::Constants::map32TilesBR};
|
||||
|
||||
std::unique_ptr<int> overworldMapPointer;
|
||||
Graphics::Bitmap overworldMapBitmap;
|
||||
|
||||
std::unique_ptr<int> owactualMapPointer;
|
||||
Graphics::Bitmap owactualMapBitmap;
|
||||
|
||||
enum Dimension {
|
||||
map32TilesTL = 0,
|
||||
|
||||
@@ -7,12 +7,10 @@ namespace Data {
|
||||
using namespace Core;
|
||||
using namespace Graphics;
|
||||
|
||||
OverworldMap::OverworldMap(Utils::ROM rom, byte index)
|
||||
: rom_(rom), index(index), parent(index) {
|
||||
// gfxBitmap = new Bitmap(512, 512, 512, PixelFormat.Format8bppIndexed,
|
||||
// gfxPtr); messageID = (short)ROM.ReadShort(Constants::overworldMessages +
|
||||
// (parent * 2));
|
||||
|
||||
OverworldMap::OverworldMap(Utils::ROM rom,
|
||||
const std::vector<Graphics::Tile16> tiles16,
|
||||
byte index)
|
||||
: rom_(rom), index(index), tiles16_(tiles16), parent(index) {
|
||||
if (index != 0x80) {
|
||||
if (index <= 150) {
|
||||
if (rom_.GetRawData()[Constants::overworldMapSize + (index & 0x3F)] !=
|
||||
@@ -105,15 +103,16 @@ OverworldMap::OverworldMap(Utils::ROM rom, byte index)
|
||||
}
|
||||
}
|
||||
|
||||
void OverworldMap::BuildMap(byte* mapParent, int count, int gameState) {
|
||||
void OverworldMap::BuildMap(byte* mapParent, int count, int gameState,
|
||||
ushort** allmapsTilesLW, ushort** allmapsTilesDW,
|
||||
ushort** allmapsTilesSP) {
|
||||
tilesUsed = new ushort*[32];
|
||||
for (int i = 0; i < 32; i++) tilesUsed[i] = new ushort;
|
||||
|
||||
if (largeMap) {
|
||||
this->parent = mapParent[index];
|
||||
|
||||
if (parent != index) {
|
||||
// sprgfx[0] = rom_.GetRawData()[Constants::overworldSpriteset + parent];
|
||||
// sprgfx[1] = rom_.GetRawData()[Constants::overworldSpriteset + parent +
|
||||
// 64]; sprgfx[2] = rom_.GetRawData()[Constants::overworldSpriteset +
|
||||
// parent + 128];
|
||||
if (!firstLoad) {
|
||||
gfx = rom_.GetRawData()[Constants::mapGfx + parent];
|
||||
palette = rom_.GetRawData()[Constants::overworldMapPalette + parent];
|
||||
@@ -124,21 +123,19 @@ void OverworldMap::BuildMap(byte* mapParent, int count, int gameState) {
|
||||
|
||||
BuildTileset(gameState);
|
||||
BuildTiles16Gfx(count); // build on GFX.mapgfx16Ptr
|
||||
//LoadPalette();
|
||||
// LoadPalette();
|
||||
|
||||
int world = 0;
|
||||
|
||||
// fix !!
|
||||
/* if (index < 64) {
|
||||
tilesUsed = ow_.allmapsTilesLW;
|
||||
}
|
||||
else if (index < 128 && index >= 64) {
|
||||
tilesUsed = ow_.allmapsTilesDW.data();
|
||||
if (index < 64) {
|
||||
tilesUsed = allmapsTilesLW;
|
||||
} else if (index < 128 && index >= 64) {
|
||||
tilesUsed = allmapsTilesDW;
|
||||
world = 1;
|
||||
} else {
|
||||
tilesUsed = ow_.allmapsTilesSP.data();
|
||||
tilesUsed = allmapsTilesSP;
|
||||
world = 2;
|
||||
} */
|
||||
}
|
||||
|
||||
int superY = ((index - (world * 64)) / 8);
|
||||
int superX = index - (world * 64) - (superY * 8);
|
||||
@@ -146,15 +143,13 @@ void OverworldMap::BuildMap(byte* mapParent, int count, int gameState) {
|
||||
for (int y = 0; y < 32; y++) {
|
||||
for (int x = 0; x < 32; x++) {
|
||||
CopyTile8bpp16((x * 16), (y * 16),
|
||||
tilesUsed[x + (superX * 32)][y + (superY * 32)],
|
||||
gfxPtr.get(), // fix
|
||||
mapblockset16.get()); // fix
|
||||
tilesUsed[x + (superX * 32)][y + (superY * 32)], gfxPtr,
|
||||
mapblockset16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OverworldMap::CopyTile8bpp16(int x, int y, int tile,
|
||||
int* destbmpPtr,
|
||||
void OverworldMap::CopyTile8bpp16(int x, int y, int tile, int* destbmpPtr,
|
||||
int* sourcebmpPtr) {
|
||||
int sourceY = (tile / 8);
|
||||
int sourceX = (tile) - ((sourceY)*8);
|
||||
@@ -163,7 +158,7 @@ void OverworldMap::CopyTile8bpp16(int x, int y, int tile,
|
||||
byte* sourcePtr = (byte*)sourcebmpPtr;
|
||||
|
||||
int destPtrPos = (x + (y * 512));
|
||||
byte* destPtr = (byte*) destbmpPtr;
|
||||
byte* destPtr = (byte*)destbmpPtr;
|
||||
|
||||
for (int ystrip = 0; ystrip < 16; ystrip++) {
|
||||
for (int xstrip = 0; xstrip < 16; xstrip++) {
|
||||
@@ -174,22 +169,17 @@ void OverworldMap::CopyTile8bpp16(int x, int y, int tile,
|
||||
}
|
||||
|
||||
void OverworldMap::CopyTile8bpp16From8(int xP, int yP, int tileID,
|
||||
int* destbmpPtr,
|
||||
int* sourcebmpPtr) {
|
||||
auto gfx16Data = (byte*) destbmpPtr;
|
||||
int* destbmpPtr, int* sourcebmpPtr) {
|
||||
auto gfx16Data = (byte*)destbmpPtr;
|
||||
|
||||
auto gfx8Data = new byte[(128 * 512) / 2];
|
||||
// (byte*)
|
||||
// GFX.currentOWgfx16Ptr.ToPointer()
|
||||
auto gfx8Data = currentOWgfx16Ptr;
|
||||
|
||||
int offsets[] = {0, 8, 4096, 4104};
|
||||
|
||||
//auto tiles = ow_.tiles16[tileID];
|
||||
auto tiles = nullptr;
|
||||
auto tiles = tiles16_[tileID];
|
||||
|
||||
for (auto tile = 0; tile < 4; tile++) {
|
||||
//TileInfo info = tiles.tiles_info[tile];
|
||||
TileInfo info;
|
||||
TileInfo info = tiles.tiles_info[tile];
|
||||
int offset = offsets[tile];
|
||||
|
||||
for (auto y = 0; y < 8; y++) {
|
||||
@@ -201,11 +191,9 @@ void OverworldMap::CopyTile8bpp16From8(int xP, int yP, int tileID,
|
||||
}
|
||||
|
||||
void OverworldMap::BuildTiles16Gfx(int count) {
|
||||
auto gfx16Data = new byte[1024];
|
||||
// (byte*)GFX.mapblockset16.get(); //(byte*)allgfx8Ptr.ToPointer();
|
||||
auto gfx8Data = new byte [1024];
|
||||
// (byte*)
|
||||
// GFX.currentOWgfx16Ptr.get(); //(byte*)allgfx16Ptr.ToPointer();
|
||||
byte* gfx16Data = (byte*)mapblockset16;
|
||||
byte* gfx8Data = currentOWgfx16Ptr;
|
||||
|
||||
int offsets[] = {0, 8, 1024, 1032};
|
||||
auto yy = 0;
|
||||
auto xx = 0;
|
||||
@@ -213,12 +201,11 @@ void OverworldMap::BuildTiles16Gfx(int count) {
|
||||
for (auto i = 0; i < count; i++) // number of tiles16 3748?
|
||||
{
|
||||
// 8x8 tile draw
|
||||
// gfx8 = 4bpp so everyting is /2
|
||||
// auto tiles = ow_.tiles16[i];
|
||||
// gfx8 = 4bpp so everyting is /2F
|
||||
auto tiles = tiles16_[i];
|
||||
|
||||
for (auto tile = 0; tile < 4; tile++) {
|
||||
//TileInfo info = ow_.tiles16[i].tiles_info[tile];
|
||||
TileInfo info;
|
||||
TileInfo info = tiles16_[i].tiles_info[tile];
|
||||
int offset = offsets[tile];
|
||||
|
||||
for (auto y = 0; y < 8; y++) {
|
||||
@@ -286,7 +273,7 @@ void OverworldMap::CopyTileToMap(int x, int y, int xx, int yy, int offset,
|
||||
gfx16Pointer[index + r] = (byte)(((pixel >> 4) & 0x0F) + tile.palette_ * 16);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
void OverworldMap::LoadPalette() {
|
||||
int previousPalId = 0;
|
||||
int previousSprPalId = 0;
|
||||
@@ -615,12 +602,12 @@ void OverworldMap::BuildTileset(int gameState) {
|
||||
staticgfx[7] = 91;
|
||||
}
|
||||
|
||||
byte* currentmapgfx8Data = new byte [1024];
|
||||
// (byte*)GFX.currentOWgfx16Ptr.ToPointer(); // loaded gfx for the current
|
||||
// // map (empty at this point)
|
||||
byte* allgfxData = new byte [1024];
|
||||
// (byte*)GFX.allgfx16Ptr
|
||||
// .ToPointer(); // all gfx of the game pack of 2048 bytes (4bpp)
|
||||
byte* currentmapgfx8Data = new byte[(128 * 512) / 2];
|
||||
// (byte*)GFX.currentOWgfx16Ptr.ToPointer(); // loaded gfx for the current
|
||||
// // map (empty at this point)
|
||||
byte* allgfxData = new byte[(128 * 7136) / 2];
|
||||
// (byte*)GFX.allgfx16Ptr
|
||||
// .ToPointer(); // all gfx of the game pack of 2048 bytes (4bpp)
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
for (int j = 0; j < 2048; j++) {
|
||||
|
||||
@@ -26,19 +26,22 @@ class OverworldMap {
|
||||
byte sprpalette[3];
|
||||
byte musics[4];
|
||||
|
||||
// 512 * 512
|
||||
std::unique_ptr<int> gfxPtr;
|
||||
std::unique_ptr<int> mapblockset16;
|
||||
// Bitmap gfxBitmap; // Needs to be removed
|
||||
int* gfxPtr = new int[512 * 512];
|
||||
int* mapblockset16 = new int[1048576];
|
||||
Graphics::Bitmap mapblockset16Bitmap;
|
||||
Graphics::Bitmap gfxBitmap;
|
||||
|
||||
byte staticgfx[16]; // Need to be used to display map and not pre render it!
|
||||
byte* staticgfx = new byte[16]; // Need to be used to display map and not pre render it!
|
||||
ushort** tilesUsed;
|
||||
|
||||
bool needRefresh = false;
|
||||
Utils::ROM rom_;
|
||||
|
||||
OverworldMap(Utils::ROM rom, byte index);
|
||||
void BuildMap(byte* mapParent, int count, int gameState);
|
||||
byte *currentOWgfx16Ptr = new byte[(128 * 512) / 2];
|
||||
std::vector<Graphics::Tile16> tiles16_;
|
||||
|
||||
OverworldMap(Utils::ROM rom, const std::vector<Graphics::Tile16> tiles16, byte index);
|
||||
void BuildMap(byte* mapParent, int count, int gameState, ushort** allmapsTilesLW, ushort** allmapsTilesDW, ushort** allmapsTilesSP);
|
||||
void CopyTile8bpp16(int x, int y, int tile, int* destbmpPtr,
|
||||
int* sourcebmpPtr);
|
||||
void CopyTile8bpp16From8(int xP, int yP, int tileID, int* destbmpPtr,
|
||||
@@ -50,16 +53,15 @@ class OverworldMap {
|
||||
|
||||
void CopyTile(int x, int y, int xx, int yy, int offset,
|
||||
Graphics::TileInfo tile, byte* gfx16Pointer, byte* gfx8Pointer);
|
||||
|
||||
void CopyTileToMap(int x, int y, int xx, int yy, int offset,
|
||||
Graphics::TileInfo tile, byte* gfx16Pointer,
|
||||
byte* gfx8Pointer);
|
||||
|
||||
/* void LoadPalette();
|
||||
void LoadPalette();
|
||||
|
||||
void SetColorsPalette(int index, ImVec4 main, ImVec4 animated, ImVec4 aux1,
|
||||
ImVec4 aux2, ImVec4 hud, ImVec4 bgrcolor, ImVec4 spr,
|
||||
ImVec4 spr2); */
|
||||
ImVec4 spr2);
|
||||
|
||||
void BuildTileset(int gameState);
|
||||
};
|
||||
|
||||
@@ -21,12 +21,20 @@ void Editor::UpdateScreen() {
|
||||
}
|
||||
DrawYazeMenu();
|
||||
|
||||
if (isLoaded) {
|
||||
if (!doneLoaded) {
|
||||
overworld.Load(rom);
|
||||
overworld_texture = &overworld.owactualMapTexture;
|
||||
doneLoaded = true;
|
||||
}
|
||||
ImGui::Image((void*)(intptr_t)overworld_texture, ImVec2(overworld.overworldMapBitmap->GetWidth(), overworld.overworldMapBitmap->GetHeight()));
|
||||
}
|
||||
|
||||
if (ImGui::BeginTabBar("##TabBar")) {
|
||||
DrawOverworldEditor();
|
||||
ImGui::EndTabBar();
|
||||
}
|
||||
|
||||
ImGui::ShowDemoWindow();
|
||||
// ImGui::ShowDemoWindow();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -52,6 +60,7 @@ void Editor::DrawYazeMenu() {
|
||||
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||
rom.LoadFromFile(filePathName);
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
// close
|
||||
@@ -145,10 +154,6 @@ void Editor::DrawOverworldEditor() {
|
||||
static bool adding_line = false;
|
||||
|
||||
ImGui::Checkbox("Enable grid", &opt_enable_grid);
|
||||
ImGui::Checkbox("Enable context menu", &opt_enable_context_menu);
|
||||
ImGui::Text(
|
||||
"Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click "
|
||||
"for context menu.");
|
||||
|
||||
ImVec2 canvas_p0 =
|
||||
ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates!
|
||||
|
||||
@@ -27,6 +27,9 @@ class Editor {
|
||||
|
||||
void DrawOverworldEditor();
|
||||
|
||||
bool isLoaded = false;
|
||||
bool doneLoaded = false;
|
||||
GLuint *overworld_texture;
|
||||
Data::Overworld overworld;
|
||||
Utils::ROM rom;
|
||||
};
|
||||
|
||||
@@ -4,7 +4,53 @@ namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
Bitmap::Bitmap() {}
|
||||
Bitmap::Bitmap(int width, int height, byte* data)
|
||||
: width_(width), height_(height), pixel_data_(data) {}
|
||||
|
||||
void Bitmap::Create(GLuint* out_texture) {
|
||||
// // Read the pixel data from the ROM
|
||||
// SDL_RWops * src = SDL_RWFromMem(pixel_data_, 0);
|
||||
// // Create the surface from that RW stream
|
||||
// SDL_Surface* surface = SDL_LoadBMP_RW(src, SDL_FALSE);
|
||||
// GLenum mode = 0;
|
||||
// Uint8 bpp = surface->format->BytesPerPixel;
|
||||
// Uint32 rm = surface->format->Rmask;
|
||||
// if (bpp == 3 && rm == 0x000000ff) mode = GL_RGB;
|
||||
// if (bpp == 3 && rm == 0x00ff0000) mode = GL_BGR;
|
||||
// if (bpp == 4 && rm == 0x000000ff) mode = GL_RGBA;
|
||||
// if (bpp == 4 && rm == 0xff000000) mode = GL_BGRA;
|
||||
|
||||
// GLsizei width = surface->w;
|
||||
// GLsizei height = surface->h;
|
||||
// GLenum format = mode;
|
||||
// GLvoid* pixels = surface->pixels;
|
||||
|
||||
// Create a OpenGL texture identifier
|
||||
GLuint image_texture;
|
||||
glGenTextures(1, &image_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, image_texture);
|
||||
|
||||
// Setup filtering parameters for display
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
// Upload pixels into texture
|
||||
#if defined(GL_UNPACK_ROW_LENGTH) && !defined(__EMSCRIPTEN__)
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width_, height_, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, pixel_data_);
|
||||
|
||||
*out_texture = image_texture;
|
||||
}
|
||||
|
||||
int Bitmap::GetWidth() {
|
||||
return width_;
|
||||
}
|
||||
int Bitmap::GetHeight() {
|
||||
return height_;
|
||||
}
|
||||
|
||||
// Simple helper function to load an image into a OpenGL texture with common
|
||||
// settings
|
||||
|
||||
@@ -1,20 +1,37 @@
|
||||
#ifndef YAZE_APPLICATION_UTILS_BITMAP_H
|
||||
#define YAZE_APPLICATION_UTILS_BITMAP_H
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include <SDL2/SDL.h>
|
||||
// #include <SDL2/SDL_opengl.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "GL/glew.h"
|
||||
#include "Utils/ROM.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
using byte = unsigned char;
|
||||
|
||||
class Bitmap {
|
||||
public:
|
||||
Bitmap();
|
||||
Bitmap()=default;
|
||||
Bitmap(int width, int height, byte* data);
|
||||
|
||||
void Create(GLuint* out_texture);
|
||||
int GetWidth();
|
||||
int GetHeight();
|
||||
|
||||
bool LoadBitmapFromROM(unsigned char* texture_data, GLuint* out_texture,
|
||||
int* out_width, int* out_height);
|
||||
|
||||
private:
|
||||
int width_;
|
||||
int height_;
|
||||
byte* pixel_data_;
|
||||
SDL_PixelFormat pixel_format_;
|
||||
};
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
|
||||
@@ -33,27 +33,27 @@ namespace yaze {
|
||||
namespace Application {
|
||||
namespace Utils {
|
||||
|
||||
char* ALTTPCompression::DecompressGfx(const char* c_data,
|
||||
unsigned char* ALTTPCompression::DecompressGfx(const unsigned char* c_data,
|
||||
const unsigned int start,
|
||||
unsigned int max_length,
|
||||
unsigned int* uncompressed_data_size,
|
||||
unsigned int* compressed_length) {
|
||||
char* toret = std_nintendo_.Decompress(c_data, start, max_length,
|
||||
unsigned char* toret = std_nintendo_.Decompress(c_data, start, max_length,
|
||||
uncompressed_data_size,
|
||||
compressed_length, D_NINTENDO_C_MODE2);
|
||||
return toret;
|
||||
}
|
||||
|
||||
char* ALTTPCompression::DecompressOverworld(
|
||||
const char* c_data, const unsigned int start, unsigned int max_length,
|
||||
unsigned char* ALTTPCompression::DecompressOverworld(
|
||||
const unsigned char* c_data, const unsigned int start, unsigned int max_length,
|
||||
unsigned int* uncompressed_data_size, unsigned int* compressed_length) {
|
||||
char* toret = std_nintendo_.Decompress(c_data, start, max_length,
|
||||
unsigned char* toret = std_nintendo_.Decompress(c_data, start, max_length,
|
||||
uncompressed_data_size,
|
||||
compressed_length, D_NINTENDO_C_MODE1);
|
||||
return toret;
|
||||
}
|
||||
|
||||
char* ALTTPCompression::CompressGfx(const char* u_data,
|
||||
unsigned char* ALTTPCompression::CompressGfx(const unsigned char* u_data,
|
||||
const unsigned int start,
|
||||
const unsigned int length,
|
||||
unsigned int* compressed_size) {
|
||||
@@ -61,7 +61,7 @@ char* ALTTPCompression::CompressGfx(const char* u_data,
|
||||
D_NINTENDO_C_MODE2);
|
||||
}
|
||||
|
||||
char* ALTTPCompression::CompressOverworld(const char* u_data,
|
||||
unsigned char* ALTTPCompression::CompressOverworld(const unsigned char* u_data,
|
||||
const unsigned int start,
|
||||
const unsigned int length,
|
||||
unsigned int* compressed_size) {
|
||||
@@ -76,13 +76,13 @@ char* ALTTPCompression::CompressOverworld(const char* u_data,
|
||||
* Then you have a new header byte and so on, until you hit a header with the
|
||||
* value FF
|
||||
*/
|
||||
char* StdNintendoCompression::Decompress(const char* c_data,
|
||||
unsigned char* StdNintendoCompression::Decompress(const unsigned char* c_data,
|
||||
const unsigned int start,
|
||||
unsigned int max_length,
|
||||
unsigned int* uncompressed_data_size,
|
||||
unsigned int* compressed_length,
|
||||
char mode) {
|
||||
char* u_data;
|
||||
unsigned char* u_data;
|
||||
unsigned char header;
|
||||
unsigned int c_data_pos;
|
||||
unsigned int u_data_pos;
|
||||
@@ -93,7 +93,7 @@ char* StdNintendoCompression::Decompress(const char* c_data,
|
||||
if (max_length != 0) max_offset = start + max_length;
|
||||
header = c_data[start];
|
||||
u_data =
|
||||
(char*)malloc(INITIAL_ALLOC_SIZE); // No way to know the final size, we
|
||||
(unsigned char*)malloc(INITIAL_ALLOC_SIZE); // No way to know the final size, we
|
||||
// will probably realloc if needed
|
||||
allocated_memory = INITIAL_ALLOC_SIZE;
|
||||
u_data_pos = 0;
|
||||
@@ -120,9 +120,9 @@ char* StdNintendoCompression::Decompress(const char* c_data,
|
||||
|
||||
// length value starts at 0, 0 is 1
|
||||
length++;
|
||||
printf("%d[%d]", command, length);
|
||||
printf("header %02X - Command : %d , length : %d\n", header, command,
|
||||
length);
|
||||
// printf("%d[%d]", command, length);
|
||||
// printf("header %02X - Command : %d , length : %d\n", header, command,
|
||||
// length);
|
||||
if (c_data_pos >= max_offset && max_offset != 0) {
|
||||
decompression_error_ =
|
||||
"Compression string exceed the max_length specified";
|
||||
@@ -133,7 +133,7 @@ char* StdNintendoCompression::Decompress(const char* c_data,
|
||||
{
|
||||
printf("Memory get reallocated by %d was %d\n", INITIAL_ALLOC_SIZE,
|
||||
allocated_memory);
|
||||
u_data = (char*)realloc(u_data, allocated_memory + INITIAL_ALLOC_SIZE);
|
||||
u_data = (unsigned char*)realloc(u_data, allocated_memory + INITIAL_ALLOC_SIZE);
|
||||
if (u_data == NULL) {
|
||||
decompression_error_ = "Can't realloc memory";
|
||||
return NULL;
|
||||
@@ -198,7 +198,7 @@ char* StdNintendoCompression::Decompress(const char* c_data,
|
||||
printf("Memory get reallocated by a copy, %d was %d\n",
|
||||
INITIAL_ALLOC_SIZE, allocated_memory);
|
||||
u_data =
|
||||
(char*)realloc(u_data, allocated_memory + INITIAL_ALLOC_SIZE);
|
||||
(unsigned char*)realloc(u_data, allocated_memory + INITIAL_ALLOC_SIZE);
|
||||
if (u_data == NULL) {
|
||||
decompression_error_ = "Can't realloc memory";
|
||||
return NULL;
|
||||
@@ -306,7 +306,7 @@ StdNintendoCompression::merge_copy(CompressionComponent* start) {
|
||||
}
|
||||
|
||||
unsigned int StdNintendoCompression::create_compression_string(
|
||||
CompressionComponent* start, char* output, char mode) {
|
||||
CompressionComponent* start, unsigned char* output, char mode) {
|
||||
unsigned int pos = 0;
|
||||
CompressionComponent* piece = start;
|
||||
|
||||
@@ -386,13 +386,13 @@ unsigned int StdNintendoCompression::create_compression_string(
|
||||
|
||||
// TODO TEST compressed data border for each cmd
|
||||
|
||||
char* StdNintendoCompression::Compress(const char* u_data,
|
||||
unsigned char* StdNintendoCompression::Compress(const unsigned char* u_data,
|
||||
const unsigned int start,
|
||||
const unsigned int length,
|
||||
unsigned int* compressed_size,
|
||||
char mode) {
|
||||
// we will realloc later
|
||||
char* compressed_data = (char*)malloc(
|
||||
unsigned char* compressed_data = (unsigned char*)malloc(
|
||||
length +
|
||||
10); // Worse case should be a copy of the string with extended header
|
||||
CompressionComponent* compressed_chain = CreateComponent(1, 1, "aaa", 2);
|
||||
@@ -561,12 +561,12 @@ char* StdNintendoCompression::Compress(const char* u_data,
|
||||
if (std_nintendo_compression_sanity_check &&
|
||||
compressed_chain_start->next != NULL) {
|
||||
// We don't call merge copy so we need more space
|
||||
char* tmp = (char*)malloc(length * 2);
|
||||
unsigned char* tmp = (unsigned char*) malloc(length * 2);
|
||||
*compressed_size =
|
||||
create_compression_string(compressed_chain_start->next, tmp, mode);
|
||||
unsigned int p;
|
||||
unsigned int k;
|
||||
char* uncomp = Decompress(tmp, 0, 0, &p, &k, mode);
|
||||
unsigned char* uncomp = Decompress(tmp, 0, 0, &p, &k, mode);
|
||||
if (uncomp == NULL) {
|
||||
fprintf(stderr, "%s\n", decompression_error_);
|
||||
return NULL;
|
||||
|
||||
@@ -26,7 +26,7 @@ class StdNintendoCompression {
|
||||
* of the define for it: D_NINTENDO_C_MODEX... 1 is is SMW, 2 is zelda3 gfx
|
||||
*/
|
||||
|
||||
char* Decompress(const char* c_data, const unsigned int start,
|
||||
unsigned char* Decompress(const unsigned char* c_data, const unsigned int start,
|
||||
unsigned int max_length,
|
||||
unsigned int* uncompressed_data_size,
|
||||
unsigned int* compressed_length, char mode);
|
||||
@@ -41,7 +41,7 @@ class StdNintendoCompression {
|
||||
* mode is the variation of the compression.
|
||||
*/
|
||||
|
||||
char* Compress(const char* u_data, const unsigned int start,
|
||||
unsigned char* Compress(const unsigned char* u_data, const unsigned int start,
|
||||
const unsigned int length, unsigned int* compressed_size,
|
||||
char mode);
|
||||
|
||||
@@ -69,7 +69,7 @@ class StdNintendoCompression {
|
||||
void DestroyChain(CompressionComponent* piece);
|
||||
CompressionComponent* merge_copy(CompressionComponent* start);
|
||||
unsigned int create_compression_string(CompressionComponent* start,
|
||||
char* output, char mode);
|
||||
unsigned char* output, char mode);
|
||||
};
|
||||
|
||||
class ALTTPCompression {
|
||||
@@ -86,16 +86,16 @@ class ALTTPCompression {
|
||||
* compressed_length is the length of the compressed data, meaning the number
|
||||
* of bytes read in c_data.
|
||||
*/
|
||||
char* Decompress(const char* c_data, const unsigned int start,
|
||||
unsigned char* Decompress(const unsigned char* c_data, const unsigned int start,
|
||||
unsigned int max_length,
|
||||
unsigned int* uncompressed_data_size,
|
||||
unsigned int* compressed_length, char mode);
|
||||
|
||||
char* DecompressGfx(const char* c_data, const unsigned int start,
|
||||
unsigned char* DecompressGfx(const unsigned char* c_data, const unsigned int start,
|
||||
unsigned int max_length,
|
||||
unsigned int* uncompressed_data_size,
|
||||
unsigned int* compressed_length);
|
||||
char* DecompressOverworld(const char* c_data, const unsigned int start,
|
||||
unsigned char* DecompressOverworld(const unsigned char* c_data, const unsigned int start,
|
||||
unsigned int max_length,
|
||||
unsigned int* uncompressed_data_size,
|
||||
unsigned int* compressed_length);
|
||||
@@ -109,13 +109,13 @@ class ALTTPCompression {
|
||||
* length is the length of u_data to compress
|
||||
* compressed_size is the resulting size of the compressed string.
|
||||
*/
|
||||
char* Compress(const char* u_data, const unsigned int start,
|
||||
unsigned char* Compress(const unsigned char* u_data, const unsigned int start,
|
||||
const unsigned int length, unsigned int* compressed_size,
|
||||
char mode);
|
||||
|
||||
char* CompressGfx(const char* u_data, const unsigned int start,
|
||||
unsigned char* CompressGfx(const unsigned char* u_data, const unsigned int start,
|
||||
const unsigned int length, unsigned int* compressed_size);
|
||||
char* CompressOverworld(const char* u_data, const unsigned int start,
|
||||
unsigned char* CompressOverworld(const unsigned char* u_data, const unsigned int start,
|
||||
const unsigned int length,
|
||||
unsigned int* compressed_size);
|
||||
|
||||
|
||||
@@ -7,23 +7,21 @@ namespace Utils {
|
||||
using namespace Graphics;
|
||||
|
||||
void ROM::LoadFromFile(const std::string& path) {
|
||||
std::cout << "filename: " << path << std::endl;
|
||||
std::ifstream stream(path, std::ios::in | std::ios::binary);
|
||||
|
||||
if (!stream.good()) {
|
||||
std::cout << "failure reading file" << std::endl;
|
||||
return;
|
||||
}
|
||||
FILE * file = fopen(path.c_str(), "r+");
|
||||
if (file == NULL) return;
|
||||
fseek(file, 0, SEEK_END);
|
||||
long int size = ftell(file);
|
||||
fclose(file);
|
||||
|
||||
std::vector<char> contents((std::istreambuf_iterator<char>(stream)),
|
||||
std::istreambuf_iterator<char>());
|
||||
std::cout << "size: " << size << std::endl;
|
||||
|
||||
for (auto i : contents) {
|
||||
int value = i;
|
||||
std::cout << "working_rom_: " << value << std::endl;
|
||||
}
|
||||
// Reading data to array of unsigned chars
|
||||
file = fopen(path.c_str(), "r+");
|
||||
current_rom_ = (unsigned char *) malloc(size);
|
||||
int bytes_read = fread(current_rom_, sizeof(unsigned char), size, file);
|
||||
fclose(file);
|
||||
|
||||
std::cout << "file size: " << contents.size() << std::endl;
|
||||
}
|
||||
|
||||
int ROM::SnesToPc(int addr) {
|
||||
@@ -60,44 +58,44 @@ short ROM::AddressFromBytes(byte addr1, byte addr2) {
|
||||
return (short)((addr1 << 8) | (addr2));
|
||||
}
|
||||
|
||||
void ROM::Write(int addr, byte value) { working_rom_[addr] = value; }
|
||||
void ROM::Write(int addr, byte value) { current_rom_[addr] = value; }
|
||||
|
||||
void ROM::WriteLong(int addr, int value) {
|
||||
working_rom_[addr] = (byte)(value & 0xFF);
|
||||
working_rom_[addr + 1] = (byte)((value >> 8) & 0xFF);
|
||||
working_rom_[addr + 2] = (byte)((value >> 16) & 0xFF);
|
||||
current_rom_[addr] = (byte)(value & 0xFF);
|
||||
current_rom_[addr + 1] = (byte)((value >> 8) & 0xFF);
|
||||
current_rom_[addr + 2] = (byte)((value >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
void ROM::WriteShort(int addr, int value) {
|
||||
working_rom_[addr] = (byte)(value & 0xFF);
|
||||
working_rom_[addr + 1] = (byte)((value >> 8) & 0xFF);
|
||||
current_rom_[addr] = (byte)(value & 0xFF);
|
||||
current_rom_[addr + 1] = (byte)((value >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
int ROM::ReadLong(int addr) {
|
||||
return ((working_rom_[addr + 2] << 16) + (working_rom_[addr + 1] << 8) +
|
||||
working_rom_[addr]);
|
||||
return ((current_rom_[addr + 2] << 16) + (current_rom_[addr + 1] << 8) +
|
||||
current_rom_[addr]);
|
||||
}
|
||||
|
||||
Tile16 ROM::ReadTile16(int addr) {
|
||||
ushort t1 = (ushort)((working_rom_[addr + 1] << 8) + working_rom_[addr]);
|
||||
ushort t2 = (ushort)((working_rom_[addr + 3] << 8) + working_rom_[addr + 2]);
|
||||
ushort t3 = (ushort)((working_rom_[addr + 5] << 8) + working_rom_[addr + 4]);
|
||||
ushort t4 = (ushort)((working_rom_[addr + 7] << 8) + working_rom_[addr + 6]);
|
||||
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) {
|
||||
return (ushort)((working_rom_[addr + 1] << 8) + working_rom_[addr]);
|
||||
return (ushort)((current_rom_[addr + 1] << 8) + current_rom_[addr]);
|
||||
}
|
||||
|
||||
short ROM::ReadRealShort(int addr) {
|
||||
return (short)((working_rom_[addr + 1] << 8) + working_rom_[addr]);
|
||||
return (short)((current_rom_[addr + 1] << 8) + current_rom_[addr]);
|
||||
}
|
||||
|
||||
ushort ROM::ReadByte(int addr) { return (ushort)(working_rom_[addr]); }
|
||||
ushort ROM::ReadByte(int addr) { return (ushort)(current_rom_[addr]); }
|
||||
|
||||
short ROM::ReadReverseShort(int addr) {
|
||||
return (short)((working_rom_[addr] << 8) + working_rom_[addr + 1]);
|
||||
return (short)((current_rom_[addr] << 8) + current_rom_[addr + 1]);
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
@@ -36,11 +36,13 @@ class ROM {
|
||||
int ReadLong(int addr);
|
||||
void WriteLong(int addr, int value);
|
||||
void LoadFromFile(const std::string& path);
|
||||
inline const char* GetRawData() { return working_rom_.data(); }
|
||||
inline byte * GetRawData() { return current_rom_; }
|
||||
|
||||
private:
|
||||
std::vector<char> original_rom_;
|
||||
std::vector<char> working_rom_;
|
||||
|
||||
byte* current_rom_;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
Reference in New Issue
Block a user