Continuing the Graphics stuff and removed Events bc im not using it

This commit is contained in:
Justin Scofield
2022-06-12 12:42:35 -04:00
parent bbe95ef332
commit 9b905a48e4
17 changed files with 328 additions and 231 deletions

View File

@@ -16,6 +16,7 @@ void Controller::onEntry() noexcept(false) {
io.KeyMap[ImGuiKey_UpArrow] = SDL_GetScancodeFromKey(SDLK_UP); io.KeyMap[ImGuiKey_UpArrow] = SDL_GetScancodeFromKey(SDLK_UP);
io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN); io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN);
io.KeyMap[ImGuiKey_Tab] = SDL_GetScancodeFromKey(SDLK_TAB); io.KeyMap[ImGuiKey_Tab] = SDL_GetScancodeFromKey(SDLK_TAB);
io.KeyMap[ImGuiKey_LeftCtrl] = SDL_GetScancodeFromKey(SDLK_LCTRL);
active = true; active = true;
} }
@@ -26,51 +27,52 @@ void Controller::onInput() {
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
switch (event.type) { switch (event.type) {
case SDL_KEYDOWN: case SDL_KEYDOWN:
switch (event.key.keysym.sym) { switch (event.key.keysym.sym) {
case SDLK_UP: case SDLK_UP:
case SDLK_DOWN: case SDLK_DOWN:
case SDLK_RETURN: case SDLK_RETURN:
case SDLK_BACKSPACE: case SDLK_BACKSPACE:
case SDLK_TAB: case SDLK_TAB:
io.KeysDown[event.key.keysym.scancode] = (event.type == SDL_KEYDOWN); io.KeysDown[event.key.keysym.scancode] =
(event.type == SDL_KEYDOWN);
break;
default:
break;
}
break; break;
default:
break;
}
break;
case SDL_KEYUP: { case SDL_KEYUP: {
int key = event.key.keysym.scancode; int key = event.key.keysym.scancode;
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown)); IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
io.KeysDown[key] = (event.type == SDL_KEYDOWN); io.KeysDown[key] = (event.type == SDL_KEYDOWN);
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
break;
}
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_CLOSE:
active = false;
break; break;
case SDL_WINDOWEVENT_SIZE_CHANGED: }
io.DisplaySize.x = static_cast<float>(event.window.data1); case SDL_WINDOWEVENT:
io.DisplaySize.y = static_cast<float>(event.window.data2); switch (event.window.event) {
case SDL_WINDOWEVENT_CLOSE:
active = false;
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
io.DisplaySize.x = static_cast<float>(event.window.data1);
io.DisplaySize.y = static_cast<float>(event.window.data2);
break;
default:
break;
}
break;
case SDL_TEXTINPUT:
io.AddInputCharactersUTF8(event.text.text);
break;
case SDL_MOUSEWHEEL:
wheel = event.wheel.y;
break; break;
default: default:
break; break;
}
break;
case SDL_TEXTINPUT:
io.AddInputCharactersUTF8(event.text.text);
break;
case SDL_MOUSEWHEEL:
wheel = event.wheel.y;
break;
default:
break;
} }
} }
@@ -86,7 +88,10 @@ void Controller::onInput() {
void Controller::onLoad() { editor.UpdateScreen(); } void Controller::onLoad() { editor.UpdateScreen(); }
void Controller::doRender() { renderer.Render(); } void Controller::doRender() {
SDL_Delay(10);
renderer.Render();
}
void Controller::onExit() { void Controller::onExit() {
ImGui_ImplSDLRenderer_Shutdown(); ImGui_ImplSDLRenderer_Shutdown();
@@ -97,6 +102,6 @@ void Controller::onExit() {
SDL_Quit(); SDL_Quit();
} }
} // namespace Core } // namespace Core
} // namespace Application } // namespace Application
} // namespace yaze } // namespace yaze

View File

