Skip to content

Commit

Permalink
First implementation for Fonline2D format tools
Browse files Browse the repository at this point in the history
  • Loading branch information
APAmk2 committed Aug 26, 2024
1 parent dbef316 commit 37b761b
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 92 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ find_package(SDL2 REQUIRED)
find_package(OpenGL REQUIRED)
set(SDL2_LIBRARY "${SDL2_LIBDIR}/SDL2.lib;${SDL2_LIBDIR}/SDL2main.lib")

add_executable (FORT WIN32 "FORT/main.cpp" "3rdparty/lodepng/lodepng.cpp" "FORT/ByteReader.cpp" "FORT/Fonline/foart.cpp" ${IMGUI_INCLUDE})
add_executable (FORT "FORT/main.cpp" "3rdparty/lodepng/lodepng.cpp" "FORT/ByteReader.cpp" "FORT/Fonline/foart.cpp" ${IMGUI_INCLUDE})
set_property(TARGET FORT PROPERTY CXX_STANDARD 20)
add_custom_command(TARGET FORT POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${SDL2_LIBDIR}/SDL2.dll" $<TARGET_FILE_DIR:FORT>)

include_directories(FORT ${SDL2_INCLUDE_DIR} ${IMGUI_PATH} ${IMGUI_PATH}/backends ${IMGUI_PATH}/misc/cpp)
include_directories(FORT ${SDL2_INCLUDE_DIR} ${IMGUI_PATH} ${IMGUI_PATH}/backends ${IMGUI_PATH}/misc/cpp 3rdparty/lodepng)
target_link_libraries(FORT ${SDL2_LIBRARY} ${OPENGL_LIBRARIES})
169 changes: 121 additions & 48 deletions FORT/Fonline/foart.cpp
Original file line number Diff line number Diff line change
@@ -1,45 +1,31 @@
#include "foart.h"
#include "SDL_opengl.h"
#include "lodepng.h"
#include <stdio.h>

using namespace std;

void file_t::read(ByteReader* reader)
{
check_num1 = reader->u8();
if (check_num1 != 42) return;
hdr_t newHdr;
newHdr.read(reader);
hdr = newHdr;

for (size_t i = 0; i < hdr.dirs; i++)
{
data_t currData;
currData.hdr_ptr = &hdr;
currData.read(reader);
data.push_back(currData);
}
}
#define DIRS_COUNT 6

void hdr_t::read(ByteReader* reader)
hdr_t::hdr_t(ByteReader* reader)
{
frames_count = reader->u16();
anim_ticks = reader->u16();
dirs = reader->u8();
}

void data_t::read(ByteReader* reader)
data_t::data_t(ByteReader* reader, hdr_t* hdr_ptr)
{
offs_x = reader->i16();
offs_y = reader->i16();
for (size_t i = 0; i < hdr_ptr->frames_count; i++)
{
frame_t currFrame;
currFrame.read(reader);
frame_t currFrame(reader);
frames.push_back(currFrame);
}
}

void frame_t::read(ByteReader* reader)
frame_t::frame_t(ByteReader* reader)
{
is_shared = reader->u8() > 0;
if(!is_shared)
Expand All @@ -60,46 +46,133 @@ void frame_t::read(ByteReader* reader)
}
}

void oldfile_t::read(ByteReader* reader)
Fo2D_t::Fo2D_t(ByteReader* reader)
{
width = reader->u32();
height = reader->u32();
if(width == 1196314761) return;
for (size_t i = 0, len = width * height; i < len; i++)
uint8_t check_num = reader->u8();
reader->Pos(0);
uint32_t animSign = reader->u32();
reader->Pos(1);
if(check_num == 42 && animSign != 0xDEADBEEF)
{
ucolor currPixel{ reader->u8(), reader->u8(), reader->u8(), reader->u8() };
pixels.push_back(currPixel);
hdr = new hdr_t(reader);

for (size_t i = 0; i < hdr->dirs; i++)
{
data_t currData(reader, hdr);
data.push_back(currData);
}
}
else if(check_num != 137 && animSign != 0xDEADBEEF)
{
reader->Pos(0);

hdr = new hdr_t;
hdr->frames_count = 1;
hdr->anim_ticks = 1;
hdr->dirs = 1;

data_t newData;
newData.hdr_ptr = hdr;

frame_t newFrame;
newFrame.width = reader->u32();
newFrame.height = reader->u32();
//if (newFrame.width == 1196314761) return;
for (size_t i = 0, len = newFrame.width * newFrame.height; i < len; i++)
{
ucolor currPixel{ reader->u8(), reader->u8(), reader->u8(), reader->u8() };
newFrame.pixels.push_back(currPixel);
}
newData.frames.push_back(newFrame);
data.push_back(newData);
}
else if (animSign == 0xDEADBEEF)
{
reader->Pos(4);
hdr = new hdr_t;
hdr->frames_count = reader->u16();
hdr->anim_ticks = reader->u32();
hdr->dirs = reader->u16();

for (uint16_t dir = 0; dir < hdr->dirs; dir++)
{
data_t newData;
newData.hdr_ptr = hdr;
for (uint16_t i = 0; i < hdr->frames_count; i++)
{
frame_t newFrame;
newFrame.width = reader->u16();
newFrame.height = reader->u16();
newData.offs_x = reader->u16();
newData.offs_y = reader->u16();
newFrame.next_x = reader->u16();
newFrame.next_y = reader->u16();

for (size_t i = 0, len = newFrame.width * newFrame.height; i < len; i++)
{
ucolor currPixel{ reader->u8(), reader->u8(), reader->u8(), reader->u8() };
newFrame.pixels.push_back(currPixel);
}
}
}
}
}

