From bbfc93a5b990d1009777de1fbd3efd51508f18ce Mon Sep 17 00:00:00 2001 From: pixel Date: Sun, 29 Feb 2004 17:44:42 +0000 Subject: First crude try of implementing BS encoding --- FAQ-cd.txt | 53 ++++++++++- Makefile | 6 +- cd-tool.cpp | 4 +- includes/luapsx.h | 4 +- lib/luapsx.cpp | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++++- luapatch.cpp | 2 + str-player.cpp | 7 ++ 7 files changed, 334 insertions(+), 10 deletions(-) diff --git a/FAQ-cd.txt b/FAQ-cd.txt index b2ed2c5..5708ba2 100644 --- a/FAQ-cd.txt +++ b/FAQ-cd.txt @@ -866,7 +866,58 @@ A: First of all, my LUA distribution is the 5.0, slightly modified. The basic iso:close() - Pwieew, all done. Good luck ! ;-) + Pwieew, all done! ;-) + + Well, almost actually. Only a few global functions remains. + + exists(filename) + + Will take a string as argument, and return a boolean to tell if the + corresponding file can be safely opened for reading. + + bsdecode(handle, width, height) + + Will return a buffer to a rgb24 picture (size width * height * 3) + corresponding to the decompressed bs picture passed as argument. Beware, + this function is weak, does no check at all, and will certainly crashes the + software if you gives a wrong type buffer. + + bsencode(handle, width, height[, max_size[, q_scale]]) + + Well return a buffer to an encoded bs frame, corresponding to the + input handle, which has to be in rgb24 format. Eventually, the function + will also return the buffer size as second returned value. q_scale + is the initial q_scale value (default = 1), and max_size is the maximum + frame size in bytes, which defaults to 14112 (standard STR size). The + function will redo the encoding process, increasing q_scale each time, + until the final frame size is <= the max_size. Eventually, the function + will return the final q_scale as the third value returned. + + blit(dest, source, dw, dh, sw, sh, sx, sy, bl) + + This will blit the source image buffer into the destination image buffer. + The destination is always a 24 bits RGB picture, of size (dw, dh). The + source buffer can be a 24 bits RGB, or a 32 bits RGBA picture, of size + (sw, sh), and shall be placed into the destination picture at position + (sx, sy) using the method described by bl. The depth of the source buffer + is determined by bl. This argument can be: + + BLIT_OVER - Source is 24 bits. Destination will be fully + overriten by the source picture. + BLIT_OVER32 - Source is 32 bits. Destination will be fully + overriten by the source picture. Source alpha ignored. + BLIT_ALPHA - Source is 32 bits. A full alpha blending will occur. + Alpha = 0: transparant, Alpha = 128: opaque. + BLIT_LIGHTEN - Source is 24 bits. The source will lighten the + destination. + BLIT_LIGHTEN32 - Source is 32 bits. The source will lighten the + destination. Alpha is used. + BLIT_DARKEN - Source is 24 bits. The source will darken the + destionation. + BLIT_DARKEN32 - Source is 32 bits. The source will darken the + destination. Alpha is used. + + Good luck! ;-) Q: What patch did you applied to the LUA compiler? diff --git a/Makefile b/Makefile index 37b6399..75097a8 100755 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ #!/usr/bin/make -f -CPPFLAGS=-Wall -g -O3 -mcpu=i686 -Iincludes `sdl-config --cflags` -DHAVE_ZLIB `baltisot-config --cflags` `lua-config --include` +CPPFLAGS=-Wall -g -O3 -mcpu=i686 -Iincludes `sdl-config --cflags` -DHAVE_ZLIB `baltisot-config --cflags` `lua-config --include` -DCHATTING LDFLAGS=-lz `sdl-config --libs` `baltisot-config --libs` -lefence CDTOOL_LDFLAGS=`baltisot-config --libs` CXX=g++ @@ -23,8 +23,8 @@ dlzss: lzss Makefile yazedc: yazedc-main.o lib/lib.a Makefile ${CXX} yazedc-main.o lib/lib.a -DYAZEDC_MAIN -o yazedc ${LDFLAGS} -cd-tool: includes/cdutils.h includes/yazedc.h cd-tool.o lib/lib.a Makefile - ${CXX} cd-tool.o lib/lib.a -o cd-tool ${CDTOOL_LDFLAGS} +cd-tool: includes/cdutils.h includes/yazedc.h cd-tool.o lib/lib.a psxdev/psxdev.a Makefile + ${CXX} cd-tool.o lib/lib.a psxdev/psxdev.a -o cd-tool ${CDTOOL_LDFLAGS} dte-tool: includes/dte.h dtemain.o lib/lib.a Makefile ${CXX} dtemain.o lib/lib.a -o dte-tool ${LDFLAGS} diff --git a/cd-tool.cpp b/cd-tool.cpp index 67f1d2d..888cf9a 100644 --- a/cd-tool.cpp +++ b/cd-tool.cpp @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: cd-tool.cpp,v 1.21 2003-12-19 21:17:07 pixel Exp $ */ +/* $Id: cd-tool.cpp,v 1.22 2004-02-29 17:44:42 pixel Exp $ */ #include #include @@ -37,6 +37,7 @@ #include "cdabstract.h" #include "isobuilder.h" #include "luacd.h" +#include "luapsx.h" static int myprint(lua_State * _L) { Lua * L = Lua::find(_L); @@ -83,6 +84,7 @@ Lua * startlua(void) { LuaOutput::pushconstruct(L); LuaBuffer::pushconstruct(L); CD_PUSHSTATICS(L); + Luapsx::pushstatics(L); L->push("print"); L->push(myprint); L->settable(LUA_GLOBALSINDEX); diff --git a/includes/luapsx.h b/includes/luapsx.h index e1bf600..53d5c4f 100644 --- a/includes/luapsx.h +++ b/includes/luapsx.h @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: luapsx.h,v 1.1 2004-02-27 04:13:32 pixel Exp $ */ +/* $Id: luapsx.h,v 1.2 2004-02-29 17:44:42 pixel Exp $ */ #ifndef __LUAPSX_H__ #define __LUAPSX_H__ @@ -29,8 +29,6 @@ class Luapsx : public LuaObject { public: static void pushstatics(Lua *) throw (GeneralException); - protected: - virtual void pushmembers(Lua *); }; #endif 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 #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; } diff --git a/luapatch.cpp b/luapatch.cpp index f878bd7..0dbae95 100644 --- a/luapatch.cpp +++ b/luapatch.cpp @@ -10,6 +10,7 @@ #include "cdutils.h" #include "isobuilder.h" #include "luacd.h" +#include "luapsx.h" #include "luapatch-res.h" @@ -439,6 +440,7 @@ virtual int startup(void) throw (GeneralException) { LuaOutput::pushconstruct(L); LuaBuffer::pushconstruct(L); CD_PUSHSTATICS(L); + Luapsx::pushstatics(L); L->push("print"); L->push(myprint); L->settable(LUA_GLOBALSINDEX); diff --git a/str-player.cpp b/str-player.cpp index fa5f17a..99ddd15 100644 --- a/str-player.cpp +++ b/str-player.cpp @@ -137,6 +137,13 @@ int process_one_sector(Handle * f) { printm(M_BARE, "Width: %i, Height: %i - bpp: %i\n", width, height, bpp); #endif memset(video + h->StFRAME_SIZE, 0, h->StSECTOR_SIZE * 2016 - h->StFRAME_SIZE); +#ifdef DUMPING + String fn; + fn.set("frame-%04i.bs", h->StFRAME_NO); + Output * tf = new Output(fn); + tf->write(video, h->StFRAME_SIZE); + delete tf; +#endif bs_decode_rgb24(buffer, (bs_header_t *) video, width, height, 0); // fwrite(screen->pixels, 3, width * height, stdout); -- cgit v1.2.3