summaryrefslogtreecommitdiff
path: root/src/plugin-luaslz.cc
blob: 5f1cfd460d33d62b2057bb931af78a9038636b4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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);
}

}