wip packer

This commit is contained in:
Nishi 2026-05-29 07:58:06 +09:00
commit 1ffea4df0d
7 changed files with 150 additions and 3 deletions

View file

@ -18,7 +18,7 @@ int main(){
signal(SIGTERM, cleanup); signal(SIGTERM, cleanup);
#endif #endif
wnd = new fishbone::Window("Fishbowl", 640, 480); wnd = new fishbone::Window("Fishbowl", 800, 600);
while(!quit); while(!quit);
} }

View file

@ -15,7 +15,6 @@ if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CPM.cmake")
message(FATAL_ERROR "Failed to download CPM.cmake: ${status}\n${log_content}") message(FATAL_ERROR "Failed to download CPM.cmake: ${status}\n${log_content}")
endif() endif()
endif() endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CPM.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/util.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/util.cmake")
file(GLOB_RECURSE SRCS src/**.cc src/**.c) file(GLOB_RECURSE SRCS src/**.cc src/**.c)
@ -69,3 +68,6 @@ if(FISHBONE_BUILD_TESTS)
enable_testing() enable_testing()
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()
# Tools
add_subdirectory(tools)

View file

@ -12,7 +12,12 @@ function(fb_add_dep TARGET_NAME DEP_NAME)
return() return()
endif() endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/deps/${DEP_NAME}.cmake") set(TOP_CMAKE "${CMAKE_CURRENT_SOURCE_DIR}/")
while(NOT EXISTS "${TOP_CMAKE}")
set(TOP_CMAKE "${TOP_CMAKE}../")
endwhile()
include("${TOP_CMAKE}cmake/deps/${DEP_NAME}.cmake")
if(NOT TARGET deps::${DEP_NAME}) if(NOT TARGET deps::${DEP_NAME})
add_library(deps::${DEP_NAME} ALIAS ${DEP_NAME}) add_library(deps::${DEP_NAME} ALIAS ${DEP_NAME})

View file

@ -24,6 +24,8 @@ fishbone::File::File(std::string path, std::string type) {
} }
fishbone::File::~File() { fishbone::File::~File() {
this->ifs.close();
this->ofs.close();
} }
size_t fishbone::File::read(void* buffer, size_t size) { size_t fishbone::File::read(void* buffer, size_t size) {

View file

@ -18,6 +18,8 @@ fishbone::Window::Window(std::string title, int width, int height){
this->impl = new fishbone::Window::Impl(); this->impl = new fishbone::Window::Impl();
this->impl->window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL); this->impl->window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL);
this->impl->ctx = SDL_GL_CreateContext(this->impl->window); this->impl->ctx = SDL_GL_CreateContext(this->impl->window);
gload_init();
} }
fishbone::Window::~Window(){ fishbone::Window::~Window(){

View file

@ -0,0 +1,7 @@
project(tools)
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/util.cmake")
add_executable(packer packer.cc)
fb_add_dep(packer lz4)

129
engine/tools/packer.cc Normal file
View file

@ -0,0 +1,129 @@
#include <vector>
#include <string>
#include <fstream>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <sys/stat.h>
#include <dirent.h>
#include <lz4.h>
/* Resource file is in simple structure:
* 4 bytes: ID
* 2 bytes: Data size
* n bytes: Data
*
* All numbers are in native endian
*/
class Chunk;
class Chunk {
void init(std::string name){
this->data = nullptr;
memset(this->id, 0, 4);
strcpy(this->id, name.c_str());
}
public:
char id[4];
unsigned char* data;
unsigned int size;
Chunk* parent;
std::vector<Chunk*> subchunks;
Chunk(std::string name){
this->init(name);
}
Chunk(Chunk* parent, std::string name){
this->init(name);
this->parent = parent;
this->parent->subchunks.push_back(this);
}
~Chunk(){
if(this->data != nullptr) delete[] this->data;
for(int i = 0; i < this->subchunks.size(); i++){
delete this->subchunks[i];
}
}
unsigned int totalSize(){
unsigned int sz = 0;
for(int i = 0; i < this->subchunks.size(); i++){
sz = this->subchunks[i]->totalSize();
}
return 4 + 4 + this->size + sz;
}
void write(std::string out){
std::ofstream* ofs = new std::ofstream(out, std::ios::binary);
this->write(ofs);
ofs->close();
}
void write(std::ofstream* ofs){
int sz = this->totalSize() - 4 - 4;
ofs->write((char*)this->id, 4);
ofs->write((char*)&sz, 4);
for(int i = 0; i < this->subchunks.size(); i++){
this->subchunks[i]->write(ofs);
}
}
};
static void readDir(Chunk* parent, std::string dirname){
DIR* dir = opendir(dirname.c_str());
struct dirent* d;
if(dir != nullptr){
while((d = readdir(dir)) != nullptr){
struct stat s;
std::string dn(d->d_name);
std::string p = dirname + "/" + dn;
Chunk* c;
if(dn == ".." || dn == ".") continue;
stat(p.c_str(), &s);
if(S_ISDIR(s.st_mode)){
c = new Chunk(parent, "DIRE");
readDir(c, p);
}else{
c = new Chunk(parent, "FILE");
}
}
closedir(dir);
}
}
int main(int argc, char** argv){
Chunk* root;
Chunk* rootdir;
if(argc < 3){
std::cerr << "Usage: " << argv[0] << " [output] [input...]" << std::endl;
return 1;
}
root = new Chunk("FBPK");
rootdir = new Chunk(root, "DIRE");
for(int i = 2; i < argc; i++){
readDir(rootdir, argv[i]);
}
root->write(argv[1]);
}