more lowercase stuff

This commit is contained in:
Justin Scofield
2022-06-12 20:22:45 -04:00
parent 1822a07e6f
commit a5e1f0fa83
23 changed files with 5848 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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
View 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

View 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

View 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", &current_set_.pcTilesLocation);
// 1, 100, ImGuiInputTextFlags_CharsHexadecimal);
ImGui::InputScalar("SNES Tile Location", ImGuiDataType_U32,
(void *)&current_set_.SNESTilesLocation);
ImGui::InputScalar("Tile Preset Length", ImGuiDataType_U32,
(void *)&current_set_.length);
ImGui::InputScalar("Bits per Pixel", ImGuiDataType_U32,
(void *)&current_set_.bpp);
ImGui::InputScalar("PC Palette Location", ImGuiDataType_U32,
(void *)&current_set_.pcPaletteLocation);
ImGui::InputScalar("SNES Palette Location", ImGuiDataType_U32,
(void *)&current_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

View 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

View 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

View 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

File diff suppressed because it is too large Load Diff

View 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

View 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

View 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

View 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

View 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

View 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

View 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