diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugin-luaslz.cc | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/plugin-luaslz.cc b/src/plugin-luaslz.cc new file mode 100644 index 0000000..5f1cfd4 --- /dev/null +++ b/src/plugin-luaslz.cc @@ -0,0 +1,84 @@ +#include <BLua.h> +#include <lzss.h> + +#ifndef WIN32 +#define WEAK __attribute__ ((weak)) +#else +#define WEAK +#endif + +class sLua_slz : public Base { + public: + static int slz_decomp(lua_State * __L) { + Lua * L = Lua::find(__L); + int n = L->gettop(); + Handle * in, * out; + int slz_type; + lzss lzss_o; + + if (n != 2) + L->error("Wrong number of arguments to slz_decomp; need two handles."); + + in = lua_recast<Handle>(L, 1); + out = lua_recast<Handle>(L, 2); + + Uint32 sig, siz_in, siz_out, file_siz; + sig = in->readU32(); + siz_in = in->readU32(); + siz_out = in->readU32(); + file_siz = in->readU32(); + + switch (sig) { + case 0x05a4c53: + out->copyfrom(in, siz_in); + slz_type = 0; + break; + case 0x15a4c53: + slz_type = 1; + lzss_o.change_scheme(lzss_o.schemes[lzss_o.VP_1]); + lzss_o.lzss_decomp(in, out, siz_out, false); + break; + case 0x25a4c53: + slz_type = 2; + lzss_o.change_scheme(lzss_o.schemes[lzss_o.VP_2]); + lzss_o.lzss_decomp(in, out, siz_out, false); + break; + case 0x35a4c53: + slz_type = 3; + Handle::ucl_decompress(in, out, siz_out, siz_in); + break; + default: + L->error("Unknown slz scheme. Expected 0, 1, 2 or 3, got " + String(n)); + break; + } + + if (file_siz) + in->seek(file_siz - 16 - siz_in, SEEK_CUR); + + L->push((lua_Number) file_siz); + L->push((lua_Number) slz_type); + return 2; + } + static void pushstatics(Lua * L) { + L->declarefunc("slz_decomp", slz_decomp); + }; +}; + +static void _init_plugin(Lua * L) { + static bool done = false; + if (done) return; + done = true; + sLua_slz::pushstatics(L); +} + +extern "C" { + +WEAK void init_plugin(Lua * L) { + _init_plugin(L); +} + +void luaslz_init(Lua * L) { + _init_plugin(L); +} + +} |