@@ -10,17 +10,17 @@ using namespace Core;
using namespace Graphics; using namespace Graphics;
Overworld::~Overworld() { Overworld::~Overworld() {
for (int i = 0; i < (int) tiles32.size(); i++) { // for (int i = 0; i < (int) tiles32.size(); i++) {
free(allmapsTilesLW[i]); // free(allmapsTilesLW[i]);
free(allmapsTilesDW[i]); // free(allmapsTilesDW[i]);
free(allmapsTilesSP[i]); // free(allmapsTilesSP[i]);
} // }
free(allmapsTilesLW); // free(allmapsTilesLW);
free(allmapsTilesDW); // free(allmapsTilesDW);
free(allmapsTilesSP); // free(allmapsTilesSP);
delete[] overworldMapPointer; // delete[] overworldMapPointer;
delete[] owactualMapPointer; // delete[] owactualMapPointer;
} }
static TileInfo GetTilesInfo(ushort tile) { static TileInfo GetTilesInfo(ushort tile) {

View File

@@ -93,9 +93,9 @@ void Editor::UpdateScreen() {
ImGuiWindowFlags flags = ImGuiWindowFlags flags =
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar |
ImGuiWindowFlags_MenuBar; ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoTitleBar;
if (!ImGui::Begin(title_.c_str(), nullptr, flags)) { if (!ImGui::Begin("##YazeMain", nullptr, flags)) {
ImGui::End(); ImGui::End();
return; return;
} }
@@ -103,12 +103,12 @@ void Editor::UpdateScreen() {
DrawYazeMenu(); DrawYazeMenu();
if (ImGui::BeginTabBar("##TabBar")) { if (ImGui::BeginTabBar("##TabBar")) {
DrawProjectEditor();
DrawOverworldEditor(); DrawOverworldEditor();
DrawDungeonEditor(); DrawDungeonEditor();
DrawGraphicsEditor(); DrawGraphicsEditor();
DrawSpriteEditor(); DrawSpriteEditor();
DrawScreenEditor(); DrawScreenEditor();
DrawROMInfo();
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
@@ -121,6 +121,7 @@ void Editor::DrawYazeMenu() {
DrawEditMenu(); DrawEditMenu();
DrawViewMenu(); DrawViewMenu();
DrawHelpMenu(); DrawHelpMenu();
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
@@ -281,24 +282,18 @@ void Editor::DrawHelpMenu() const {
} }
} }
// first step would be to decompress all graphics data from the game void Editor::DrawProjectEditor() {
// (in alttp that's easy they're all located in the same location all the if (ImGui::BeginTabItem("Project")) {
// same sheet size 128x32) have a code that convert PC address to SNES and if (rom.isLoaded()) {
// vice-versa ImGui::Text("Title: %s", rom.getTitle());
ImGui::Text("Version: %d", rom.getVersion());
ImGui::Text("ROM Size: %ld", rom.getSize());
}
ImGui::EndTabItem();
}
}
// 1) find the gfx pointers (you could use ZS constant file)
// 2) decompress all the gfx with your lz2 decompressor
// 3) convert the 3bpp snes data into PC 4bpp (probably the hardest part)
// 4) get the tiles32 data
// 5) get the tiles16 data
// 6) get the map32 data (they must be decompressed as well with a lz2
// variant not the same as gfx compression but pretty similar) 7) get the
// gfx data of the map yeah i forgot that one and load 4bpp in a pseudo vram
// and use that to render tiles on screen 8) try to render the tiles on the
// bitmap in black & white to start 9) get the palettes data and try to find
// how they're loaded in the game that's a big puzzle to solve then 9 you'll
// have an overworld map viewer, in less than few hours if are able to
// understand the data quickly
void Editor::DrawOverworldEditor() { void Editor::DrawOverworldEditor() {
if (ImGui::BeginTabItem("Overworld")) { if (ImGui::BeginTabItem("Overworld")) {
overworld_editor_.Update(); overworld_editor_.Update();
@@ -369,18 +364,6 @@ void Editor::DrawScreenEditor() {
} }
} }
void Editor::DrawROMInfo() {
if (ImGui::BeginTabItem("ROM Info")) {
if (rom.isLoaded()) {
ImGui::Text("Title: %s", rom.getTitle());
ImGui::Text("Version: %d", rom.getVersion());
ImGui::Text("ROM Size: %ld", rom.getSize());
}
ImGui::EndTabItem();
}
}
} // namespace Editor } // namespace Editor
} // namespace Application } // namespace Application
} // namespace yaze } // namespace yaze

View File

@@ -31,12 +31,12 @@ class Editor {
void DrawViewMenu(); void DrawViewMenu();
void DrawHelpMenu() const; void DrawHelpMenu() const;
void DrawProjectEditor();
void DrawOverworldEditor(); void DrawOverworldEditor();
void DrawDungeonEditor(); void DrawDungeonEditor();
void DrawGraphicsEditor(); void DrawGraphicsEditor();
void DrawSpriteEditor(); void DrawSpriteEditor();
void DrawScreenEditor(); void DrawScreenEditor();
void DrawROMInfo();
void *rom_data_; void *rom_data_;
bool isLoaded = true; bool isLoaded = true;
@@ -48,6 +48,10 @@ class Editor {
TextEditor::LanguageDefinition language65816Def; TextEditor::LanguageDefinition language65816Def;
OverworldEditor overworld_editor_; OverworldEditor overworld_editor_;
Graphics::Scene current_scene_;
Graphics::SNESPalette current_palette_;
Graphics::TilePreset current_set_;
ImGuiTableFlags toolset_table_flags = ImGuiTableFlags_SizingFixedFit; ImGuiTableFlags toolset_table_flags = ImGuiTableFlags_SizingFixedFit;
}; };

