more lowercase stuff
This commit is contained in:
1206
src/Application/Core/constants.h
Normal file
1206
src/Application/Core/constants.h
Normal file
File diff suppressed because it is too large
Load Diff
114
src/Application/Core/controller.cc
Normal file
114
src/Application/Core/controller.cc
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "controller.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
#include "core/renderer.h"
|
||||
#include "core/window.h"
|
||||
#include "editor/editor.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Core {
|
||||
|
||||
bool Controller::isActive() const { return active_; }
|
||||
|
||||
void Controller::onEntry() {
|
||||
window_.Create();
|
||||
renderer_.Create(window_.Get());
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
io.KeyMap[ImGuiKey_Backspace] = SDL_GetScancodeFromKey(SDLK_BACKSPACE);
|
||||
io.KeyMap[ImGuiKey_Enter] = SDL_GetScancodeFromKey(SDLK_RETURN);
|
||||
io.KeyMap[ImGuiKey_UpArrow] = SDL_GetScancodeFromKey(SDLK_UP);
|
||||
io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN);
|
||||
io.KeyMap[ImGuiKey_Tab] = SDL_GetScancodeFromKey(SDLK_TAB);
|
||||
io.KeyMap[ImGuiKey_LeftCtrl] = SDL_GetScancodeFromKey(SDLK_LCTRL);
|
||||
active_ = true;
|
||||
}
|
||||
|
||||
void Controller::onInput() {
|
||||
int wheel = 0;
|
||||
SDL_Event event;
|
||||
ImGuiIO &io = ImGui::GetIO();
|
||||
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_UP:
|
||||
case SDLK_DOWN:
|
||||
case SDLK_RETURN:
|
||||
case SDLK_BACKSPACE:
|
||||
case SDLK_TAB:
|
||||
io.KeysDown[event.key.keysym.scancode] =
|
||||
(event.type == SDL_KEYDOWN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYUP: {
|
||||
int key = event.key.keysym.scancode;
|
||||
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
|
||||
io.KeysDown[key] = (event.type == SDL_KEYDOWN);
|
||||
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
|
||||
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
|
||||
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
|
||||
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT:
|
||||
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;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int mouseX;
|
||||
int mouseY;
|
||||
const int buttons = SDL_GetMouseState(&mouseX, &mouseY);
|
||||
io.DeltaTime = 1.0f / 60.0f;
|
||||
io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
|
||||
io.MouseDown[0] = buttons & SDL_BUTTON(SDL_BUTTON_LEFT);
|
||||
io.MouseDown[1] = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT);
|
||||
io.MouseWheel = static_cast<float>(wheel);
|
||||
}
|
||||
|
||||
void Controller::onLoad() { editor_.UpdateScreen(); }
|
||||
|
||||
void Controller::doRender() {
|
||||
SDL_Delay(10);
|
||||
renderer_.Render();
|
||||
}
|
||||
|
||||
void Controller::onExit() {
|
||||
ImGui_ImplSDLRenderer_Shutdown();
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
window_.Destroy();
|
||||
renderer_.Destroy();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
44
src/Application/Core/controller.h
Normal file
44
src/Application/Core/controller.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef YAZE_APPLICATION_CORE_CONTROLLER_H
|
||||
#define YAZE_APPLICATION_CORE_CONTROLLER_H
|
||||
#define SDL_MAIN_HANDLED
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui/imgui_internal.h>
|
||||
|
||||
#include "core/renderer.h"
|
||||
#include "core/window.h"
|
||||
#include "editor/editor.h"
|
||||
|
||||
int main(int argc, char** argv);
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Core {
|
||||
|
||||
class Controller {
|
||||
public:
|
||||
Controller() = default;
|
||||
|
||||
bool isActive() const;
|
||||
void onEntry();
|
||||
void onInput();
|
||||
void onLoad();
|
||||
void doRender();
|
||||
void onExit();
|
||||
|
||||
private:
|
||||
inline void quit() { active_ = false; }
|
||||
friend int ::main(int argc, char** argv);
|
||||
|
||||
bool active_;
|
||||
Window window_;
|
||||
Renderer renderer_;
|
||||
Editor::Editor editor_;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APPLICATION_CORE_CONTROLLER_H
|
||||
77
src/Application/Core/renderer.cc
Normal file
77
src/Application/Core/renderer.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "Renderer.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <imgui/backends/imgui_impl_sdl.h>
|
||||
#include <imgui/backends/imgui_impl_sdlrenderer.h>
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include "graphics/icons.h"
|
||||
#include "graphics/style.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Core {
|
||||
|
||||
void Renderer::Create(SDL_Window* window) {
|
||||
if (window == nullptr) {
|
||||
SDL_Log("SDL_CreateWindow: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
} else {
|
||||
renderer = SDL_CreateRenderer(
|
||||
window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
if (renderer == nullptr) {
|
||||
SDL_Log("SDL_CreateRenderer: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
} else {
|
||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the ImGui and ImPlot contexts
|
||||
ImGui::CreateContext();
|
||||
|
||||
// Initialize ImGui for SDL
|
||||
ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
|
||||
ImGui_ImplSDLRenderer_Init(renderer);
|
||||
|
||||
// Load available fonts
|
||||
const ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->AddFontFromFileTTF("assets/Fonts/Karla-Regular.ttf", 14.0f);
|
||||
|
||||
// merge in icons from Google Material Design
|
||||
static const ImWchar icons_ranges[] = {ICON_MIN_MD, 0xf900, 0};
|
||||
ImFontConfig icons_config;
|
||||
icons_config.MergeMode = true;
|
||||
icons_config.GlyphOffset.y = 5.0f;
|
||||
icons_config.GlyphMinAdvanceX = 13.0f;
|
||||
icons_config.PixelSnapH = true;
|
||||
io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_MD, 18.0f, &icons_config,
|
||||
icons_ranges);
|
||||
io.Fonts->AddFontFromFileTTF("assets/Fonts/Roboto-Medium.ttf", 14.0f);
|
||||
io.Fonts->AddFontFromFileTTF("assets/Fonts/Cousine-Regular.ttf", 14.0f);
|
||||
io.Fonts->AddFontFromFileTTF("assets/Fonts/DroidSans.ttf", 16.0f);
|
||||
|
||||
// Set the default style
|
||||
Style::ColorsYaze();
|
||||
|
||||
// Build a new ImGui frame
|
||||
ImGui_ImplSDLRenderer_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame(window);
|
||||
}
|
||||
|
||||
void Renderer::Render() {
|
||||
SDL_RenderClear(renderer);
|
||||
ImGui::Render();
|
||||
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
void Renderer::Destroy() {
|
||||
SDL_DestroyRenderer(renderer);
|
||||
renderer = nullptr;
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
29
src/Application/Core/renderer.h
Normal file
29
src/Application/Core/renderer.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef YAZE_APPLICATION_CORE_RENDERER_H
|
||||
#define YAZE_APPLICATION_CORE_RENDERER_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <imgui/backends/imgui_impl_sdl.h>
|
||||
#include <imgui/backends/imgui_impl_sdlrenderer.h>
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include "graphics/icons.h"
|
||||
#include "graphics/style.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Core {
|
||||
|
||||
static SDL_Renderer* renderer = nullptr;
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
void Create(SDL_Window* window);
|
||||
void Render();
|
||||
void Destroy();
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APPLICATION_CORE_RENDERER_H
|
||||
33
src/Application/Core/window.cc
Normal file
33
src/Application/Core/window.cc
Normal file
@@ -0,0 +1,33 @@
|
||||
#include "Window.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Core {
|
||||
|
||||
// TODO: pass in the size of the window as argument
|
||||
void Window::Create() {
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING)) {
|
||||
SDL_Log("SDL_Init: %s\n", SDL_GetError());
|
||||
} else {
|
||||
window = SDL_CreateWindow("Yet Another Zelda3 Editor", // window title
|
||||
SDL_WINDOWPOS_UNDEFINED, // initial x position
|
||||
SDL_WINDOWPOS_UNDEFINED, // initial y position
|
||||
1200, // width, in pixels
|
||||
800, // height, in pixels
|
||||
SDL_WINDOW_RESIZABLE // window flags
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Window* Window::Get() { return window; }
|
||||
|
||||
void Window::Destroy() {
|
||||
SDL_DestroyWindow(window);
|
||||
window = nullptr;
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
24
src/Application/Core/window.h
Normal file
24
src/Application/Core/window.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef YAZE_APPLICATION_CORE_WINDOW_H
|
||||
#define YAZE_APPLICATION_CORE_WINDOW_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Core {
|
||||
|
||||
class Window {
|
||||
public:
|
||||
void Create();
|
||||
void Destroy();
|
||||
SDL_Window* Get();
|
||||
|
||||
private:
|
||||
SDL_Window* window = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
348
src/Application/Data/OW/overworld.cc
Normal file
348
src/Application/Data/OW/overworld.cc
Normal file
@@ -0,0 +1,348 @@
|
||||
#include "overworld.h"
|
||||
|
||||
#include "graphics/tile.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Data {
|
||||
|
||||
using namespace Core;
|
||||
using namespace Graphics;
|
||||
|
||||
Overworld::~Overworld() {
|
||||
// for (int i = 0; i < (int) 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;
|
||||
ushort v = 0;
|
||||
ushort h = 0;
|
||||
ushort tid = (ushort)(tile & 0x3FF);
|
||||
byte p = (byte)((tile >> 10) & 0x07);
|
||||
|
||||
o = (ushort)((tile & 0x2000) >> 13);
|
||||
h = (ushort)((tile & 0x4000) >> 14);
|
||||
v = (ushort)((tile & 0x8000) >> 15);
|
||||
|
||||
return TileInfo(tid, p, v, h, o);
|
||||
}
|
||||
|
||||
void Overworld::Load(Data::ROM rom) {
|
||||
rom_ = rom;
|
||||
for (int i = 0; i < 0x2B; i++) {
|
||||
// tileLeftEntrance.push_back(
|
||||
// rom_.ReadShort(Constants::overworldEntranceAllowedTilesLeft + (i *
|
||||
// 2)));
|
||||
// tileRightEntrance.push_back(rom_.ReadShort(
|
||||
// Constants::overworldEntranceAllowedTilesRight + (i * 2)));
|
||||
}
|
||||
|
||||
AssembleMap32Tiles();
|
||||
AssembleMap16Tiles();
|
||||
DecompressAllMapTiles();
|
||||
|
||||
// Map Initialization :
|
||||
for (int i = 0; i < 160; 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, allmapsTilesLW,
|
||||
allmapsTilesDW, allmapsTilesSP);
|
||||
}
|
||||
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
ushort Overworld::GenerateTile32(int i, int k, int dimension) {
|
||||
return (ushort)(rom_.GetRawData()[map32address[dimension] + k + (i)] +
|
||||
(((rom_.GetRawData()[map32address[dimension] + (i) +
|
||||
(k <= 1 ? 4 : 5)] >>
|
||||
(k % 2 == 0 ? 4 : 0)) &
|
||||
0x0F) *
|
||||
256));
|
||||
}
|
||||
|
||||
void Overworld::AssembleMap32Tiles() {
|
||||
for (int i = 0; i < 0x33F0; i += 6) {
|
||||
ushort tl, tr, bl, br;
|
||||
for (int k = 0; k < 4; k++) {
|
||||
tl = GenerateTile32(i, k, (int)Dimension::map32TilesTL);
|
||||
tr = GenerateTile32(i, k, (int)Dimension::map32TilesTR);
|
||||
bl = GenerateTile32(i, k, (int)Dimension::map32TilesBL);
|
||||
br = GenerateTile32(i, k, (int)Dimension::map32TilesBR);
|
||||
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() {
|
||||
int tpos = Core::Constants::map16Tiles;
|
||||
for (int i = 0; i < 4096; i += 1) // 3760
|
||||
{
|
||||
TileInfo t0 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos);
|
||||
tpos += 2;
|
||||
TileInfo t1 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos);
|
||||
tpos += 2;
|
||||
TileInfo t2 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos);
|
||||
tpos += 2;
|
||||
TileInfo t3 = GetTilesInfo((uintptr_t)rom_.GetRawData() + tpos);
|
||||
tpos += 2;
|
||||
tiles16.push_back(Tile16(t0, t1, t2, t3));
|
||||
}
|
||||
}
|
||||
|
||||
void Overworld::DecompressAllMapTiles() {
|
||||
int lowest = 0x0FFFFF;
|
||||
int highest = 0x0F8000;
|
||||
int sx = 0;
|
||||
int sy = 0;
|
||||
int c = 0;
|
||||
for (int i = 0; i < 160; i++) {
|
||||
int p1 = (rom_.GetRawData()[(Constants::compressedAllMap32PointersHigh) +
|
||||
2 + (int)(3 * i)]
|
||||
<< 16) +
|
||||
(rom_.GetRawData()[(Constants::compressedAllMap32PointersHigh) +
|
||||
1 + (int)(3 * i)]
|
||||
<< 8) +
|
||||
(rom_.GetRawData()[(Constants::compressedAllMap32PointersHigh +
|
||||
(int)(3 * i))]);
|
||||
|
||||
char* tmp = new char[256];
|
||||
p1 = lorom_snes_to_pc(p1, &tmp);
|
||||
std::cout << tmp << std::endl;
|
||||
int p2 = (rom_.GetRawData()[(Constants::compressedAllMap32PointersLow) + 2 +
|
||||
(int)(3 * i)]
|
||||
<< 16) +
|
||||
(rom_.GetRawData()[(Constants::compressedAllMap32PointersLow) + 1 +
|
||||
(int)(3 * i)]
|
||||
<< 8) +
|
||||
(rom_.GetRawData()[(Constants::compressedAllMap32PointersLow +
|
||||
(int)(3 * i))]);
|
||||
p2 = lorom_snes_to_pc(p2, &tmp);
|
||||
std::cout << tmp << std::endl;
|
||||
delete[] tmp;
|
||||
|
||||
int ttpos = 0;
|
||||
unsigned int compressedSize1 = 0;
|
||||
unsigned int compressedSize2 = 0;
|
||||
unsigned int compressedLength1 = 0;
|
||||
unsigned int compressedLength2 = 0;
|
||||
|
||||
if (p1 >= highest) {
|
||||
highest = p1;
|
||||
}
|
||||
if (p2 >= highest) {
|
||||
highest = p2;
|
||||
}
|
||||
|
||||
if (p1 <= lowest) {
|
||||
if (p1 > 0x0F8000) {
|
||||
lowest = p1;
|
||||
}
|
||||
}
|
||||
if (p2 <= lowest) {
|
||||
if (p2 > 0x0F8000) {
|
||||
lowest = p2;
|
||||
}
|
||||
}
|
||||
|
||||
auto bytes =
|
||||
alttp_decompress_overworld((char*)rom_.GetRawData(), p2, 1000,
|
||||
&compressedSize1, &compressedLength1);
|
||||
auto bytes2 =
|
||||
alttp_decompress_overworld((char*)rom_.GetRawData(), p1, 1000,
|
||||
&compressedSize2, &compressedLength2);
|
||||
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
ushort tidD = (ushort)((bytes2[ttpos] << 8) + bytes[ttpos]);
|
||||
|
||||
int tpos = tidD;
|
||||
if (tpos < tiles32.size()) {
|
||||
if (i < 64) {
|
||||
allmapsTilesLW[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] =
|
||||
tiles32[tpos].tile0_;
|
||||
allmapsTilesLW[(x * 2) + 1 + (sx * 32)][(y * 2) + (sy * 32)] =
|
||||
tiles32[tpos].tile1_;
|
||||
allmapsTilesLW[(x * 2) + (sx * 32)][(y * 2) + 1 + (sy * 32)] =
|
||||
tiles32[tpos].tile2_;
|
||||
allmapsTilesLW[(x * 2) + 1 + (sx * 32)][(y * 2) + 1 + (sy * 32)] =
|
||||
tiles32[tpos].tile3_;
|
||||
} else if (i < 128 && i >= 64) {
|
||||
allmapsTilesDW[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] =
|
||||
tiles32[tpos].tile0_;
|
||||
allmapsTilesDW[(x * 2) + 1 + (sx * 32)][(y * 2) + (sy * 32)] =
|
||||
tiles32[tpos].tile1_;
|
||||
allmapsTilesDW[(x * 2) + (sx * 32)][(y * 2) + 1 + (sy * 32)] =
|
||||
tiles32[tpos].tile2_;
|
||||
allmapsTilesDW[(x * 2) + 1 + (sx * 32)][(y * 2) + 1 + (sy * 32)] =
|
||||
tiles32[tpos].tile3_;
|
||||
} else {
|
||||
allmapsTilesSP[(x * 2) + (sx * 32)][(y * 2) + (sy * 32)] =
|
||||
tiles32[tpos].tile0_;
|
||||
allmapsTilesSP[(x * 2) + 1 + (sx * 32)][(y * 2) + (sy * 32)] =
|
||||
tiles32[tpos].tile1_;
|
||||
allmapsTilesSP[(x * 2) + (sx * 32)][(y * 2) + 1 + (sy * 32)] =
|
||||
tiles32[tpos].tile2_;
|
||||
allmapsTilesSP[(x * 2) + 1 + (sx * 32)][(y * 2) + 1 + (sy * 32)] =
|
||||
tiles32[tpos].tile3_;
|
||||
}
|
||||
}
|
||||
|
||||
ttpos += 1;
|
||||
}
|
||||
}
|
||||
|
||||
sx++;
|
||||
if (sx >= 8) {
|
||||
sy++;
|
||||
sx = 0;
|
||||
}
|
||||
|
||||
c++;
|
||||
if (c >= 64) {
|
||||
sx = 0;
|
||||
sy = 0;
|
||||
c = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "MapPointers(lowest) : " << lowest << std::endl;
|
||||
std::cout << "MapPointers(highest) : " << highest << std::endl;
|
||||
}
|
||||
|
||||
void Overworld::FetchLargeMaps() {
|
||||
for (int i = 128; i < 145; i++) {
|
||||
mapParent[i] = 0;
|
||||
}
|
||||
|
||||
mapParent[128] = 128;
|
||||
mapParent[129] = 129;
|
||||
mapParent[130] = 129;
|
||||
mapParent[137] = 129;
|
||||
mapParent[138] = 129;
|
||||
mapParent[136] = 136;
|
||||
allmaps[136].largeMap = false;
|
||||
|
||||
bool mapChecked[64];
|
||||
for (int i = 0; i < 64; i++) {
|
||||
mapChecked[i] = false;
|
||||
}
|
||||
int xx = 0;
|
||||
int yy = 0;
|
||||
while (true) {
|
||||
int i = xx + (yy * 8);
|
||||
if (mapChecked[i] == false) {
|
||||
if (allmaps[i].largeMap == true) {
|
||||
mapChecked[i] = true;
|
||||
mapParent[i] = (byte)i;
|
||||
mapParent[i + 64] = (byte)(i + 64);
|
||||
|
||||
mapChecked[i + 1] = true;
|
||||
mapParent[i + 1] = (byte)i;
|
||||
mapParent[i + 65] = (byte)(i + 64);
|
||||
|
||||
mapChecked[i + 8] = true;
|
||||
mapParent[i + 8] = (byte)i;
|
||||
mapParent[i + 72] = (byte)(i + 64);
|
||||
|
||||
mapChecked[i + 9] = true;
|
||||
mapParent[i + 9] = (byte)i;
|
||||
mapParent[i + 73] = (byte)(i + 64);
|
||||
xx++;
|
||||
} else {
|
||||
mapParent[i] = (byte)i;
|
||||
mapParent[i + 64] = (byte)(i + 64);
|
||||
mapChecked[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
xx++;
|
||||
if (xx >= 8) {
|
||||
xx = 0;
|
||||
yy += 1;
|
||||
if (yy >= 8) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Overworld::LoadOverworldMap() {
|
||||
overworldMapBitmap = new Bitmap(128, 128, overworldMapPointer);
|
||||
overworldMapBitmap->Create(&overworldMapTexture);
|
||||
owactualMapBitmap = new Bitmap(512, 512, owactualMapPointer);
|
||||
owactualMapBitmap->Create(&owactualMapTexture);
|
||||
|
||||
// Mode 7
|
||||
char* ptr = overworldMapPointer;
|
||||
|
||||
int pos = 0;
|
||||
for (int sy = 0; sy < 16; sy++) {
|
||||
for (int sx = 0; sx < 16; sx++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < 8; x++) {
|
||||
ptr[x + (sx * 8) + (y * 128) + (sy * 1024)] =
|
||||
rom_.GetRawData()[0x0C4000 + pos];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ColorPalette cp = overworldMapBitmap.Palette;
|
||||
// for (int i = 0; i < 256; i += 2)
|
||||
// {
|
||||
// //55B27 = US LW
|
||||
// //55C27 = US DW
|
||||
// cp.Entries[i / 2] = getColor((short)((ROM.DATA[0x55B27 + i + 1] << 8) +
|
||||
// ROM.DATA[0x55B27 + i]));
|
||||
|
||||
// int k = 0;
|
||||
// int j = 0;
|
||||
// for (int y = 10; y < 14; y++)
|
||||
// {
|
||||
// for (int x = 0; x < 15; x++)
|
||||
// {
|
||||
// cp.Entries[145 + k] = Palettes.globalSprite_Palettes[0][j];
|
||||
// k++;
|
||||
// j++;
|
||||
// }
|
||||
// k++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// overworldMapBitmap.Palette = cp;
|
||||
// owactualMapBitmap.Palette = cp;
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
79
src/Application/Data/OW/overworld.h
Normal file
79
src/Application/Data/OW/overworld.h
Normal file
@@ -0,0 +1,79 @@
|
||||
#ifndef YAZE_APPLICATION_DATA_OVERWORLD_H
|
||||
#define YAZE_APPLICATION_DATA_OVERWORLD_H
|
||||
|
||||
#include <rommapping.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "core/constants.h"
|
||||
#include "data/rom.h"
|
||||
#include "graphics/bitmap.h"
|
||||
#include "graphics/tile.h"
|
||||
#include "overworld_map.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Data {
|
||||
|
||||
using ushort = unsigned short;
|
||||
using byte = unsigned char;
|
||||
|
||||
class Overworld {
|
||||
public:
|
||||
Overworld() = default;
|
||||
~Overworld();
|
||||
|
||||
void Load(Data::ROM rom);
|
||||
|
||||
char* overworldMapPointer = new char[0x40000];
|
||||
Graphics::Bitmap* overworldMapBitmap;
|
||||
GLuint overworldMapTexture;
|
||||
|
||||
char* owactualMapPointer = new char[0x40000];
|
||||
Graphics::Bitmap* owactualMapBitmap;
|
||||
GLuint owactualMapTexture;
|
||||
|
||||
private:
|
||||
Data::ROM rom_;
|
||||
int gameState = 1;
|
||||
bool isLoaded = false;
|
||||
byte mapParent[160];
|
||||
|
||||
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;
|
||||
std::vector<Graphics::Tile32> map16tiles;
|
||||
|
||||
std::vector<OverworldMap> allmaps;
|
||||
|
||||
std::vector<ushort> tileLeftEntrance;
|
||||
std::vector<ushort> tileRightEntrance;
|
||||
|
||||
int map32address[4] = {
|
||||
Core::Constants::map32TilesTL, Core::Constants::map32TilesTR,
|
||||
Core::Constants::map32TilesBL, Core::Constants::map32TilesBR};
|
||||
|
||||
enum Dimension {
|
||||
map32TilesTL = 0,
|
||||
map32TilesTR = 1,
|
||||
map32TilesBL = 2,
|
||||
map32TilesBR = 3
|
||||
};
|
||||
|
||||
ushort GenerateTile32(int i, int k, int dimension);
|
||||
void AssembleMap32Tiles();
|
||||
void AssembleMap16Tiles();
|
||||
void DecompressAllMapTiles();
|
||||
void FetchLargeMaps();
|
||||
void LoadOverworldMap();
|
||||
};
|
||||
|
||||
} // namespace Data
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
117
src/Application/Data/rom.cc
Normal file
117
src/Application/Data/rom.cc
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "ROM.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Data {
|
||||
|
||||
void ROM::LoadFromFile(const std::string &path) {
|
||||
FILE *file = fopen(path.c_str(), "r+");
|
||||
if (file == NULL) return;
|
||||
fseek(file, 0, SEEK_END);
|
||||
size = ftell(file);
|
||||
fclose(file);
|
||||
|
||||
// Reading data to array of unsigned chars
|
||||
file = fopen(path.c_str(), "r+");
|
||||
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);
|
||||
fclose(file);
|
||||
|
||||
memcpy(title, rom_data_ + 32704, 21);
|
||||
type = LoROM;
|
||||
version = current_rom_[27];
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
std::vector<tile8> ROM::ExtractTiles(TilePreset &preset) {
|
||||
std::cout << "Extracting tiles..." << std::endl;
|
||||
uint filePos = 0;
|
||||
uint size_out = 0;
|
||||
uint size = preset.length;
|
||||
int tilePos = preset.pcTilesLocation;
|
||||
std::vector<tile8> rawTiles;
|
||||
filePos = getRomPosition(preset, tilePos, preset.SNESTilesLocation);
|
||||
std::cout << "ROM Position: " << filePos << " from "
|
||||
<< preset.SNESTilesLocation << std::endl;
|
||||
|
||||
// decompress the graphics
|
||||
char *data = (char *)malloc(sizeof(char) * size);
|
||||
memcpy(data, (rom_data_ + filePos), size);
|
||||
data = alttp_decompress_gfx(data, 0, size, &size_out, &lastCompressedSize);
|
||||
std::cout << "size: " << size << std::endl;
|
||||
std::cout << "lastCompressedSize: " << lastCompressedSize << std::endl;
|
||||
if (data == NULL) {
|
||||
std::cout << alttp_decompression_error << std::endl;
|
||||
return rawTiles;
|
||||
}
|
||||
// unpack the tiles based on their depth
|
||||
unsigned tileCpt = 0;
|
||||
std::cout << "Unpacking tiles..." << std::endl;
|
||||
for (unsigned int tilePos = 0; tilePos < size; tilePos += preset.bpp * 8) {
|
||||
tile8 newTile = unpack_bpp_tile(data, tilePos, preset.bpp);
|
||||
newTile.id = tileCpt;
|
||||
rawTiles.push_back(newTile);
|
||||
tileCpt++;
|
||||
}
|
||||
std::cout << "Done unpacking tiles" << std::endl;
|
||||
free(data);
|
||||
std::cout << "Done extracting tiles." << std::endl;
|
||||
return rawTiles;
|
||||
}
|
||||
|
||||
SNESPalette ROM::ExtractPalette(TilePreset &preset) {
|
||||
unsigned int filePos = getRomPosition(preset, preset.pcPaletteLocation,
|
||||
preset.SNESPaletteLocation);
|
||||
std::cout << "Palette pos : " << filePos << std::endl; // TODO: make this hex
|
||||
unsigned int palette_size = pow(2, preset.bpp); // - 1;
|
||||
char *ab = (char *)malloc(sizeof(char) * (palette_size * 2));
|
||||
memcpy(ab, rom_data_ + filePos, palette_size * 2);
|
||||
|
||||
for (int i = 0; i < palette_size; i++) {
|
||||
std::cout << ab[i];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
const char *data = ab;
|
||||
SNESPalette pal(ab);
|
||||
if (preset.paletteNoZeroColor) {
|
||||
SNESColor col;
|
||||
|
||||
col.setRgb(ImVec4(153, 153, 153, 255));
|
||||
pal.colors.push_back(col);
|
||||
pal.colors.erase(pal.colors.begin(),
|
||||
pal.colors.begin() + pal.colors.size() - 1);
|
||||
}
|
||||
return pal;
|
||||
}
|
||||
|
||||
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 AddressFromBytes(byte addr1, byte addr2, byte addr3) {
|
||||
return (addr1 << 16) | (addr2 << 8) | addr3;
|
||||
}
|
||||
|
||||
short ROM::AddressFromBytes(byte addr1, byte addr2) {
|
||||
return (short)((addr1 << 8) | (addr2));
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
67
src/Application/Data/rom.h
Normal file
67
src/Application/Data/rom.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef YAZE_APPLICATION_UTILS_ROM_H
|
||||
#define YAZE_APPLICATION_UTILS_ROM_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Core/Constants.h"
|
||||
#include "graphics/tile.h"
|
||||
#include "compressions/alttpcompression.h"
|
||||
#include "compressions/stdnintendo.h"
|
||||
#include "rommapping.h"
|
||||
#include "tile.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Data {
|
||||
|
||||
using byte = unsigned char;
|
||||
using ushort = unsigned short;
|
||||
|
||||
using namespace Graphics;
|
||||
|
||||
int AddressFromBytes(byte addr1, byte addr2, byte addr3);
|
||||
|
||||
class ROM {
|
||||
public:
|
||||
void LoadFromFile(const std::string& path);
|
||||
std::vector<tile8> ExtractTiles(TilePreset& preset);
|
||||
SNESPalette ExtractPalette(TilePreset& preset);
|
||||
unsigned int getRomPosition(const TilePreset& preset, int directAddr,
|
||||
unsigned int snesAddr);
|
||||
short AddressFromBytes(byte addr1, byte addr2);
|
||||
inline byte* GetRawData() { return current_rom_; }
|
||||
const unsigned char* getTitle() const { return title; }
|
||||
unsigned int getSize() const { return size; }
|
||||
char getVersion() const { return version; }
|
||||
bool isLoaded() const { return loaded; }
|
||||
|
||||
private:
|
||||
bool loaded = false;
|
||||
|
||||
byte* current_rom_;
|
||||
char* rom_data_;
|
||||
|
||||
bool fastrom;
|
||||
long int size;
|
||||
enum rom_type type;
|
||||
|
||||
bool overrideHeaderInfo;
|
||||
bool overridenHeaderInfo;
|
||||
unsigned int lastUnCompressSize;
|
||||
unsigned int lastCompressedSize;
|
||||
unsigned int lastCompressSize;
|
||||
unsigned char version;
|
||||
unsigned char title[21] = "ROM Not Loaded";
|
||||
};
|
||||
|
||||
} // namespace Data
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
507
src/Application/Editor/editor.cc
Normal file
507
src/Application/Editor/editor.cc
Normal file
@@ -0,0 +1,507 @@
|
||||
#include "Editor.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Editor {
|
||||
|
||||
using namespace Core;
|
||||
|
||||
Editor::Editor() {
|
||||
static bool inited = false;
|
||||
if (!inited) {
|
||||
static const char *const keywords[] = {
|
||||
"ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE",
|
||||
"BPL", "BRA", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV",
|
||||
"CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "EOR", "INC", "INX",
|
||||
"INY", "JMP", "JSR", "JSL", "LDA", "LDX", "LDY", "LSR", "MVN",
|
||||
"NOP", "ORA", "PEA", "PER", "PHA", "PHB", "PHD", "PHP", "PHX",
|
||||
"PHY", "PLA", "PLB", "PLD", "PLP", "PLX", "PLY", "REP", "ROL",
|
||||
"ROR", "RTI", "RTL", "RTS", "SBC", "SEC", "SEI", "SEP", "STA",
|
||||
"STP", "STX", "STY", "STZ", "TAX", "TAY", "TCD", "TCS", "TDC",
|
||||
"TRB", "TSB", "TSC", "TSX", "TXA", "TXS", "TXY", "TYA", "TYX",
|
||||
"WAI", "WDM", "XBA", "XCE", "ORG", "LOROM", "HIROM", "NAMESPACE", "DB"};
|
||||
for (auto &k : keywords) language65816Def.mKeywords.emplace(k);
|
||||
|
||||
static const char *const identifiers[] = {
|
||||
"abort", "abs", "acos", "asin", "atan", "atexit",
|
||||
"atof", "atoi", "atol", "ceil", "clock", "cosh",
|
||||
"ctime", "div", "exit", "fabs", "floor", "fmod",
|
||||
"getchar", "getenv", "isalnum", "isalpha", "isdigit", "isgraph",
|
||||
"ispunct", "isspace", "isupper", "kbhit", "log10", "log2",
|
||||
"log", "memcmp", "modf", "pow", "putchar", "putenv",
|
||||
"puts", "rand", "remove", "rename", "sinh", "sqrt",
|
||||
"srand", "strcat", "strcmp", "strerror", "time", "tolower",
|
||||
"toupper"};
|
||||
for (auto &k : identifiers) {
|
||||
TextEditor::Identifier id;
|
||||
id.mDeclaration = "Built-in function";
|
||||
language65816Def.mIdentifiers.insert(std::make_pair(std::string(k), id));
|
||||
}
|
||||
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"[ \\t]*#[ \\t]*[a-zA-Z_]+",
|
||||
TextEditor::PaletteIndex::Preprocessor));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"L?\\\"(\\\\.|[^\\\"])*\\\"", TextEditor::PaletteIndex::String));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"\\'\\\\?[^\\']\\'", TextEditor::PaletteIndex::CharLiteral));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?",
|
||||
TextEditor::PaletteIndex::Number));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"[+-]?[0-9]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"0[0-7]+[Uu]?[lL]?[lL]?", TextEditor::PaletteIndex::Number));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?",
|
||||
TextEditor::PaletteIndex::Number));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"[a-zA-Z_][a-zA-Z0-9_]*", TextEditor::PaletteIndex::Identifier));
|
||||
language65816Def.mTokenRegexStrings.push_back(
|
||||
std::make_pair<std::string, TextEditor::PaletteIndex>(
|
||||
"[\\[\\]\\{\\}\\!\\%\\^\\&\\*\\(\\)\\-\\+\\=\\~\\|\\<\\>\\?\\/"
|
||||
"\\;\\,\\.]",
|
||||
TextEditor::PaletteIndex::Punctuation));
|
||||
|
||||
language65816Def.mCommentStart = "/*";
|
||||
language65816Def.mCommentEnd = "*/";
|
||||
language65816Def.mSingleLineComment = ";";
|
||||
|
||||
language65816Def.mCaseSensitive = false;
|
||||
language65816Def.mAutoIndentation = true;
|
||||
|
||||
language65816Def.mName = "65816";
|
||||
|
||||
inited = true;
|
||||
}
|
||||
asm_editor_.SetLanguageDefinition(language65816Def);
|
||||
asm_editor_.SetPalette(TextEditor::GetDarkPalette());
|
||||
|
||||
current_set_.bpp = 4;
|
||||
current_set_.pcTilesLocation = 0x80000;
|
||||
current_set_.SNESTilesLocation = 0;
|
||||
current_set_.length = 28672;
|
||||
current_set_.pcPaletteLocation = 0xDD326;
|
||||
current_set_.SNESPaletteLocation = 0;
|
||||
current_set_.compression = "zelda3";
|
||||
current_palette_.colors.push_back(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
current_palette_.colors.push_back(ImVec4(0.0f, 0.5f, 0.0f, 1.0f));
|
||||
current_palette_.colors.push_back(ImVec4(0.0f, 0.0f, 0.4f, 1.0f));
|
||||
current_palette_.colors.push_back(ImVec4(0.3f, 0.0f, 0.0f, 1.0f));
|
||||
current_palette_.colors.push_back(ImVec4(0.3f, 0.7f, 0.9f, 1.0f));
|
||||
current_palette_.colors.push_back(ImVec4(0.5f, 0.5f, 0.5f, 1.0f));
|
||||
}
|
||||
|
||||
void Editor::UpdateScreen() {
|
||||
const ImGuiIO &io = ImGui::GetIO();
|
||||
ImGui::NewFrame();
|
||||
ImGui::SetNextWindowPos(ImVec2(0, 0));
|
||||
ImVec2 dimensions(io.DisplaySize.x, io.DisplaySize.y);
|
||||
ImGui::SetNextWindowSize(dimensions, ImGuiCond_Always);
|
||||
ImGuiWindowFlags flags =
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoTitleBar;
|
||||
|
||||
if (!ImGui::Begin("##YazeMain", nullptr, flags)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
DrawYazeMenu();
|
||||
|
||||
TAB_BAR("##TabBar");
|
||||
DrawProjectEditor();
|
||||
DrawOverworldEditor();
|
||||
DrawDungeonEditor();
|
||||
DrawGraphicsEditor();
|
||||
DrawSpriteEditor();
|
||||
DrawScreenEditor();
|
||||
END_TAB_BAR();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void Editor::DrawYazeMenu() {
|
||||
MENU_BAR();
|
||||
DrawFileMenu();
|
||||
DrawEditMenu();
|
||||
DrawViewMenu();
|
||||
DrawHelpMenu();
|
||||
END_MENU_BAR();
|
||||
|
||||
// display
|
||||
if (ImGuiFileDialog::Instance()->Display("ChooseFileDlgKey")) {
|
||||
// action if OK
|
||||
if (ImGuiFileDialog::Instance()->IsOk()) {
|
||||
std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName();
|
||||
std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath();
|
||||
rom.LoadFromFile(filePathName);
|
||||
overworld_editor_.SetRom(rom);
|
||||
rom_data_ = (void *)rom.GetRawData();
|
||||
}
|
||||
|
||||
// close
|
||||
ImGuiFileDialog::Instance()->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawFileMenu() const {
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
if (ImGui::MenuItem("Open", "Ctrl+O")) {
|
||||
// TODO: Add the ability to open ALTTP ROM
|
||||
ImGuiFileDialog::Instance()->OpenDialog("ChooseFileDlgKey", "Open ROM",
|
||||
".sfc,.smc", ".");
|
||||
}
|
||||
if (ImGui::BeginMenu("Open Recent")) {
|
||||
ImGui::MenuItem("alttp.sfc");
|
||||
// TODO: Display recently accessed files here
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::MenuItem("Save", "Ctrl+S")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
if (ImGui::MenuItem("Save As..")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// TODO: Make these options matter
|
||||
if (ImGui::BeginMenu("Options")) {
|
||||
static bool enabled = true;
|
||||
ImGui::MenuItem("Enabled", "", &enabled);
|
||||
ImGui::BeginChild("child", ImVec2(0, 60), true);
|
||||
for (int i = 0; i < 10; i++) ImGui::Text("Scrolling Text %d", i);
|
||||
ImGui::EndChild();
|
||||
static float f = 0.5f;
|
||||
static int n = 0;
|
||||
ImGui::SliderFloat("Value", &f, 0.0f, 1.0f);
|
||||
ImGui::InputFloat("Input", &f, 0.1f);
|
||||
ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawEditMenu() const {
|
||||
if (ImGui::BeginMenu("Edit")) {
|
||||
if (ImGui::MenuItem("Undo", "Ctrl+Z")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
if (ImGui::MenuItem("Undo", "Ctrl+Y")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Cut", "Ctrl+X")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
if (ImGui::MenuItem("Copy", "Ctrl+C")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
if (ImGui::MenuItem("Paste", "Ctrl+V")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Find", "Ctrl+F")) {
|
||||
// TODO: Implement this
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawViewMenu() {
|
||||
static bool show_imgui_metrics = false;
|
||||
static bool show_imgui_style_editor = false;
|
||||
static bool show_memory_editor = false;
|
||||
static bool show_asm_editor = false;
|
||||
static bool show_imgui_demo = false;
|
||||
|
||||
if (show_imgui_metrics) {
|
||||
ImGui::ShowMetricsWindow(&show_imgui_metrics);
|
||||
}
|
||||
|
||||
if (show_memory_editor) {
|
||||
static MemoryEditor mem_edit;
|
||||
mem_edit.DrawWindow("Memory Editor", rom_data_, rom.getSize());
|
||||
}
|
||||
|
||||
if (show_imgui_demo) {
|
||||
ImGui::ShowDemoWindow();
|
||||
}
|
||||
|
||||
if (show_asm_editor) {
|
||||
static bool asm_is_loaded = false;
|
||||
auto cpos = asm_editor_.GetCursorPosition();
|
||||
static const char *fileToEdit = "assets/bunnyhood.asm";
|
||||
if (!asm_is_loaded) {
|
||||
std::ifstream t(fileToEdit);
|
||||
if (t.good()) {
|
||||
std::string str((std::istreambuf_iterator<char>(t)),
|
||||
std::istreambuf_iterator<char>());
|
||||
asm_editor_.SetText(str);
|
||||
}
|
||||
asm_is_loaded = true;
|
||||
}
|
||||
|
||||
ImGui::Begin("ASM Editor", &show_asm_editor);
|
||||
ImGui::Text("%6d/%-6d %6d lines | %s | %s | %s | %s", cpos.mLine + 1,
|
||||
cpos.mColumn + 1, asm_editor_.GetTotalLines(),
|
||||
asm_editor_.IsOverwrite() ? "Ovr" : "Ins",
|
||||
asm_editor_.CanUndo() ? "*" : " ",
|
||||
asm_editor_.GetLanguageDefinition().mName.c_str(), fileToEdit);
|
||||
|
||||
asm_editor_.Render(fileToEdit);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (show_imgui_style_editor) {
|
||||
ImGui::Begin("Style Editor (ImGui)", &show_imgui_style_editor);
|
||||
ImGui::ShowStyleEditor();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("View")) {
|
||||
ImGui::MenuItem("HEX Editor", nullptr, &show_memory_editor);
|
||||
ImGui::MenuItem("ASM Editor", nullptr, &show_asm_editor);
|
||||
ImGui::MenuItem("ImGui Demo", nullptr, &show_imgui_demo);
|
||||
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu("GUI Tools")) {
|
||||
ImGui::MenuItem("Metrics (ImGui)", nullptr, &show_imgui_metrics);
|
||||
ImGui::MenuItem("Style Editor (ImGui)", nullptr,
|
||||
&show_imgui_style_editor);
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawHelpMenu() const {
|
||||
if (ImGui::BeginMenu("Help")) {
|
||||
if (ImGui::MenuItem("About")) {
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawProjectEditor() {
|
||||
static bool inited = false;
|
||||
|
||||
if (ImGui::BeginTabItem("Project")) {
|
||||
if (ImGui::BeginTable("##projectTable", 2,
|
||||
ImGuiTableFlags_SizingStretchSame)) {
|
||||
ImGui::TableSetupColumn("##inputs");
|
||||
ImGui::TableSetupColumn("##outputs");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Title: %s", rom.getTitle());
|
||||
ImGui::Text("Version: %d", rom.getVersion());
|
||||
ImGui::Text("ROM Size: %ld", rom.getSize());
|
||||
|
||||
ImGui::InputInt("PC Tile Location", ¤t_set_.pcTilesLocation);
|
||||
// 1, 100, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
ImGui::InputScalar("SNES Tile Location", ImGuiDataType_U32,
|
||||
(void *)¤t_set_.SNESTilesLocation);
|
||||
|
||||
ImGui::InputScalar("Tile Preset Length", ImGuiDataType_U32,
|
||||
(void *)¤t_set_.length);
|
||||
|
||||
ImGui::InputScalar("Bits per Pixel", ImGuiDataType_U32,
|
||||
(void *)¤t_set_.bpp);
|
||||
|
||||
ImGui::InputScalar("PC Palette Location", ImGuiDataType_U32,
|
||||
(void *)¤t_set_.pcPaletteLocation);
|
||||
|
||||
ImGui::InputScalar("SNES Palette Location", ImGuiDataType_U32,
|
||||
(void *)¤t_set_.SNESPaletteLocation);
|
||||
|
||||
BASIC_BUTTON("ExtractTiles") {
|
||||
if (rom.isLoaded()) {
|
||||
tiles_ = rom.ExtractTiles(current_set_);
|
||||
}
|
||||
}
|
||||
|
||||
BASIC_BUTTON("BuildSurface") {
|
||||
if (rom.isLoaded()) {
|
||||
current_palette_ = rom.ExtractPalette(current_set_);
|
||||
current_scene_.buildSurface(tiles_, current_palette_,
|
||||
current_set_.tilesPattern);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &[key, texture] : current_scene_.imagesCache) {
|
||||
ImGui::Image((void *)(SDL_Texture *)texture, ImVec2(8, 8));
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
static ImVector<ImVec2> points;
|
||||
static ImVec2 scrolling(0.0f, 0.0f);
|
||||
static bool opt_enable_context_menu = true;
|
||||
static bool opt_enable_grid = true;
|
||||
ImVec2 canvas_p0 = ImGui::GetCursorScreenPos();
|
||||
ImVec2 canvas_sz = ImGui::GetContentRegionAvail();
|
||||
ImVec2 canvas_p1 =
|
||||
ImVec2(canvas_p0.x + canvas_sz.x, canvas_p0.y + canvas_sz.y);
|
||||
|
||||
// Draw border and background color
|
||||
const ImGuiIO &io = ImGui::GetIO();
|
||||
ImDrawList *draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(32, 32, 32, 255));
|
||||
draw_list->AddRect(canvas_p0, canvas_p1, IM_COL32(255, 255, 255, 255));
|
||||
|
||||
// This will catch our interactions
|
||||
ImGui::InvisibleButton(
|
||||
"canvas", canvas_sz,
|
||||
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight);
|
||||
const bool is_hovered = ImGui::IsItemHovered(); // Hovered
|
||||
const bool is_active = ImGui::IsItemActive(); // Held
|
||||
const ImVec2 origin(canvas_p0.x + scrolling.x,
|
||||
canvas_p0.y + scrolling.y); // Lock scrolled origin
|
||||
const ImVec2 mouse_pos_in_canvas(io.MousePos.x - origin.x,
|
||||
io.MousePos.y - origin.y);
|
||||
|
||||
// Pan (we use a zero mouse threshold when there's no context menu)
|
||||
const float mouse_threshold_for_pan =
|
||||
opt_enable_context_menu ? -1.0f : 0.0f;
|
||||
if (is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right,
|
||||
mouse_threshold_for_pan)) {
|
||||
scrolling.x += io.MouseDelta.x;
|
||||
scrolling.y += io.MouseDelta.y;
|
||||
}
|
||||
|
||||
// Context menu (under default mouse threshold)
|
||||
ImVec2 drag_delta = ImGui::GetMouseDragDelta(ImGuiMouseButton_Right);
|
||||
if (opt_enable_context_menu && drag_delta.x == 0.0f &&
|
||||
drag_delta.y == 0.0f)
|
||||
ImGui::OpenPopupOnItemClick("context",
|
||||
ImGuiPopupFlags_MouseButtonRight);
|
||||
if (ImGui::BeginPopup("context")) {
|
||||
ImGui::MenuItem("Placeholder");
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Draw grid + all lines in the canvas
|
||||
draw_list->PushClipRect(canvas_p0, canvas_p1, true);
|
||||
if (opt_enable_grid) {
|
||||
const float GRID_STEP = 64.0f;
|
||||
for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x;
|
||||
x += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y),
|
||||
ImVec2(canvas_p0.x + x, canvas_p1.y),
|
||||
IM_COL32(200, 200, 200, 40));
|
||||
for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y;
|
||||
y += GRID_STEP)
|
||||
draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y),
|
||||
ImVec2(canvas_p1.x, canvas_p0.y + y),
|
||||
IM_COL32(200, 200, 200, 40));
|
||||
}
|
||||
|
||||
if (current_scene_.imagesCache.size() != 0) {
|
||||
for (const auto &[key, value] : current_scene_.imagesCache) {
|
||||
const float GRID_STEP = 8.0f;
|
||||
float x = fmodf(scrolling.x, GRID_STEP);
|
||||
float y = fmodf(scrolling.y, GRID_STEP);
|
||||
draw_list->AddImage((void *)(SDL_Surface *)value,
|
||||
ImVec2(canvas_p0.x + x, canvas_p0.y),
|
||||
ImVec2(canvas_p0.x + x, canvas_p1.y));
|
||||
x += GRID_STEP;
|
||||
if (x == 128) {
|
||||
x = 0;
|
||||
y += GRID_STEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_list->PopClipRect();
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawOverworldEditor() {
|
||||
if (ImGui::BeginTabItem("Overworld")) {
|
||||
overworld_editor_.Update();
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawDungeonEditor() {
|
||||
if (ImGui::BeginTabItem("Dungeon")) {
|
||||
if (ImGui::BeginTable("DWToolset", 9, toolset_table_flags, ImVec2(0, 0))) {
|
||||
ImGui::TableSetupColumn("#undoTool");
|
||||
ImGui::TableSetupColumn("#redoTool");
|
||||
ImGui::TableSetupColumn("#history");
|
||||
ImGui::TableSetupColumn("#separator");
|
||||
ImGui::TableSetupColumn("#bg1Tool");
|
||||
ImGui::TableSetupColumn("#bg2Tool");
|
||||
ImGui::TableSetupColumn("#bg3Tool");
|
||||
ImGui::TableSetupColumn("#itemTool");
|
||||
ImGui::TableSetupColumn("#spriteTool");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_UNDO);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_REDO);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_MANAGE_HISTORY);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text(ICON_MD_MORE_VERT);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_FILTER_1);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_FILTER_2);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_FILTER_3);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_GRASS);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(ICON_MD_PEST_CONTROL_RODENT);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawGraphicsEditor() {
|
||||
if (ImGui::BeginTabItem("Graphics")) {
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawSpriteEditor() {
|
||||
if (ImGui::BeginTabItem("Sprites")) {
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::DrawScreenEditor() {
|
||||
if (ImGui::BeginTabItem("Screens")) {
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
61
src/Application/Editor/editor.h
Normal file
61
src/Application/Editor/editor.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef YAZE_APPLICATION_VIEW_EDITOR_H
|
||||
#define YAZE_APPLICATION_VIEW_EDITOR_H
|
||||
|
||||
#include <ImGuiColorTextEdit/TextEditor.h>
|
||||
#include <ImGuiFileDialog/ImGuiFileDialog.h>
|
||||
#include <imgui/imgui.h>
|
||||
#include <imgui/imgui_memory_editor.h>
|
||||
#include <imgui/misc/cpp/imgui_stdlib.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Core/constants.h"
|
||||
#include "Data/rom.h"
|
||||
#include "Graphics/icons.h"
|
||||
#include "overworld_editor.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Editor {
|
||||
|
||||
class Editor {
|
||||
public:
|
||||
Editor();
|
||||
void UpdateScreen();
|
||||
|
||||
private:
|
||||
void DrawYazeMenu();
|
||||
void DrawFileMenu() const;
|
||||
void DrawEditMenu() const;
|
||||
void DrawViewMenu();
|
||||
void DrawHelpMenu() const;
|
||||
|
||||
void DrawProjectEditor();
|
||||
void DrawOverworldEditor();
|
||||
void DrawDungeonEditor();
|
||||
void DrawGraphicsEditor();
|
||||
void DrawSpriteEditor();
|
||||
void DrawScreenEditor();
|
||||
|
||||
void *rom_data_;
|
||||
bool isLoaded = true;
|
||||
|
||||
Data::ROM rom;
|
||||
TextEditor asm_editor_;
|
||||
TextEditor::LanguageDefinition language65816Def;
|
||||
OverworldEditor overworld_editor_;
|
||||
|
||||
Graphics::Scene current_scene_;
|
||||
Graphics::SNESPalette current_palette_;
|
||||
Graphics::TilePreset current_set_;
|
||||
|
||||
std::vector<tile8> tiles_;
|
||||
|
||||
ImGuiTableFlags toolset_table_flags = ImGuiTableFlags_SizingFixedFit;
|
||||
};
|
||||
|
||||
} // namespace Editor
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APPLICATION_VIEW_EDITOR_H
|
||||
259
src/Application/Graphics/bitmap.cc
Normal file
259
src/Application/Graphics/bitmap.cc
Normal file
@@ -0,0 +1,259 @@
|
||||
#include "Bitmap.h"
|
||||
|
||||
#include "data/rom.h"
|
||||
#include "rommapping.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
int GetPCGfxAddress(char *romData, char id) {
|
||||
char **info1, **info2, **info3, **info4;
|
||||
int gfxPointer1 =
|
||||
lorom_snes_to_pc((romData[Core::Constants::gfx_1_pointer + 1] << 8) +
|
||||
(romData[Core::Constants::gfx_1_pointer]),
|
||||
info1);
|
||||
int gfxPointer2 =
|
||||
lorom_snes_to_pc((romData[Core::Constants::gfx_2_pointer + 1] << 8) +
|
||||
(romData[Core::Constants::gfx_2_pointer]),
|
||||
info2);
|
||||
int gfxPointer3 =
|
||||
lorom_snes_to_pc((romData[Core::Constants::gfx_3_pointer + 1] << 8) +
|
||||
(romData[Core::Constants::gfx_3_pointer]),
|
||||
info3);
|
||||
|
||||
char gfxGamePointer1 = romData[gfxPointer1 + id];
|
||||
char gfxGamePointer2 = romData[gfxPointer2 + id];
|
||||
char gfxGamePointer3 = romData[gfxPointer3 + id];
|
||||
|
||||
return lorom_snes_to_pc(
|
||||
Data::AddressFromBytes(gfxGamePointer1, gfxGamePointer2, gfxGamePointer3),
|
||||
info4);
|
||||
}
|
||||
|
||||
char *CreateAllGfxDataRaw(char *romData) {
|
||||
// 0-112 -> compressed 3bpp bgr -> (decompressed each) 0x600 chars
|
||||
// 113-114 -> compressed 2bpp -> (decompressed each) 0x800 chars
|
||||
// 115-126 -> uncompressed 3bpp sprites -> (each) 0x600 chars
|
||||
// 127-217 -> compressed 3bpp sprites -> (decompressed each) 0x600 chars
|
||||
// 218-222 -> compressed 2bpp -> (decompressed each) 0x800 chars
|
||||
|
||||
char *buffer = new char[346624];
|
||||
int bufferPos = 0;
|
||||
char *data = new char[2048];
|
||||
unsigned int uncompressedSize = 0;
|
||||
unsigned int compressedSize = 0;
|
||||
|
||||
for (int i = 0; i < Core::Constants::NumberOfSheets; i++) {
|
||||
isbpp3[i] = ((i >= 0 && i <= 112) || // Compressed 3bpp bg
|
||||
(i >= 115 && i <= 126) || // Uncompressed 3bpp sprites
|
||||
(i >= 127 && i <= 217) // Compressed 3bpp sprites
|
||||
);
|
||||
|
||||
// uncompressed sheets
|
||||
if (i >= 115 && i <= 126) {
|
||||
data = new char[Core::Constants::Uncompressed3BPPSize];
|
||||
int startAddress = GetPCGfxAddress(romData, (char)i);
|
||||
for (int j = 0; j < Core::Constants::Uncompressed3BPPSize; j++) {
|
||||
data[j] = romData[j + startAddress];
|
||||
}
|
||||
} else {
|
||||
data = alttp_decompress_gfx((char *)romData,
|
||||
GetPCGfxAddress(romData, (char)i),
|
||||
Core::Constants::UncompressedSheetSize,
|
||||
&uncompressedSize, &compressedSize);
|
||||
}
|
||||
|
||||
for (int j = 0; j < sizeof(data); j++) {
|
||||
buffer[j + bufferPos] = data[j];
|
||||
}
|
||||
|
||||
bufferPos += sizeof(data);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void CreateAllGfxData(char *romData, char *allgfx16Ptr) {
|
||||
char *data = CreateAllGfxDataRaw(romData);
|
||||
char *newData =
|
||||
new char[0x6F800]; // NEED TO GET THE APPROPRIATE SIZE FOR THAT
|
||||
unsigned char *mask =
|
||||
new unsigned char[]{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
|
||||
int sheetPosition = 0;
|
||||
|
||||
// 8x8 tile
|
||||
for (int s = 0; s < Core::Constants::NumberOfSheets; s++) // Per Sheet
|
||||
{
|
||||
for (int j = 0; j < 4; j++) // Per Tile Line Y
|
||||
{
|
||||
for (int i = 0; i < 16; i++) // Per Tile Line X
|
||||
{
|
||||
for (int y = 0; y < 8; y++) // Per Pixel Line
|
||||
{
|
||||
if (isbpp3[s]) {
|
||||
char lineBits0 =
|
||||
data[(y * 2) + (i * 24) + (j * 384) + sheetPosition];
|
||||
char lineBits1 =
|
||||
data[(y * 2) + (i * 24) + (j * 384) + 1 + sheetPosition];
|
||||
char lineBits2 =
|
||||
data[(y) + (i * 24) + (j * 384) + 16 + sheetPosition];
|
||||
|
||||
for (int x = 0; x < 4; x++) // Per Pixel X
|
||||
{
|
||||
char pixdata = 0;
|
||||
char pixdata2 = 0;
|
||||
|
||||
if ((lineBits0 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||
pixdata += 1;
|
||||
}
|
||||
if ((lineBits1 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||
pixdata += 2;
|
||||
}
|
||||
if ((lineBits2 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||
pixdata += 4;
|
||||
}
|
||||
|
||||
if ((lineBits0 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||
pixdata2 += 1;
|
||||
}
|
||||
if ((lineBits1 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||
pixdata2 += 2;
|
||||
}
|
||||
if ((lineBits2 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||
pixdata2 += 4;
|
||||
}
|
||||
|
||||
newData[(y * 64) + (x) + (i * 4) + (j * 512) + (s * 2048)] =
|
||||
(char)((pixdata << 4) | pixdata2);
|
||||
}
|
||||
} else {
|
||||
char lineBits0 =
|
||||
data[(y * 2) + (i * 16) + (j * 256) + sheetPosition];
|
||||
char lineBits1 =
|
||||
data[(y * 2) + (i * 16) + (j * 256) + 1 + sheetPosition];
|
||||
|
||||
for (int x = 0; x < 4; x++) // Per Pixel X
|
||||
{
|
||||
char pixdata = 0;
|
||||
char pixdata2 = 0;
|
||||
|
||||
if ((lineBits0 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||
pixdata += 1;
|
||||
}
|
||||
if ((lineBits1 & mask[(x * 2)]) == mask[(x * 2)]) {
|
||||
pixdata += 2;
|
||||
}
|
||||
|
||||
if ((lineBits0 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||
pixdata2 += 1;
|
||||
}
|
||||
if ((lineBits1 & mask[(x * 2) + 1]) == mask[(x * 2) + 1]) {
|
||||
pixdata2 += 2;
|
||||
}
|
||||
|
||||
newData[(y * 64) + (x) + (i * 4) + (j * 512) + (s * 2048)] =
|
||||
(char)((pixdata << 4) | pixdata2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isbpp3[s]) {
|
||||
sheetPosition += Core::Constants::Uncompressed3BPPSize;
|
||||
} else {
|
||||
sheetPosition += Core::Constants::UncompressedSheetSize;
|
||||
}
|
||||
}
|
||||
|
||||
char *allgfx16Data = (char *)allgfx16Ptr;
|
||||
|
||||
for (int i = 0; i < 0x6F800; i++) {
|
||||
allgfx16Data[i] = newData[i];
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap::Bitmap(int width, int height, char *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->charsPerPixel;
|
||||
// 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
|
||||
bool Bitmap::LoadBitmapFromROM(unsigned char *texture_data, GLuint *out_texture,
|
||||
int *out_width, int *out_height) {
|
||||
// Load from file
|
||||
int image_width = 0;
|
||||
int image_height = 0;
|
||||
if (texture_data == NULL) return false;
|
||||
|
||||
// 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);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
||||
GL_CLAMP_TO_EDGE); // This is required on WebGL for non
|
||||
// power-of-two textures
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // Same
|
||||
|
||||
// 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_RGBA, image_width, image_height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, texture_data);
|
||||
|
||||
*out_texture = image_texture;
|
||||
*out_width = image_width;
|
||||
*out_height = image_height;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
43
src/Application/Graphics/bitmap.h
Normal file
43
src/Application/Graphics/bitmap.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef YAZE_APPLICATION_UTILS_BITMAP_H
|
||||
#define YAZE_APPLICATION_UTILS_BITMAP_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL_opengl.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "Core/Constants.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
class Bitmap {
|
||||
public:
|
||||
Bitmap() = default;
|
||||
Bitmap(int width, int height, char *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_;
|
||||
char *pixel_data_;
|
||||
};
|
||||
|
||||
static bool isbpp3[Core::Constants::NumberOfSheets];
|
||||
|
||||
int GetPCGfxAddress(char *romData, char id);
|
||||
char *CreateAllGfxDataRaw(char *romData);
|
||||
void CreateAllGfxData(char *romData, char *allgfx16Ptr);
|
||||
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
2192
src/Application/Graphics/icons.h
Normal file
2192
src/Application/Graphics/icons.h
Normal file
File diff suppressed because it is too large
Load Diff
102
src/Application/Graphics/palette.cc
Normal file
102
src/Application/Graphics/palette.cc
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "Palette.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
SNESColor::SNESColor() {
|
||||
rgb = ImVec4(0.f, 0.f, 0.f, 0.f);
|
||||
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) {
|
||||
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::setSNES(uint16_t val) {
|
||||
snes = val;
|
||||
m_color col = convertcolor_snes_to_rgb(val);
|
||||
rgb = ImVec4(col.red, col.green, col.blue, 1.f);
|
||||
}
|
||||
|
||||
SNESPalette::SNESPalette() { size = 0; }
|
||||
|
||||
SNESPalette::SNESPalette(uint8_t mSize) {
|
||||
size = mSize;
|
||||
for (unsigned int i = 0; i < mSize; i++) {
|
||||
SNESColor col;
|
||||
colors.push_back(col);
|
||||
}
|
||||
}
|
||||
|
||||
SNESPalette::SNESPalette(char* data) {
|
||||
assert((sizeof(data) % 4 == 0) && (sizeof(data) <= 32));
|
||||
size = sizeof(data) / 2;
|
||||
for (unsigned i = 0; i < sizeof(data); i += 2) {
|
||||
SNESColor col;
|
||||
col.snes = static_cast<uchar>(data[i + 1]) << 8;
|
||||
col.snes = col.snes | static_cast<uchar>(data[i]);
|
||||
m_color mColor = convertcolor_snes_to_rgb(col.snes);
|
||||
col.rgb = ImVec4(mColor.red, mColor.green, mColor.blue, 1.f);
|
||||
colors.push_back(col);
|
||||
}
|
||||
}
|
||||
|
||||
SNESPalette::SNESPalette(std::vector<ImVec4> cols) {
|
||||
// foreach (ImVec4 col, cols) {
|
||||
// SNESColor scol;
|
||||
// scol.setRgb(col);
|
||||
// colors.push_back(scol);
|
||||
// }
|
||||
// size = cols.size();
|
||||
}
|
||||
|
||||
char* SNESPalette::encode() {
|
||||
// char* data(size * 2, 0);
|
||||
char* data = new char[size * 2];
|
||||
for (unsigned int i = 0; i < size; i++) {
|
||||
// std::cout << QString::number(colors[i].snes, 16);
|
||||
data[i * 2] = (char)(colors[i].snes & 0xFF);
|
||||
data[i * 2 + 1] = (char)(colors[i].snes >> 8);
|
||||
}
|
||||
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 Application
|
||||
} // namespace yaze
|
||||
48
src/Application/Graphics/palette.h
Normal file
48
src/Application/Graphics/palette.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef YAZE_APPLICATION_GRAPHICS_PALETTE_H
|
||||
#define YAZE_APPLICATION_GRAPHICS_PALETTE_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <imgui/imgui.h>
|
||||
#include <palette.h>
|
||||
#include <tile.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
struct SNESColor {
|
||||
SNESColor();
|
||||
SNESColor(ImVec4);
|
||||
uint16_t snes;
|
||||
ImVec4 rgb;
|
||||
void setRgb(ImVec4);
|
||||
void setSNES(uint16_t);
|
||||
uint8_t approxSNES();
|
||||
ImVec4 approxRGB();
|
||||
};
|
||||
|
||||
class SNESPalette {
|
||||
public:
|
||||
SNESPalette();
|
||||
SNESPalette(uint8_t mSize);
|
||||
SNESPalette(char* snesPal);
|
||||
SNESPalette(std::vector<ImVec4>);
|
||||
|
||||
char* encode();
|
||||
SDL_Palette* GetSDL_Palette();
|
||||
|
||||
uint8_t size;
|
||||
std::vector<SNESColor> colors;
|
||||
std::vector<SDL_Palette*> sdl_palettes_;
|
||||
std::vector<SDL_Color*> colors_arrays_;
|
||||
};
|
||||
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_APPLICATION_GRAPHICS_PALETTE_H
|
||||
104
src/Application/Graphics/scene.cc
Normal file
104
src/Application/Graphics/scene.cc
Normal file
@@ -0,0 +1,104 @@
|
||||
#include "Scene.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
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,
|
||||
const 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];
|
||||
// QImage newImage(8, 8, QImage::Format_Indexed8);
|
||||
// newImage.setColorCount(mPalette.size);
|
||||
// for (int i = 0; i < mPalette.size; i++) {
|
||||
// newImage.setColor(i, mPalette.colors.at(i).rgb);
|
||||
// }
|
||||
// for (int i = 0; i < 8; i++) {
|
||||
// for (int j = 0; j < 8; j++)
|
||||
// newImage.setPixel(i, j, tile.data[i + j * 8]);
|
||||
// }
|
||||
// QPixmap m;
|
||||
// m.convertFromImage(newImage);
|
||||
// imagesCache[tile.id] = m;
|
||||
// GraphicsTileItem *newTileItem = new GraphicsTileItem(m, tile);
|
||||
// addItem(newTileItem);
|
||||
// newTileItem->setTileZoom(tilesZoom);
|
||||
// newTileItem->setPos(i * newTileItem->boundingRect().width() + i,
|
||||
// j * newTileItem->boundingRect().width() + j);
|
||||
}
|
||||
}
|
||||
// unsigned max_w = items()[0]->boundingRect().width() *
|
||||
// arrangedTiles[0].size() + arrangedTiles[0].size(); unsigned max_h =
|
||||
// items()[0]->boundingRect().width() * arrangedTiles.size() +
|
||||
// arrangedTiles.size(); setSceneRect(QRect(0, 0, max_w, max_h));
|
||||
}
|
||||
|
||||
void Scene::updateScene() {
|
||||
std::cout << "Update scene";
|
||||
unsigned int itemCpt = 0;
|
||||
for (unsigned int j = 0; j < arrangedTiles.size(); j++) {
|
||||
for (unsigned int i = 0; i < arrangedTiles[0].size(); i++) {
|
||||
tile8 tile = arrangedTiles[j][i];
|
||||
// QPixmap m = imagesCache[tile.id];
|
||||
// GraphicsTileItem *tileItem = (GraphicsTileItem *)items()[itemCpt];
|
||||
// tileItem->image = m;
|
||||
// tileItem->rawTile = tile;
|
||||
// tileItem->setTileZoom(tilesZoom);
|
||||
// tileItem->setPos(i * tileItem->boundingRect().width() + i,
|
||||
// j * tileItem->boundingRect().width() + j);
|
||||
itemCpt++;
|
||||
}
|
||||
}
|
||||
// unsigned max_w =
|
||||
// items()[0]->boundingRect().width() * arrangedTiles[0].size() +
|
||||
// arrangedTiles[0].size();
|
||||
// unsigned max_h = items()[0]->boundingRect().width() * arrangedTiles.size()
|
||||
// +
|
||||
// arrangedTiles.size();
|
||||
// setSceneRect(QRect(0, 0, max_w, max_h));
|
||||
}
|
||||
|
||||
void Scene::setTilesZoom(unsigned int tileZoom) {
|
||||
tilesZoom = tileZoom;
|
||||
// if (!items().isEmpty()) updateScene();
|
||||
}
|
||||
|
||||
void Scene::setTilesPattern(TilesPattern tp) { tilesPattern = tp; }
|
||||
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
44
src/Application/Graphics/scene.h
Normal file
44
src/Application/Graphics/scene.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef YAZE_APPLICATION_GRAPHICS_SCENE_H
|
||||
#define YAZE_APPLICATION_GRAPHICS_SCENE_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <tile.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "Core/Renderer.h"
|
||||
#include "graphics/tile.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
class Scene {
|
||||
public:
|
||||
Scene() = default;
|
||||
void buildScene(const std::vector<tile8>& tiles, const SNESPalette mPalette,
|
||||
const TilesPattern& tp);
|
||||
|
||||
void buildSurface(const std::vector<tile8>& tiles,
|
||||
SNESPalette& mPalette, const TilesPattern& tp);
|
||||
|
||||
void updateScene();
|
||||
void setTilesZoom(unsigned int tileZoom);
|
||||
void setTilesPattern(TilesPattern tp);
|
||||
|
||||
std::unordered_map<unsigned int, SDL_Texture*> imagesCache;
|
||||
|
||||
private:
|
||||
unsigned int tilesZoom;
|
||||
TilesPattern tilesPattern;
|
||||
std::vector<tile8> allTiles;
|
||||
std::vector<std::vector<tile8> > arrangedTiles;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
19
src/Application/Graphics/style.h
Normal file
19
src/Application/Graphics/style.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef YAZE_APPLICATION_CORE_STYLE_H
|
||||
#define YAZE_APPLCIATION_CORE_STYLE_H
|
||||
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/imgui_internal.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Core {
|
||||
namespace Style {
|
||||
|
||||
void ColorsYaze();
|
||||
|
||||
} // namespace Style
|
||||
} // namespace Core
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
219
src/Application/Graphics/tile.cc
Normal file
219
src/Application/Graphics/tile.cc
Normal file
@@ -0,0 +1,219 @@
|
||||
#include "Tile.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
TilesPattern::TilesPattern() {
|
||||
tilesPerRow = 16;
|
||||
numberOfTiles = 16;
|
||||
// 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>{4, 5, 6, 7});
|
||||
transformVector.push_back(std::vector<int>{8, 9, 11, 12});
|
||||
transformVector.push_back(std::vector<int>{13, 14, 15, 16});
|
||||
}
|
||||
|
||||
// [pattern]
|
||||
// name = "32x32 B (4x4)"
|
||||
// number_of_tile = 16
|
||||
// pattern =
|
||||
void TilesPattern::default_settings() {
|
||||
numberOfTiles = 16;
|
||||
std::string patternString =
|
||||
"[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, A, B], [C, D, E, F]";
|
||||
|
||||
transformVector.clear();
|
||||
|
||||
std::smatch cm;
|
||||
std::regex arrayRegExp("(\\[[\\s|0-F|a-f|,]+\\])");
|
||||
|
||||
int pos = 0;
|
||||
while (std::regex_search(patternString, cm, arrayRegExp)) {
|
||||
// while (arrayRegExp.indexIn(patternString, pos) != -1) {
|
||||
std::string arrayString = cm[1];
|
||||
std::vector<int> tmpVect;
|
||||
// std::cout << arrayString;
|
||||
unsigned int stringPos = 1;
|
||||
|
||||
while (arrayString[stringPos] != ']') {
|
||||
while (arrayString[stringPos] == ' ') stringPos++;
|
||||
std::smatch cm_;
|
||||
std::regex hex("([0-F|a-f]+)");
|
||||
bool ok;
|
||||
|
||||
std::regex_search(arrayString, cm, hex);
|
||||
if (cm[1] == stringPos) {
|
||||
std::cout << "here" << std::endl;
|
||||
// tmpVect.push_back(stoi(cm[1]));
|
||||
}
|
||||
while (arrayString[stringPos] == ' ') stringPos++;
|
||||
stringPos++; // should be the comma
|
||||
}
|
||||
|
||||
pos += cm.size();
|
||||
transformVector.push_back(tmpVect);
|
||||
}
|
||||
std::cout << transformVector.size() << std::endl;
|
||||
}
|
||||
|
||||
std::vector<std::vector<tile8> > TilesPattern::transform(
|
||||
const std::vector<tile8> &tiles) const {
|
||||
unsigned int repeatOffsetY = 0;
|
||||
unsigned int repeatOffsetX = 0;
|
||||
unsigned int tVectHeight = transformVector.size();
|
||||
unsigned int tVectWidth = transformVector[0].size();
|
||||
unsigned int repeat = 0;
|
||||
std::vector<std::vector<tile8> > toret;
|
||||
unsigned int transPerRow = tilesPerRow / tVectWidth;
|
||||
unsigned int nbTransform = tiles.size() / numberOfTiles;
|
||||
printf("Tiles size : %d\nnbtransform : %d\npattern number of tiles : %d\n",
|
||||
tiles.size(), nbTransform, numberOfTiles);
|
||||
|
||||
if (transPerRow > nbTransform)
|
||||
toret.resize(tVectHeight);
|
||||
else
|
||||
toret.resize(
|
||||
((unsigned int)(((double)nbTransform / (double)transPerRow) + 0.5)) *
|
||||
tVectHeight);
|
||||
|
||||
for (auto &each : toret) {
|
||||
each.resize(tilesPerRow);
|
||||
}
|
||||
|
||||
std::cout << toret[0].size() << " x " << toret.size();
|
||||
while (repeat != nbTransform) {
|
||||
std::cout << "repeat" << repeat;
|
||||
for (unsigned int j = 0; j < tVectHeight; j++) {
|
||||
for (unsigned int i = 0; i < tVectWidth; i++) {
|
||||
unsigned int posTile = transformVector[j][i] + numberOfTiles * repeat;
|
||||
unsigned int posX = i + repeatOffsetX;
|
||||
unsigned int posY = j + repeatOffsetY;
|
||||
printf("X: %d - Y: %d - posTile : %d", posX, posY, posTile);
|
||||
// toret[posY][posX] = tiles[posTile];
|
||||
toret.at(posY).at(posX) = tiles[posTile];
|
||||
}
|
||||
}
|
||||
if (repeatOffsetX + tVectWidth == tilesPerRow) {
|
||||
repeatOffsetX = 0;
|
||||
repeatOffsetY += tVectHeight;
|
||||
} else
|
||||
repeatOffsetX += tVectWidth;
|
||||
repeat++;
|
||||
}
|
||||
std::cout << "End of transform";
|
||||
return toret;
|
||||
}
|
||||
|
||||
std::vector<tile8> TilesPattern::reverse(
|
||||
const std::vector<tile8> &tiles) const {
|
||||
unsigned int repeatOffsetY = 0;
|
||||
unsigned int repeatOffsetX = 0;
|
||||
unsigned int tVectHeight = transformVector.size();
|
||||
unsigned int tVectWidth = transformVector[0].size();
|
||||
unsigned int repeat = 0;
|
||||
unsigned int nbTransPerRow = tilesPerRow / tVectWidth;
|
||||
unsigned int nbTiles = tiles.size();
|
||||
std::vector<tile8> toretVec(tiles.size());
|
||||
|
||||
for (unsigned int i = 0; i < nbTiles; i++) {
|
||||
unsigned int lineNb = i / tilesPerRow;
|
||||
unsigned int lineInTab = lineNb % tVectHeight;
|
||||
unsigned int colInTab = i % tVectWidth;
|
||||
unsigned int tileNb = transformVector[lineInTab][colInTab];
|
||||
|
||||
unsigned int lineBlock = i / (nbTransPerRow * numberOfTiles);
|
||||
unsigned int blockNB =
|
||||
(i % (nbTransPerRow * numberOfTiles) % tilesPerRow) / tVectWidth;
|
||||
|
||||
// std::cout << colInTab << lineInTab << " = " << tileNb;
|
||||
// unsigned int pos = tileNb + ((i % tilesPerRow) / nbTransPerRow) *
|
||||
// numberOfTiles;
|
||||
unsigned int pos = tileNb + (lineBlock + blockNB) * numberOfTiles;
|
||||
// std::cout << i << "Goes to : " << pos;
|
||||
toretVec[pos] = tiles[i];
|
||||
}
|
||||
return toretVec;
|
||||
}
|
||||
|
||||
std::vector<std::vector<tile8> > TilesPattern::transform(
|
||||
const TilesPattern &pattern, const std::vector<tile8> &tiles) {
|
||||
return pattern.transform(tiles);
|
||||
}
|
||||
|
||||
TilePreset::TilePreset() {
|
||||
pcTilesLocation = -1;
|
||||
SNESTilesLocation = 0;
|
||||
length = 0;
|
||||
bpp = 0;
|
||||
compression = "None";
|
||||
pcPaletteLocation = 0;
|
||||
SNESPaletteLocation = 0;
|
||||
paletteNoZeroColor = false;
|
||||
}
|
||||
|
||||
bool TilePreset::save(const std::string &file) {
|
||||
// QSettings pFile(file, QSettings::IniFormat);
|
||||
|
||||
// if (pFile.isWritable() == false)
|
||||
// return false;
|
||||
|
||||
// pFile.setValue("_/name", name);
|
||||
// pFile.setValue("rom/name", romName);
|
||||
// pFile.setValue("rom/type", romType);
|
||||
|
||||
// pFile.setValue("tiles/pc_location", QString::number(pcTilesLocation, 16));
|
||||
// pFile.setValue("tiles/snes_location", QString::number(SNESTilesLocation,
|
||||
// 16)); pFile.setValue("tiles/length", length); pFile.setValue("tiles/bpp",
|
||||
// bpp); pFile.setValue("tiles/compression", compression);
|
||||
// pFile.setValue("tiles/pattern", tilesPattern.name);
|
||||
|
||||
// pFile.setValue("palette/pc_location", QString::number(pcPaletteLocation,
|
||||
// 16)); pFile.setValue("palette/snes_location",
|
||||
// QString::number(SNESPaletteLocation, 16));
|
||||
// pFile.setValue("palette/nozerocolor", paletteNoZeroColor);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TilePreset::load(const std::string &file) {
|
||||
// QSettings pFile(file, QSettings::IniFormat);
|
||||
|
||||
// /* Meh solution to know if the file is right*/
|
||||
// if (pFile.value("_/name").toString().isEmpty())
|
||||
// return false;
|
||||
// name = pFile.value("_/name").toString();
|
||||
// romName = pFile.value("rom/name").toString();
|
||||
// romType = pFile.value("rom/type").toString();
|
||||
|
||||
// /* Locations are stored in a hex string */
|
||||
// bool ok;
|
||||
// pcTilesLocation = pFile.value("tiles/pc_location").toString().toUInt(&ok,
|
||||
// 16); SNESTilesLocation =
|
||||
// pFile.value("tiles/snes_location").toString().toUInt(&ok, 16); length =
|
||||
// pFile.value("tiles/length").toInt(); bpp =
|
||||
// pFile.value("tiles/bpp").toInt(); compression =
|
||||
// pFile.value("tiles/compression").toString(); QString patternName =
|
||||
// pFile.value("tiles/pattern").toString(); if (patternName.isEmpty())
|
||||
// patternName = "normal";
|
||||
// tilesPattern = TilesPattern::pattern(patternName);
|
||||
|
||||
// pcPaletteLocation =
|
||||
// pFile.value("palette/pc_location").toString().toUInt(&ok, 16);
|
||||
// SNESPaletteLocation =
|
||||
// pFile.value("palette/snes_location").toString().toUInt(&ok, 16);
|
||||
// paletteNoZeroColor = pFile.value("palette/nozerocolor").toBool();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
112
src/Application/Graphics/tile.h
Normal file
112
src/Application/Graphics/tile.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef YAZE_APPLICATION_DATA_TILE_H
|
||||
#define YAZE_APPLICATION_DATA_TILE_H
|
||||
|
||||
#include <tile.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Palette.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace Application {
|
||||
namespace Graphics {
|
||||
|
||||
using byte = unsigned char;
|
||||
using ushort = unsigned short;
|
||||
using uint = unsigned int;
|
||||
|
||||
// vhopppcc cccccccc
|
||||
// [0, 1]
|
||||
// [2, 3]
|
||||
class TileInfo {
|
||||
public:
|
||||
ushort id_;
|
||||
ushort over_;
|
||||
ushort vertical_mirror_;
|
||||
ushort horizontal_mirror_;
|
||||
byte palette_;
|
||||
TileInfo() {}
|
||||
TileInfo(ushort id, byte palette, ushort v, ushort h, ushort o)
|
||||
: id_(id),
|
||||
palette_(palette),
|
||||
vertical_mirror_(v),
|
||||
horizontal_mirror_(h),
|
||||
over_(o) {}
|
||||
};
|
||||
|
||||
class Tile32 {
|
||||
public:
|
||||
ushort tile0_;
|
||||
ushort tile1_;
|
||||
ushort tile2_;
|
||||
ushort tile3_;
|
||||
|
||||
Tile32(ushort t0, ushort t1, ushort t2, ushort t3)
|
||||
: tile0_(t0), tile1_(t1), tile2_(t2), tile3_(t3) {}
|
||||
};
|
||||
|
||||
class Tile16 {
|
||||
public:
|
||||
TileInfo tile0_;
|
||||
TileInfo tile1_;
|
||||
TileInfo tile2_;
|
||||
TileInfo tile3_;
|
||||
std::vector<TileInfo> tiles_info;
|
||||
|
||||
Tile16(TileInfo t0, TileInfo t1, TileInfo t2, TileInfo t3)
|
||||
: tile0_(t0), tile1_(t1), tile2_(t2), tile3_(t3) {
|
||||
tiles_info.push_back(tile0_);
|
||||
tiles_info.push_back(tile1_);
|
||||
tiles_info.push_back(tile2_);
|
||||
tiles_info.push_back(tile3_);
|
||||
}
|
||||
};
|
||||
|
||||
class TilesPattern {
|
||||
public:
|
||||
TilesPattern();
|
||||
std::string name;
|
||||
std::string description;
|
||||
bool custom;
|
||||
unsigned int tilesPerRow;
|
||||
unsigned int numberOfTiles;
|
||||
|
||||
void default_settings();
|
||||
|
||||
static TilesPattern pattern(std::string name);
|
||||
static std::vector<std::vector<tile8> > transform(
|
||||
const TilesPattern& pattern, const std::vector<tile8>& tiles);
|
||||
|
||||
protected:
|
||||
std::vector<std::vector<tile8> > transform(
|
||||
const std::vector<tile8>& tiles) const;
|
||||
std::vector<tile8> reverse(const std::vector<tile8>& tiles) const;
|
||||
std::vector<std::vector<int> > transformVector;
|
||||
};
|
||||
|
||||
class TilePreset {
|
||||
public:
|
||||
TilePreset();
|
||||
|
||||
bool save(const std::string& file);
|
||||
bool load(const std::string& file);
|
||||
|
||||
bool paletteNoZeroColor;
|
||||
int pcTilesLocation;
|
||||
uint16_t SNESTilesLocation;
|
||||
uint16_t SNESPaletteLocation;
|
||||
uint32_t pcPaletteLocation;
|
||||
uint32_t length;
|
||||
uint32_t bpp;
|
||||
|
||||
TilesPattern tilesPattern;
|
||||
std::string compression;
|
||||
};
|
||||
|
||||
} // namespace Graphics
|
||||
} // namespace Application
|
||||
} // namespace yaze
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user