diff --git a/engine/include/fishbone/client.h b/engine/include/fishbone/client.h index 85eb0fe..1d9f160 100644 --- a/engine/include/fishbone/client.h +++ b/engine/include/fishbone/client.h @@ -13,7 +13,7 @@ namespace fishbone { class Client { public: fishbone::SoundDriver sound; - fishbone::Window window; + fishbone::Window window; }; }; // namespace fishbone diff --git a/engine/include/fishbone/thread.h b/engine/include/fishbone/thread.h index 60bf556..114269c 100644 --- a/engine/include/fishbone/thread.h +++ b/engine/include/fishbone/thread.h @@ -14,7 +14,7 @@ namespace fishbone { Impl* impl; public: - using Callable = void(*)(fishbone::Thread* thread, void* arg); + using Callable = void (*)(fishbone::Thread* thread, void* arg); using CallableLambda = std::function; Thread(Callable call, void* arg); diff --git a/engine/include/fishbone/window.h b/engine/include/fishbone/window.h index 43b5a74..7af1a18 100644 --- a/engine/include/fishbone/window.h +++ b/engine/include/fishbone/window.h @@ -12,10 +12,10 @@ namespace fishbone { struct Impl; Impl* impl; - public: + public: Window(std::string title, int width, int height); ~Window(); }; -}; +}; // namespace fishbone #endif diff --git a/engine/src/mixer.cc b/engine/src/mixer.cc index e629d39..9b58af1 100644 --- a/engine/src/mixer.cc +++ b/engine/src/mixer.cc @@ -42,7 +42,7 @@ void fishbone::Mixer::read(short* buffer, size_t frames) { float angle, v; float d; float lf, rf; - + for(int j = 0; j < 3; j++) r[j] = this->position[i] - this->sounds[i]->position[j]; angle = atan2(r[2], r[0]); @@ -83,7 +83,7 @@ void fishbone::Mixer::read(short* buffer, size_t frames) { r = req[(j * this->sounds[i]->rate / fishbone::Mixer::rate) * 2 + 1]; } - if(this->sounds[i]->is3d){ + if(this->sounds[i]->is3d) { l = (l + r) / 2; r = l; } diff --git a/engine/src/thread/sdl2.cc b/engine/src/thread/sdl2.cc index 91cb860..24e432c 100644 --- a/engine/src/thread/sdl2.cc +++ b/engine/src/thread/sdl2.cc @@ -3,14 +3,14 @@ #include struct call_arg { - fishbone::Thread::Callable call; - fishbone::Thread* thread; - void* arg; + fishbone::Thread::Callable call; + fishbone::Thread* thread; + void* arg; }; struct call_arg2 { - fishbone::Thread::CallableLambda call; - fishbone::Thread* thread; + fishbone::Thread::CallableLambda call; + fishbone::Thread* thread; }; static int SDLCALL thread_call(void* data) { diff --git a/engine/src/window/sdl2.cc b/engine/src/window/sdl2.cc index b12b57e..9216dcd 100644 --- a/engine/src/window/sdl2.cc +++ b/engine/src/window/sdl2.cc @@ -5,24 +5,24 @@ static bool sdl_video_init = false; struct fishbone::Window::Impl { - SDL_Window* window; + SDL_Window* window; SDL_GLContext ctx; }; -fishbone::Window::Window(std::string title, int width, int height){ +fishbone::Window::Window(std::string title, int width, int height) { if(!sdl_video_init) { SDL_InitSubSystem(SDL_INIT_VIDEO); sdl_video_init = true; } - 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->ctx = SDL_GL_CreateContext(this->impl->window); + this->impl->ctx = SDL_GL_CreateContext(this->impl->window); gload_init(); } -fishbone::Window::~Window(){ +fishbone::Window::~Window() { SDL_GL_DeleteContext(this->impl->ctx); SDL_DestroyWindow(this->impl->window); delete this->impl; diff --git a/engine/tools/packer.cc b/engine/tools/packer.cc index 9cf3421..ede7cc5 100644 --- a/engine/tools/packer.cc +++ b/engine/tools/packer.cc @@ -9,16 +9,40 @@ #include #include -#include +#include + +#define PATH_PART_LEN 32 /* Resource file is in simple structure: * 4 bytes: ID * 2 bytes: Data size * n bytes: Data * + * Subchunks come after data, so you have to know how chunk is strcutured + * * All numbers are in native endian + * + * DIRE chunk comes with following data: + * PATH_PART_LEN bytes name + * and nests FILE chunks + * + * FILE chunk comes with following data: + * 2 bytes flag + * 4 bytes data location + * 4 bytes data size + * PATH_PART_LEN bytes name */ +struct Data { + unsigned int size; + unsigned char* data; +}; + +#define FILE_FLAG_RAW (1 << 0) + +unsigned int loc = 0; +std::vector datalist; + class Chunk; class Chunk { @@ -26,6 +50,9 @@ class Chunk { this->data = nullptr; memset(this->id, 0, 4); strcpy(this->id, name.c_str()); + this->name = ""; + this->fullpath = ""; + this->keepRaw = false; } public: @@ -34,9 +61,14 @@ public: unsigned int size; Chunk* parent; std::vector subchunks; + std::string name; + std::string fullpath; + bool keepRaw; Chunk(std::string name){ this->init(name); + + this->parent = nullptr; } Chunk(Chunk* parent, std::string name){ @@ -64,19 +96,79 @@ public: 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; + unsigned int sz = 0; + + if(memcmp(this->id, "FILE", 4) == 0){ + unsigned short* flag; + unsigned int* location; + unsigned int* size; + char* name; + std::ifstream ifs(this->fullpath, std::ios::binary); + + unsigned int cbound; + unsigned char* fdata; + unsigned char* cdata; + unsigned int fsize; + unsigned int csize; + struct Data dc; + + ifs.seekg(0, std::ios_base::end); + fsize = ifs.tellg(); + ifs.seekg(0, std::ios_base::beg); + + fdata = new unsigned char[fsize]; + ifs.read((char*)fdata, fsize); + + if(this->keepRaw){ + cdata = fdata; + csize = fsize; + }else{ + cbound = LZ4F_compressFrameBound(fsize, nullptr); + cdata = new unsigned char[cbound]; + + csize = LZ4F_compressFrame(cdata, cbound, fdata, fsize, nullptr); + + delete[] fdata; + } + + this->size = 2 + 4 + 4 + PATH_PART_LEN; + this->data = new unsigned char[this->size]; + + flag = (unsigned short*)&this->data[0]; + location = (unsigned int*)&this->data[2]; + size = (unsigned int*)&this->data[2 + 4]; + name = (char*)&this->data[2 + 4 + 4]; + + *flag = (this->keepRaw ? FILE_FLAG_RAW : 0); + *location = loc; + *size = csize; + + memset(name, 0, PATH_PART_LEN); + memcpy(name, this->name.c_str(), this->name.size()); + + dc.data = cdata; + dc.size = csize; + datalist.push_back(dc); + + loc += csize; + }else if(memcmp(this->id, "DIRE", 4) == 0){ + char* name; + + this->size = PATH_PART_LEN; + this->data = new unsigned char[this->size]; + + name = (char*)&this->data[0]; + + memset(name, 0, PATH_PART_LEN); + memcpy(name, this->name.c_str(), this->name.size()); + } + + sz = this->totalSize() - 4 - 4; ofs->write((char*)this->id, 4); ofs->write((char*)&sz, 4); + if(this->size > 0) ofs->write((char*)this->data, this->size); for(int i = 0; i < this->subchunks.size(); i++){ this->subchunks[i]->write(ofs); } @@ -100,9 +192,20 @@ static void readDir(Chunk* parent, std::string dirname){ if(S_ISDIR(s.st_mode)){ c = new Chunk(parent, "DIRE"); + c->name = dn; + readDir(c, p); }else{ + int pos = dn.find_last_of('.'); + std::string ext = (pos == std::string::npos) ? "" : dn.substr(pos, dn.size() - pos); + c = new Chunk(parent, "FILE"); + c->name = dn; + c->fullpath = p; + + if(ext == ".png"){ + c->keepRaw = true; + } } } closedir(dir); @@ -112,6 +215,7 @@ static void readDir(Chunk* parent, std::string dirname){ int main(int argc, char** argv){ Chunk* root; Chunk* rootdir; + std::ofstream* ofs; if(argc < 3){ std::cerr << "Usage: " << argv[0] << " [output] [input...]" << std::endl; @@ -119,11 +223,18 @@ int main(int argc, char** argv){ } root = new Chunk("FBPK"); + rootdir = new Chunk(root, "DIRE"); + rootdir->name = ""; for(int i = 2; i < argc; i++){ readDir(rootdir, argv[i]); } - root->write(argv[1]); + ofs = new std::ofstream(argv[1], std::ios::binary); + root->write(ofs); + for(int i = 0; i < datalist.size(); i++){ + ofs->write((char*)datalist[i].data, datalist[i].size); + } + ofs->close(); }