From bbfc93a5b990d1009777de1fbd3efd51508f18ce Mon Sep 17 00:00:00 2001
From: pixel <pixel>
Date: Sun, 29 Feb 2004 17:44:42 +0000
Subject: First crude try of implementing BS encoding

---
 lib/luapsx.cpp | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 266 insertions(+), 2 deletions(-)

(limited to 'lib')

diff --git a/lib/luapsx.cpp b/lib/luapsx.cpp
index 0665d05..14dc1e3 100644
--- a/lib/luapsx.cpp
+++ b/lib/luapsx.cpp
@@ -17,9 +17,273 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: luapsx.cpp,v 1.1 2004-02-27 04:13:32 pixel Exp $ */
+/* $Id: luapsx.cpp,v 1.2 2004-02-29 17:44:42 pixel Exp $ */
 
+#include <LuaHandle.h>
 #include "luapsx.h"
+#include "generic.h"
 
-void Luapsx::pushstatics(Lua * L) throw (GeneralException) {
+void over(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+    d[0] = R;
+    d[1] = G;
+    d[2] = B;
+}
+
+void alpha(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+    A = MIN(A, (Byte) 128);
+    d[0] = ((int)d[0] * (128 - A) + R * A) >> 7;
+    d[1] = ((int)d[1] * (128 - A) + G * A) >> 7;
+    d[2] = ((int)d[2] * (128 - A) + B * A) >> 7;
+}
+
+void lighten(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+    A = MIN(A, (Byte) 128);
+    R = ((int)d[0] * (128 - A) + R * A) >> 7;
+    G = ((int)d[1] * (128 - A) + G * A) >> 7;
+    B = ((int)d[2] * (128 - A) + B * A) >> 7;
+    d[0] = MAX(R, d[0]);
+    d[1] = MAX(G, d[1]);
+    d[2] = MAX(B, d[2]);
+}
+
+void darken(Byte * d, Byte R, Byte G, Byte B, Byte A) {
+    A = MIN(A, (Byte) 128);
+    R = ((int)d[0] * (128 - A) + R * A) >> 7;
+    G = ((int)d[1] * (128 - A) + G * A) >> 7;
+    B = ((int)d[2] * (128 - A) + B * A) >> 7;
+    d[0] = MIN(R, d[0]);
+    d[1] = MIN(G, d[1]);
+    d[2] = MIN(B, d[2]);
+}
+
+enum {
+    BLIT_OVER = 0,
+    BLIT_OVER32,
+    BLIT_ALPHA,
+    BLIT_LIGHTEN,
+    BLIT_LIGHTEN32,
+    BLIT_DARKEN,
+    BLIT_DARKEN32,
+};
+
+typedef void psx;
+
+enum psx_functions_t {
+    PSX_BSDECODE = 0,
+    PSX_BSENCODE,
+    PSX_BLIT,
+};
+
+struct lua_functypes_t psx_functions[] = {
+    { PSX_BSDECODE,	"bsdecode",	3, 3, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER } },
+    { PSX_BSENCODE,	"bsencode", 	3, 5, { LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
+    { PSX_BLIT,		"blit",		9, 9, { LUA_OBJECT, LUA_OBJECT, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER, LUA_NUMBER } },
+    { -1, 0, 0, 0, 0 }
+};
+
+class sLua_psx : public Base {
+  public:
+    DECLARE_FUNCTION(psx, PSX_BSDECODE);
+  private:
+    static int psx_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luapsx::pushstatics(Lua * L) throw (GeneralException ) {
+    CHECK_FUNCTIONS(psx);
+
+    PUSH_FUNCTION(psx, PSX_BSDECODE);
+
+    L->push("BLIT_OVER");
+    L->push((lua_Number) BLIT_OVER);
+    L->settable(LUA_GLOBALSINDEX);    
+
+    L->push("BLIT_OVER32");
+    L->push((lua_Number) BLIT_OVER32);
+    L->settable(LUA_GLOBALSINDEX);    
+
+    L->push("BLIT_ALPHA");
+    L->push((lua_Number) BLIT_ALPHA);
+    L->settable(LUA_GLOBALSINDEX);    
+
+    L->push("BLIT_LIGHTEN");
+    L->push((lua_Number) BLIT_LIGHTEN);
+    L->settable(LUA_GLOBALSINDEX);    
+
+    L->push("BLIT_LIGHTEN32");
+    L->push((lua_Number) BLIT_LIGHTEN32);
+    L->settable(LUA_GLOBALSINDEX);
+
+    L->push("BLIT_DARKEN");
+    L->push((lua_Number) BLIT_DARKEN);
+    L->settable(LUA_GLOBALSINDEX);    
+
+    L->push("BLIT_DARKEN32");
+    L->push((lua_Number) BLIT_DARKEN32);
+    L->settable(LUA_GLOBALSINDEX);    
+}
+
+int sLua_psx::psx_proceed_statics(Lua * L, int n, int caller) {
+    int r = 0;
+    
+    switch (caller) {
+    case PSX_BSDECODE:
+	r = 1;
+	{
+	    Buffer * b = new Buffer(true);
+	    Handle * f = (Handle *) LuaObject::getme(L, 1);
+	    int width = L->tonumber(2);
+	    int height = L->tonumber(3);
+	    Byte * in = (Byte *) malloc(f->GetSize() + 10);
+	    Byte * out = (Byte *) malloc(width * height * 3);
+	    LuaBuffer lb(b);
+	    lb.pushdestruct(L);
+	    f->read(in, f->GetSize());
+	    bs_decode_rgb24(out, (bs_header_t *) in, width, height, 0);
+	    for (int i = 0; i < width * height * 3; i++) {
+		b[i] = out[i];
+	    }
+	    free(out);
+	    free(in);
+	}
+    case PSX_BSENCODE:
+	r = 3;
+	{
+	    unsigned short out[0x80000];
+	    Buffer * b = new Buffer(true);
+	    LuaBuffer lb(b);
+	    lb.pushdestruct(L);
+	    Handle * f = (Handle *) LuaObject::getme(L, 1);
+	    bs_input_image_t img;
+	    img.width = L->tonumber(2);
+	    img.height = L->tonumber(3);
+	    int max_size = 14112, cur_size;
+	    int q_scale = 1;
+	    if (n >= 4)
+		max_size = L->tonumber(4);
+	    if (n >= 5)
+		q_scale = L->tonumber(5);
+	    img.lpbits = (Byte *) malloc(f->GetSize());
+	    img.top = img.lpbits;
+	    img.nextline = img.width * 3;
+	    img.bit = 24;
+	    
+	    f->read(img.lpbits, f->GetSize());
+	    
+	    bs_init();
+	    
+	    cur_size = max_size + 1;
+	    
+	    for (cur_size = max_size + 1; max_size < cur_size; q_scale++) {
+		cur_size = bs_encode((bs_header_t *) out, &img, 2, q_scale, 0);
+	    }
+	    
+	    for (int i = 0; i < cur_size; i++) {
+		b[i] = out[i];
+	    }
+	    
+	    L->push((lua_Number) cur_size);
+	    L->push((lua_Number) q_scale);
+	}
+    case PSX_BLIT:
+	r = 0;
+	{
+	    Handle * d = (Handle *) LuaObject::getme(L, 1);
+	    Handle * s = (Handle *) LuaObject::getme(L, 2);
+	    int dw = L->tonumber(3),
+		dh = L->tonumber(4),
+		sw = L->tonumber(5),
+		sh = L->tonumber(6),
+		sx = L->tonumber(7),
+		sy = L->tonumber(8),
+		bl = L->tonumber(9);
+	    int bytes, dstart = 0, dskip = 0, sstart = 0, sskip = 0, i, j;
+	    Byte RGB[3], R, G, B, A = 128;
+	    void (*op_func)(Byte *, Byte, Byte, Byte, Byte);
+	    
+	    switch(bl) {
+	    case BLIT_OVER:
+		bytes = 3;
+		op_func = over;
+		break;
+	    case BLIT_OVER32:
+		bytes = 4;
+		op_func = over;
+		break;
+	    case BLIT_ALPHA:
+		bytes = 4;
+		op_func = alpha;
+		break;
+	    case BLIT_LIGHTEN:
+		bytes = 3;
+		op_func = lighten;
+		break;
+	    case BLIT_LIGHTEN32:
+		bytes = 4;
+		op_func = lighten;
+		break;
+	    case BLIT_DARKEN:
+		bytes = 3;
+		op_func = darken;
+		break;
+	    case BLIT_DARKEN32:
+		bytes = 4;
+		op_func = darken;
+		break;
+	    default:
+		L->error("Blitting operation unknown.");
+		return 0;
+	    }
+	    
+	    if (sy < 0) {
+		sstart += sw * bytes * sy;
+		sh -= sy;
+		sy = 0;
+	    } else {
+		dstart += dw * 3 * sy;
+	    }
+	    
+	    if ((sy + sh) > dh) {
+		sh -= (sy + sh) - dh;
+	    }
+	    
+	    if (sx < 0) {
+		sstart += sx * bytes;
+		sskip += sx * bytes;
+		sw -= sx;
+		sx = 0;
+	    } else {
+		dstart += sx * 3;
+	    }
+	    
+	    if ((sx + sw) > dw) {
+		sskip += (sx + sw) - dw;
+		sw -= (sx + sw) - dw;
+	    }
+	    
+	    dskip = (dw - sw) * 3;
+	    
+	    d->seek(dstart);
+	    s->seek(sstart);
+	    
+	    for (i = 0; i < sh; i++, s->seek(sskip, SEEK_CUR), d->seek(dskip, SEEK_CUR)) {
+		for (j = 0; j < sw; j++) {
+		    RGB[0] = d->readU8();
+		    RGB[1] = d->readU8();
+		    RGB[2] = d->readU8();
+		    d->seek(-3, SEEK_CUR);
+		    R = s->readU8();
+		    G = s->readU8();
+		    B = s->readU8();
+		    if (bytes == 4)
+			A = s->readU8();
+		    op_func(RGB, R, G, B, A);
+		    d->writeU8(R);
+		    d->writeU8(G);
+		    d->writeU8(B);
+		}
+	    }
+	    
+	}
+    }
+    return r;
 }
-- 
cgit v1.2.3