summaryrefslogtreecommitdiff
path: root/src/plugin-luaslz.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugin-luaslz.cc')
-rw-r--r--src/plugin-luaslz.cc84
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);
+}
+
+}