diff --git a/client/main.cc b/client/main.cc index d76acb0..a37c4e6 100644 --- a/client/main.cc +++ b/client/main.cc @@ -18,7 +18,7 @@ int main(){ signal(SIGTERM, cleanup); #endif - wnd = new fishbone::Window("Fishbowl", 640, 480); + wnd = new fishbone::Window("Fishbowl", 800, 600); while(!quit); } diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index 470f90f..90c2438 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -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}") endif() endif() -include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CPM.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/util.cmake") file(GLOB_RECURSE SRCS src/**.cc src/**.c) @@ -69,3 +68,6 @@ if(FISHBONE_BUILD_TESTS) enable_testing() add_subdirectory(tests) endif() + +# Tools +add_subdirectory(tools) diff --git a/engine/cmake/util.cmake b/engine/cmake/util.cmake index ee4dd5c..8ac15f6 100644 --- a/engine/cmake/util.cmake +++ b/engine/cmake/util.cmake @@ -12,7 +12,12 @@ function(fb_add_dep TARGET_NAME DEP_NAME) return() 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}) add_library(deps::${DEP_NAME} ALIAS ${DEP_NAME}) diff --git a/engine/src/file.cc b/engine/src/file.cc index 72cf8bb..5620858 100644 --- a/engine/src/file.cc +++ b/engine/src/file.cc @@ -24,6 +24,8 @@ fishbone::File::File(std::string path, std::string type) { } fishbone::File::~File() { + this->ifs.close(); + this->ofs.close(); } size_t fishbone::File::read(void* buffer, size_t size) { diff --git a/engine/src/window/sdl2.cc b/engine/src/window/sdl2.cc index 373c5ba..b12b57e 100644 --- a/engine/src/window/sdl2.cc +++ b/engine/src/window/sdl2.cc @@ -18,6 +18,8 @@ fishbone::Window::Window(std::string title, int width, int height){ 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->ctx = SDL_GL_CreateContext(this->impl->window); + + gload_init(); } fishbone::Window::~Window(){ diff --git a/engine/tools/CMakeLists.txt b/engine/tools/CMakeLists.txt new file mode 100644 index 0000000..997f83d --- /dev/null +++ b/engine/tools/CMakeLists.txt @@ -0,0 +1,7 @@ +project(tools) + +include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/util.cmake") + +add_executable(packer packer.cc) + +fb_add_dep(packer lz4) diff --git a/engine/tools/packer.cc b/engine/tools/packer.cc new file mode 100644 index 0000000..9cf3421 --- /dev/null +++ b/engine/tools/packer.cc @@ -0,0 +1,129 @@ +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +/* 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 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]); +}