View File

@@ -8,25 +8,90 @@
#include "Graphics/Bitmap.h" #include "Graphics/Bitmap.h"
#include "Graphics/Tile.h" #include "Graphics/Tile.h"
// first step would be to decompress all graphics data from the game
// (in alttp that's easy they're all located in the same location all the
// same sheet size 128x32) have a code that convert PC address to SNES and
// vice-versa
// 1) find the gfx pointers (you could use ZS constant file)
// 2) decompress all the gfx with your lz2 decompressor
// 3) convert the 3bpp snes data into PC 4bpp (probably the hardest part)
// 4) get the tiles32 data
// 5) get the tiles16 data
// 6) get the map32 data (they must be decompressed as well with a lz2
// variant not the same as gfx compression but pretty similar) 7) get the
// gfx data of the map yeah i forgot that one and load 4bpp in a pseudo vram
// and use that to render tiles on screen 8) try to render the tiles on the
// bitmap in black & white to start 9) get the palettes data and try to find
// how they're loaded in the game that's a big puzzle to solve then 9 you'll
// have an overworld map viewer, in less than few hours if are able to
// understand the data quickly
namespace yaze { namespace yaze {
namespace Application { namespace Application {
namespace Editor { namespace Editor {
void OverworldEditor::Update() { void OverworldEditor::Update() {
if (rom_.isLoaded()) { if (rom_.isLoaded()) {
if (!doneLoaded) { if (!doneLoaded) {
overworld.Load(rom_); //overworld.Load(rom_);
Graphics::CreateAllGfxData(rom_.GetRawData(), allGfx16Ptr); // name=The Legend of Zelda - Link Sprites
SDL_Surface *surface =
SDL_CreateRGBSurfaceFrom(allGfx16Ptr, 128, 7104, 4, 64,
0x0000FF, // red mask
0x00FF00, // green mask
0xFF0000, // blue mask
1);
surface = current_scene_.buildSurface( // [rom]
rom_.ExtractTiles(4, 2048), palette_, current_set_.tilesPattern); // name=
// type=LoROM
gfx_texture = SDL_CreateTextureFromSurface(Core::renderer, surface);
// [tiles]
// pc_location=80000
// snes_location=0
// length=28672
// bpp=4
// compression=None
// pattern=normal
// [tiles_arrangement]
// tiles_per_row=16
// [palette]
// pc_location=dd308
// snes_location=0
// nozerocolor=true
// name="The Legend of Zelda - Action Sprites, shields, shovel and book"
// [rom]
// name=
// type=LoROM
// [tiles]
// pc_location=c0d64
// snes_location=0
// length=1081
// bpp=3
// compression=zelda3
// [tiles_arrangement]
// tiles_per_row=16
// [palette]
// pc_location=0
// snes_location=0
// nozerocolor=true
current_set_.pcTilesLocation = 0x8000;
current_set_.SNESTilesLocation = 0;
current_set_.length = 1000;
current_set_.bpp = 3;
current_set_.compression = "zelda3";
current_set_.pcPaletteLocation = 0;
current_set_.SNESPaletteLocation = 0;
palette_.colors.push_back(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
palette_.colors.push_back(ImVec4(0.0f, 0.5f, 0.0f, 1.0f));
palette_.colors.push_back(ImVec4(0.0f, 0.0f, 0.4f, 1.0f));
palette_.colors.push_back(ImVec4(0.3f, 0.0f, 0.0f, 1.0f));
palette_.colors.push_back(ImVec4(0.3f, 0.7f, 0.9f, 1.0f));
palette_.colors.push_back(ImVec4(0.5f, 0.5f, 0.5f, 1.0f));
current_scene_.buildSurface(rom_.ExtractTiles(current_set_), palette_, current_set_.tilesPattern);
doneLoaded = true; doneLoaded = true;
} }
} }
@@ -261,7 +326,9 @@ void OverworldEditor::DrawTileSelector() {
if (ImGui::BeginTabBar("##TabBar", ImGuiTabBarFlags_FittingPolicyScroll)) { if (ImGui::BeginTabBar("##TabBar", ImGuiTabBarFlags_FittingPolicyScroll)) {
if (ImGui::BeginTabItem("Tile8")) { if (ImGui::BeginTabItem("Tile8")) {
if (rom_.isLoaded()) { if (rom_.isLoaded()) {
ImGui::Image((void *)(intptr_t)gfx_texture, ImVec2(128, 7104)); for (const auto & [key, value] : current_scene_.imagesCache) {
ImGui::Image((void *)(SDL_Texture*)value, ImVec2(8, 8));
}
} }
ImGui::EndTabItem(); ImGui::EndTabItem();

View File

@@ -16,6 +16,8 @@ namespace Editor {
using byte = unsigned char; using byte = unsigned char;
static constexpr unsigned int k4BPP = 4;
class OverworldEditor { class OverworldEditor {
public: public:
void Update(); void Update();

View File

@@ -1,12 +0,0 @@
#include "Event.h"
namespace yaze {
namespace Application {
namespace Events {
void Event::Assign(const std::function<void()>& event) { event_ = event; }
void Event::Trigger() const { event_(); }
} // namespace Events
} // namespace Application
} // namespace yaze

View File

@@ -1,23 +0,0 @@
#ifndef YAZE_APPLICATION_EVENTS_EVENT_H
#define YAZE_APPLICATION_EVENTS_EVENT_H
#include <functional>
namespace yaze {
namespace Application {
namespace Events {
class Event {
public:
void Assign(const std::function<void()> & event);
void Trigger() const;
private:
std::function<void()> event_;
};
} // namespace Events
} // namespace Application
} // namespace yaze
#endif // YAZE_APPLICATION_EVENTS_EVENT_H

View File

@@ -12,6 +12,15 @@ SNESColor::SNESColor() {
snes = 0; snes = 0;
} }
SNESColor::SNESColor(ImVec4 val) {
rgb = val;
m_color col;
col.red = val.x;
col.blue = val.y;
col.green = val.z;
snes = convertcolor_rgb_to_snes(col);
}
void SNESColor::setRgb(ImVec4 val) { void SNESColor::setRgb(ImVec4 val) {
rgb = val; rgb = val;
m_color col; m_color col;
@@ -38,8 +47,8 @@ SNESPalette::SNESPalette(uint8_t mSize) {
} }
SNESPalette::SNESPalette(char* data) { SNESPalette::SNESPalette(char* data) {
//assert((data.size() % 4 == 0) && data.size() <= 32); // assert((data.size() % 4 == 0) && data.size() <= 32);
//size = data.size() / 2; // size = data.size() / 2;
size = sizeof(data) / 2; size = sizeof(data) / 2;
for (unsigned i = 0; i < sizeof(data); i += 2) { for (unsigned i = 0; i < sizeof(data); i += 2) {
SNESColor col; SNESColor col;
@@ -61,16 +70,34 @@ SNESPalette::SNESPalette(std::vector<ImVec4> cols) {
} }
char* SNESPalette::encode() { char* SNESPalette::encode() {
//char* data(size * 2, 0); // char* data(size * 2, 0);
char* data = new char[size * 2]; char* data = new char[size * 2];
for (unsigned int i = 0; i < size; i++) { for (unsigned int i = 0; i < size; i++) {
//std::cout << QString::number(colors[i].snes, 16); // std::cout << QString::number(colors[i].snes, 16);
data[i * 2] = (char)(colors[i].snes & 0xFF); data[i * 2] = (char)(colors[i].snes & 0xFF);
data[i * 2 + 1] = (char)(colors[i].snes >> 8); data[i * 2 + 1] = (char)(colors[i].snes >> 8);
} }
return data; return data;
} }
SDL_Palette* SNESPalette::GetSDL_Palette() {
SDL_Palette* result = new SDL_Palette;
result->ncolors = size;
SDL_Color* sdl_colors = new SDL_Color[size];
for (int i = 0; i < size; i++) {
sdl_colors[i].r = (uint8_t) colors[i].rgb.x * 100;
sdl_colors[i].g = (uint8_t) colors[i].rgb.y * 100;
sdl_colors[i].b = (uint8_t) colors[i].rgb.z * 100;
}
result->colors = sdl_colors;
// store the pointers to free them later
sdl_palettes_.push_back(result);
colors_arrays_.push_back(sdl_colors);
return result;
}
} // namespace Graphics } // namespace Graphics
} // namespace Application } // namespace Application
} // namespace yaze } // namespace yaze

View File

@@ -1,6 +1,7 @@
#ifndef YAZE_APPLICATION_GRAPHICS_PALETTE_H #ifndef YAZE_APPLICATION_GRAPHICS_PALETTE_H
#define YAZE_APPLICATION_GRAPHICS_PALETTE_H #define YAZE_APPLICATION_GRAPHICS_PALETTE_H
#include <SDL2/SDL.h>
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include <palette.h> #include <palette.h>
#include <tile.h> #include <tile.h>
@@ -9,12 +10,14 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
namespace yaze { namespace yaze {
namespace Application { namespace Application {
namespace Graphics { namespace Graphics {
struct SNESColor { struct SNESColor {
SNESColor(); SNESColor();
SNESColor(ImVec4);
uint16_t snes; uint16_t snes;
ImVec4 rgb; ImVec4 rgb;
void setRgb(ImVec4); void setRgb(ImVec4);
@@ -31,8 +34,13 @@ class SNESPalette {
SNESPalette(std::vector<ImVec4>); SNESPalette(std::vector<ImVec4>);
char* encode(); char* encode();
SDL_Palette* GetSDL_Palette();
uint8_t size; uint8_t size;
std::vector<SNESColor> colors; std::vector<SNESColor> colors;
std::vector<SDL_Palette*> sdl_palettes_;
std::vector<SDL_Color*> colors_arrays_;
}; };
} // namespace Graphics } // namespace Graphics

View File

@@ -4,6 +4,37 @@ namespace yaze {
namespace Application { namespace Application {
namespace Graphics { namespace Graphics {
void Scene::buildSurface(const std::vector<tile8>& tiles, SNESPalette& mPalette,
const TilesPattern& tp) {
arrangedTiles = TilesPattern::transform(tp, tiles);
tilesPattern = tp;
allTiles = tiles;
for (unsigned int j = 0; j < arrangedTiles.size(); j++) {
for (unsigned int i = 0; i < arrangedTiles[0].size(); i++) {
tile8 tile = arrangedTiles[j][i];
// SDL_PIXELFORMAT_RGB888 ?
SDL_Surface* newImage = SDL_CreateRGBSurfaceWithFormat(
0, 8, 8, SDL_BITSPERPIXEL(3), SDL_PIXELFORMAT_RGB444);
SDL_PixelFormat* format = newImage->format;
format->palette = mPalette.GetSDL_Palette();
char* ptr = (char*)newImage->pixels;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
ptr[i * 8 + j] = (char)tile.data[i * 8 + j];
}
}
SDL_Texture* texture =
SDL_CreateTextureFromSurface(Core::renderer, newImage);
imagesCache[tile.id] = texture;
}
}
}
void Scene::buildScene(const std::vector<tile8>& tiles, void Scene::buildScene(const std::vector<tile8>& tiles,
const SNESPalette mPalette, const TilesPattern& tp) { const SNESPalette mPalette, const TilesPattern& tp) {
arrangedTiles = TilesPattern::transform(tp, tiles); arrangedTiles = TilesPattern::transform(tp, tiles);
@@ -31,30 +62,10 @@ void Scene::buildScene(const std::vector<tile8>& tiles,
// j * newTileItem->boundingRect().width() + j); // j * newTileItem->boundingRect().width() + j);
} }
} }
// unsigned max_w = // unsigned max_w = items()[0]->boundingRect().width() *
// items()[0]->boundingRect().width() * arrangedTiles[0].size() + // arrangedTiles[0].size() + arrangedTiles[0].size(); unsigned max_h =
// arrangedTiles[0].size(); // items()[0]->boundingRect().width() * arrangedTiles.size() +
// unsigned max_h = items()[0]->boundingRect().width() * arrangedTiles.size() // arrangedTiles.size(); setSceneRect(QRect(0, 0, max_w, max_h));
// +
// arrangedTiles.size();
// setSceneRect(QRect(0, 0, max_w, max_h));
}
SDL_Surface* Scene::buildSurface(const std::vector<tile8>& tiles,
const SNESPalette mPalette,
const TilesPattern& tp) {
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 128, 7104, SDL_BITSPERPIXEL(4), SDL_PIXELFORMAT_RGB444);
arrangedTiles = TilesPattern::transform(tp, tiles);
tilesPattern = tp;
allTiles = tiles;
for (unsigned int j = 0; j < arrangedTiles.size(); j++) {
for (unsigned int i = 0; i < arrangedTiles[0].size(); i++) {
tile8 tile = arrangedTiles[j][i];
}
}
} }
void Scene::updateScene() { void Scene::updateScene() {

View File

@@ -10,7 +10,6 @@
#include "Core/Renderer.h" #include "Core/Renderer.h"
#include "Graphics/Tile.h" #include "Graphics/Tile.h"
namespace yaze { namespace yaze {
namespace Application { namespace Application {
namespace Graphics { namespace Graphics {
@@ -21,19 +20,21 @@ class Scene {
void buildScene(const std::vector<tile8>& tiles, const SNESPalette mPalette, void buildScene(const std::vector<tile8>& tiles, const SNESPalette mPalette,
const TilesPattern& tp); const TilesPattern& tp);
SDL_Surface* buildSurface(const std::vector<tile8>& tiles, void buildSurface(const std::vector<tile8>& tiles,
const SNESPalette mPalette, const TilesPattern& tp); SNESPalette& mPalette, const TilesPattern& tp);
void updateScene(); void updateScene();
void setTilesZoom(unsigned int tileZoom); void setTilesZoom(unsigned int tileZoom);
void setTilesPattern(TilesPattern tp); void setTilesPattern(TilesPattern tp);
std::unordered_map<unsigned int, SDL_Texture*> imagesCache;
private: private:
std::vector<tile8> allTiles;
std::vector<std::vector<tile8> > arrangedTiles;
unsigned int tilesZoom; unsigned int tilesZoom;
TilesPattern tilesPattern; TilesPattern tilesPattern;
// QMap<unsigned int, QPixmap> imagesCache; std::vector<tile8> allTiles;
std::vector<std::vector<tile8> > arrangedTiles;
}; };
} // namespace Graphics } // namespace Graphics

View File

@@ -46,13 +46,13 @@ char *hexString(const char *str, const unsigned int size) {
TilesPattern::TilesPattern() { TilesPattern::TilesPattern() {
tilesPerRow = 16; tilesPerRow = 16;
numberOfTiles = 16; numberOfTiles = 16;
transformVector.push_back(std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9, 11, 12, 13, 14, 15, 16}); transformVector.push_back(std::vector<int>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 9,
11, 12, 13, 14, 15, 16});
// transformVector.push_back(std::vector<int>{0, 1, 2, 3}); // transformVector.push_back(std::vector<int>{0, 1, 2, 3});
// transformVector.push_back(std::vector<int>{4, 5, 6, 7}); // transformVector.push_back(std::vector<int>{4, 5, 6, 7});
// transformVector.push_back(std::vector<int>{8, 9, 11, 12}); // transformVector.push_back(std::vector<int>{8, 9, 11, 12});
// transformVector.push_back(std::vector<int>{13, 14, 15, 16}); // transformVector.push_back(std::vector<int>{13, 14, 15, 16});
// default_settings();
} }
// [pattern] // [pattern]
// name = "32x32 B (4x4)" // name = "32x32 B (4x4)"
@@ -97,43 +97,43 @@ void TilesPattern::default_settings() {
std::cout << transformVector.size() << std::endl; std::cout << transformVector.size() << std::endl;
} }
bool TilesPattern::load(std::string patternFile) { // bool TilesPattern::load(std::string patternFile) {
// QSettings pFile(patternFile, QSettings::IniFormat); // QSettings pFile(patternFile, QSettings::IniFormat);
// name = pFile.value("pattern/name").toString(); // name = pFile.value("pattern/name").toString();
// description = pFile.value("pattern/description").toString(); // description = pFile.value("pattern/description").toString();
// numberOfTiles = pFile.value("pattern/number_of_tile").toInt(); // numberOfTiles = pFile.value("pattern/number_of_tile").toInt();
// std::cout << name; // std::cout << name;
// // unsigned int nbOfTile = pFile.value("_/number_of_tile").toUInt(); // // unsigned int nbOfTile = pFile.value("_/number_of_tile").toUInt();
// std::string patternString = pFile.value("pattern/pattern").toString(); // std::string patternString = pFile.value("pattern/pattern").toString();
// std::cout << patternString; // std::cout << patternString;
// // Pattern String is a array description // // Pattern String is a array description
// transformVector.clear(); // transformVector.clear();
// QRegExp arrayRegExp("(\\[[\\s|0-F|a-f|,]+\\])"); // QRegExp arrayRegExp("(\\[[\\s|0-F|a-f|,]+\\])");
// int pos = 0; // int pos = 0;
// while (arrayRegExp.indexIn(patternString, pos) != -1) { // while (arrayRegExp.indexIn(patternString, pos) != -1) {
// std::string arrayString = arrayRegExp.cap(1); // std::string arrayString = arrayRegExp.cap(1);
// std::vector<int> tmpVect; // std::vector<int> tmpVect;
// // std::cout << arrayString; // // std::cout << arrayString;
// unsigned int stringPos = 1; // unsigned int stringPos = 1;
// while (arrayString[stringPos] != ']') { // while (arrayString[stringPos] != ']') {
// while (arrayString[stringPos].isSpace()) stringPos++; // while (arrayString[stringPos].isSpace()) stringPos++;
// QRegExp hex("([0-F|a-f]+)"); // QRegExp hex("([0-F|a-f]+)");
// bool ok; // bool ok;
// if (hex.indexIn(arrayString, stringPos) == stringPos) { // if (hex.indexIn(arrayString, stringPos) == stringPos) {
// tmpVect.append(hex.cap(1).toInt(&ok, 16)); // tmpVect.append(hex.cap(1).toInt(&ok, 16));
// } // }
// while (arrayString[stringPos].isSpace()) stringPos++; // while (arrayString[stringPos].isSpace()) stringPos++;
// stringPos++; // should be the comma // stringPos++; // should be the comma
// } // }
// pos += arrayRegExp.matchedLength(); // pos += arrayRegExp.matchedLength();
// transformVector.append(tmpVect); // transformVector.append(tmpVect);
// } // }
// std::cout << transformVector.size() << transformVector; // std::cout << transformVector.size() << transformVector;
return true; // return true;
} // }
bool TilesPattern::loadPatterns() { bool TilesPattern::loadPatterns() {
// foreach (std::string fileName, patternDirectory.entryList(QDir::Files)) { // foreach (std::string fileName, patternDirectory.entryList(QDir::Files)) {
@@ -165,6 +165,7 @@ std::vector<std::vector<tile8> > TilesPattern::transform(
unsigned int nbTransform = tiles.size() / numberOfTiles; unsigned int nbTransform = tiles.size() / numberOfTiles;
printf("Tiles size : %d - nbtransform : %d - pattern number of tiles : %d", printf("Tiles size : %d - nbtransform : %d - pattern number of tiles : %d",
tiles.size(), nbTransform, numberOfTiles); tiles.size(), nbTransform, numberOfTiles);
if (transPerRow > nbTransform) if (transPerRow > nbTransform)
toret.resize(tVectHeight); toret.resize(tVectHeight);
else else
@@ -174,7 +175,7 @@ std::vector<std::vector<tile8> > TilesPattern::transform(
std::vector<std::vector<tile8> > vec(toret); std::vector<std::vector<tile8> > vec(toret);
auto it = vec.begin(); auto it = vec.begin();
for (auto each : vec) { for (auto &each : vec) {
each.resize(tilesPerRow); each.resize(tilesPerRow);
} }
// while (it.hasNext()) { // while (it.hasNext()) {
@@ -182,13 +183,13 @@ std::vector<std::vector<tile8> > TilesPattern::transform(
// } // }
// std::cout << toret[0].size() << "x" << toret.size(); // std::cout << toret[0].size() << "x" << toret.size();
while (repeat != nbTransform) { while (repeat != nbTransform) {
// std::cout << "repeat" << repeat; std::cout << "repeat" << repeat;
for (unsigned int j = 0; j < tVectHeight; j++) { for (unsigned int j = 0; j < tVectHeight; j++) {
for (unsigned int i = 0; i < tVectWidth; i++) { for (unsigned int i = 0; i < tVectWidth; i++) {
unsigned int posTile = transformVector[j][i] + numberOfTiles * repeat; unsigned int posTile = transformVector[j][i] + numberOfTiles * repeat;
unsigned int posX = i + repeatOffsetX; unsigned int posX = i + repeatOffsetX;
unsigned int posY = j + repeatOffsetY; unsigned int posY = j + repeatOffsetY;
// qDebug("X: %d - Y: %d - posTile : %d", posX, posY, posTile); printf("X: %d - Y: %d - posTile : %d", posX, posY, posTile);
toret[posY][posX] = tiles[posTile]; toret[posY][posX] = tiles[posTile];
} }
} }

View File

@@ -103,8 +103,6 @@ class TilesPattern {
void default_settings(); void default_settings();
bool load(std::string patternFile);
static bool loadPatterns(); static bool loadPatterns();
static TilesPattern pattern(std::string name); static TilesPattern pattern(std::string name);
static std::unordered_map<std::string, TilesPattern> Patterns(); static std::unordered_map<std::string, TilesPattern> Patterns();

View File

@@ -20,45 +20,67 @@ void ROM::LoadFromFile(const std::string &path) {
// 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);
rom_data_ = (char *) malloc(size);
fread(rom_data_, sizeof(char), size, file);
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_ + 32704, 21); memcpy(title, current_rom_ + 32704, 21);
type = LoROM; 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]; version = current_rom_[27];
loaded = true; loaded = true;
} }
std::vector<tile8> ROM::ExtractTiles(TilePreset &preset) {
std::vector<tile8> ROM::ExtractTiles(unsigned int bpp, unsigned int length) { std::cout << "Begin ROM::ExtractTiles" << std::endl;
std::vector<tile8> rawTiles; std::vector<tile8> rawTiles;
unsigned int lastCompressedSize; uint filePos = 0;
unsigned int size = length; unsigned int size = preset.length;
char *data = alttp_decompress_gfx((char*)current_rom_, 0, length, &size, &lastCompressedSize); filePos =
getRomPosition(preset, preset.pcTilesLocation, preset.SNESTilesLocation);
char *data = (char *)rom_data_ + filePos;
memcpy(data, rom_data_ + filePos, preset.length);
data =
alttp_decompress_gfx(data, 0, preset.length, &size, &lastCompressedSize);
std::cout << "size: " << size << std::endl;
std::cout << "lastCompressedSize: " << lastCompressedSize << std::endl;
if (data == NULL) { if (data == NULL) {
std:: cout << alttp_decompression_error << std::endl;
return rawTiles; return rawTiles;
} }
unsigned tileCpt = 0; unsigned tileCpt = 0;
for (unsigned int tilePos = 0; tilePos < size; tilePos += bpp * 8) { for (unsigned int tilePos = 0; tilePos < size; tilePos += preset.bpp * 8) {
tile8 newTile = unpack_bpp_tile(data, tilePos, bpp); std::cout << "Unpacking tile..." << std::endl;
tile8 newTile = unpack_bpp_tile(data, tilePos, preset.bpp);
newTile.id = tileCpt; newTile.id = tileCpt;
rawTiles.push_back(newTile); rawTiles.push_back(newTile);
tileCpt++; tileCpt++;
} }
free(data); free(data);
std::cout << "End ROM::ExtractTiles" << std::endl;
return rawTiles; return rawTiles;
} }
unsigned int ROM::getRomPosition(const TilePreset &preset, int directAddr,
unsigned int snesAddr) {
bool romHasHeader = false; // romInfo.hasHeader
if (overrideHeaderInfo) romHasHeader = overridenHeaderInfo;
unsigned int filePos = -1;
enum rom_type rType = LoROM;
std::cout << "ROM::getRomPosition: directAddr:" << directAddr << std::endl;
if (directAddr == -1) {
filePos = rommapping_snes_to_pc(snesAddr, rType, romHasHeader);
} else {
filePos = directAddr;
if (romHasHeader) filePos += 0x200;
}
std::cout << "ROM::getRomPosition: filePos:" << filePos << std::endl;
return filePos;
}
int ROM::SnesToPc(int addr) { int ROM::SnesToPc(int addr) {
if (addr >= 0x808000) { if (addr >= 0x808000) {

View File

@@ -31,9 +31,11 @@ int AddressFromBytes(byte addr1, byte addr2, byte addr3);
class ROM { class ROM {
public: public:
void LoadFromFile(const std::string& path); void LoadFromFile(const std::string& path);
std::vector<tile8> ExtractTiles(unsigned int bpp, unsigned int length); std::vector<tile8> ExtractTiles(TilePreset& preset);
unsigned int getRomPosition(const TilePreset& preset, int directAddr,
unsigned int snesAddr);
int SnesToPc(int addr); int SnesToPc(int addr);
short AddressFromBytes(byte addr1, byte addr2); short AddressFromBytes(byte addr1, byte addr2);
ushort ReadShort(int addr); ushort ReadShort(int addr);
void Write(int addr, byte value); void Write(int addr, byte value);
@@ -55,17 +57,19 @@ class ROM {
bool loaded = false; bool loaded = false;
byte* current_rom_; byte* current_rom_;
char* rom_data_;
bool overrideHeaderInfo;
bool overridenHeaderInfo;
unsigned int lastUnCompressSize;
unsigned int lastCompressedSize;
unsigned int lastCompressSize;
enum rom_type type; enum rom_type type;
bool fastrom; bool fastrom;
bool make_sense;
unsigned char title[21]; unsigned char title[21];
long int size; long int size;
unsigned int sram_size;
uint16_t creator_id;
unsigned char version; unsigned char version;
unsigned char checksum_comp;
unsigned char checksum;
}; };
} // namespace Utils } // namespace Utils

View File

@@ -45,7 +45,6 @@ add_executable(
Application/Graphics/Scene.cc Application/Graphics/Scene.cc
Application/Editor/Editor.cc Application/Editor/Editor.cc
Application/Editor/OverworldEditor.cc Application/Editor/OverworldEditor.cc
Application/Events/Event.cc
Application/Utils/Compression.cc Application/Utils/Compression.cc
Application/Utils/ROM.cc Application/Utils/ROM.cc
# GUI libraries # GUI libraries