bool decodeFonline2D(filesystem::path& filename, int& width, int& height)
int frameCounter = 0;

bool readFonline2D(std::filesystem::path& filename, Fo2D_t*& file)
{
delete file;
file = nullptr;
frameCounter = 0;
ByteReader* reader = new ByteReader;
if(!reader->Reset(filename.string(), ByteReader::BigEndian)) return false;
file_t file;
file.read(reader);
if (!reader->Reset(filename.string(), ByteReader::BigEndian)) return false;
file = new Fo2D_t(reader);
file->filename = filename.stem().string();
reader->Close();
delete reader;

if (file.check_num1 != 42) return false;
return true;
}

frame_t* currFrame_ptr = &file.data[0].frames[0];
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, currFrame_ptr->width, currFrame_ptr->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &currFrame_ptr->pixels[0]);
width = currFrame_ptr->width;
height = currFrame_ptr->height;
void exportFonline2D(Fo2D_t*& file)
{
for (size_t currData = 0; currData < file->hdr->dirs; currData++)
{
for (size_t currFrame = 0; currFrame < file->hdr->frames_count; currFrame++)
{
frame_t* currFrame_ptr = &file->data[currData].frames[currFrame];
std::vector<unsigned char> image;

int width = currFrame_ptr->width;
int height = currFrame_ptr->height;
image.resize(width * height * 4);
for (size_t i = 0; i < width * height; i++)
{
image[i * 4] = currFrame_ptr->pixels[i].r;
image[i * 4 + 1] = currFrame_ptr->pixels[i].g;
image[i * 4 + 2] = currFrame_ptr->pixels[i].b;
image[i * 4 + 3] = currFrame_ptr->pixels[i].a;
}

return true;
unsigned error = lodepng::encode((file->filename + "_" + to_string(currData) + "_" + to_string(currFrame)) + ".png", image, width, height);
if (error) std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl;
}
}
}

void decodeOldFonline2D(filesystem::path& filename, int& width, int& height)
bool renderFonline2D(Fo2D_t* file, int& width, int& height, int& dir)
{
ByteReader* reader = new ByteReader;
if(!reader->Reset(filename.string(), ByteReader::BigEndian)) return;
oldfile_t file;
file.read(reader);
reader->Close();
if (file.width == 1196314761) return;
frame_t* currFrame_ptr = &file->data[dir].frames[frameCounter];
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, currFrame_ptr->width, currFrame_ptr->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &currFrame_ptr->pixels[0]);
width = currFrame_ptr->width;
height = currFrame_ptr->height;

frameCounter++;
if (frameCounter >= file->data[dir].frames.size())
{
frameCounter = 0;
}

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, file.width, file.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &file.pixels[0]);
width = file.width;
height = file.height;
return true;
}
59 changes: 28 additions & 31 deletions FORT/Fonline/foart.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "ByteReader.hpp"
#include <vector>
#include <filesystem>
#include <string>

struct ucolor
{
Expand All @@ -15,57 +16,53 @@ struct ucolor
class frame_t
{
public:
bool is_shared;
uint16_t width;
uint16_t height;
int16_t next_x;
int16_t next_y;
bool is_shared = false;
uint16_t width = 0;
uint16_t height = 0;
int16_t next_x = 0;
int16_t next_y = 0;
std::vector<ucolor> pixels;
uint16_t shared_indx;
uint16_t shared_indx = 0;

void read(ByteReader* reader);
frame_t(ByteReader* reader);
frame_t() {};
};

class hdr_t
{
public:
uint16_t frames_count;
uint16_t anim_ticks;
uint8_t dirs;
uint16_t frames_count = 0;
uint16_t anim_ticks = 0;
uint8_t dirs = 0;

void read(ByteReader* reader);
hdr_t(ByteReader* reader);
hdr_t() {};
};

class data_t
{
public:
hdr_t* hdr_ptr;
int16_t offs_x;
int16_t offs_y;
hdr_t* hdr_ptr = nullptr;
int16_t offs_x = 0;
int16_t offs_y = 0;
std::vector<frame_t> frames;

void read(ByteReader* reader);
data_t(ByteReader* reader, hdr_t* hdr_ptr);
data_t() {};
};

class file_t
class Fo2D_t
{
public:
uint8_t check_num1;
hdr_t hdr;
hdr_t* hdr = nullptr;
std::vector<data_t> data;
std::string filename = "";

void read(ByteReader* reader);
Fo2D_t(ByteReader* reader);
};

class oldfile_t // Old file format, only for FO2 graphics support - APAMk2
{
public:
uint32_t width;
uint32_t height;
std::vector<ucolor> pixels;

void read(ByteReader* reader);
};

bool decodeFonline2D(std::filesystem::path& filename, int& width, int& height);
void decodeOldFonline2D(std::filesystem::path& filename, int& width, int& height);
bool readFonline2D(std::filesystem::path& filename, Fo2D_t*& file);
void exportFonline2D(Fo2D_t*& file);
bool renderFonline2D(Fo2D_t* file, int& width, int& height, int& dir);
//bool readOldFonline2D(std::filesystem::path& filename, oldfile_t*& file);
//void renderOldFonline2D(oldfile_t* file, int& width, int& height);
Loading

0 comments on commit 37b761b

Please sign in to comment.