aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Hamm2002-03-06 19:58:06 +0000
committerVincent Hamm2002-03-06 19:58:06 +0000
commitcf868605f6f619c339660eb3380246d92bbbbe5f (patch)
treecb471f0286ab328808c145ab542828baa766ae58
parent6265b84fb3b2cd07a6e079b1d12fa89a521e6898 (diff)
downloadscummvm-rg350-cf868605f6f619c339660eb3380246d92bbbbe5f.tar.gz
scummvm-rg350-cf868605f6f619c339660eb3380246d92bbbbe5f.tar.bz2
scummvm-rg350-cf868605f6f619c339660eb3380246d92bbbbe5f.zip
Preliminary smush playback support.
svn-id: r3669
-rw-r--r--Makefile2
-rw-r--r--insane.cpp561
-rw-r--r--script_v2.cpp4
-rw-r--r--scumm.h5
-rw-r--r--scummvm.cpp3
-rw-r--r--smush.h77
6 files changed, 649 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 91340e3b0f..98151f7ea5 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ OBJS = actor.o boxes.o costume.o gfx.o object.o resource.o \
saveload.o script.o scummvm.o sound.o string.o \
sys.o verbs.o sdl.o script_v1.o script_v2.o debug.o gui.o \
sound/imuse.o sound/fmopl.o sound/adlib.o sound/gmidi.o debugrl.o \
- akos.o vars.o
+ akos.o vars.o insane.o
DISTFILES=$(OBJS:.o=.cpp) Makefile scumm.h scummsys.h stdafx.h stdafx.cpp \
windows.cpp debugrl.h whatsnew.txt readme.txt copying.txt \
diff --git a/insane.cpp b/insane.cpp
new file mode 100644
index 0000000000..e23b9685fe
--- /dev/null
+++ b/insane.cpp
@@ -0,0 +1,561 @@
+// insane.cpp : Defines the entry point for the console application.
+//
+
+#define NEED_SDL_HEADERS
+
+#include "stdafx.h"
+#include "scumm.h"
+
+#define SWAP2(a) ((((a)>>24)&0xFF) | (((a)>>8)&0xFF00) | (((a)<<8)&0xFF0000) | (((a)<<24)&0xFF000000))
+
+void invalidblock(uint32 tag) {
+ error("Encountered invalid block %c%c%c%c", tag>>24, tag>>16, tag>>8, tag);
+}
+
+uint32 SmushPlayer::nextBE32() {
+ uint32 a = *((uint32*)_cur);
+ _cur += sizeof(uint32);
+ return SWAP2(a);
+}
+
+void SmushPlayer::fileRead(void *mem, int len) {
+ if (fread(mem, len,1, _in) != 1)
+ error("EOF while reading");
+}
+
+uint32 SmushPlayer::fileReadBE32() {
+ uint32 number;
+ fileRead(&number, sizeof(number));
+ return SWAP2(number);
+}
+
+uint32 SmushPlayer::fileReadLE32() {
+ uint32 number;
+ fileRead(&number, sizeof(number));
+ return number;
+}
+
+void SmushPlayer::openFile(byte* fileName) {
+ byte buf[100];
+ sprintf((char*)buf,"%s%s%s",(char*)sm->_gameDataPath,(char*)sm->_videoPath,(char*)fileName);
+ _in = fopen((char*)buf, "rb");
+}
+
+void SmushPlayer::nextBlock() {
+ _blockTag = fileReadBE32();
+ _blockSize = fileReadBE32();
+
+ if (_block != NULL)
+ free(_block);
+
+ _block = (byte*)malloc(_blockSize);
+ if (_block==NULL)
+ error("cannot allocate memory");
+
+ fileRead(_block, _blockSize);
+}
+
+bool SmushPlayer::parseTag() {
+ switch(nextBlock(), _blockTag) {
+ case 'AHDR':
+ parseAHDR();
+ break;
+ case 'FRME':
+ parseFRME();
+ break;
+ default:
+ invalidblock(_blockTag);
+ }
+ return true;
+}
+
+void SmushPlayer::parseAHDR() {
+// memcpy(_fluPalette, _block, 0x300);
+ _paletteChanged = true;
+
+ printf("parse AHDR\n");
+}
+
+void SmushPlayer::parseNPAL() {
+ memcpy(_fluPalette, _cur, 0x300);
+ _paletteChanged = true;
+}
+
+void codec1(CodecData *cd) {
+ uint y = cd->y;
+ byte *src = cd->src;
+ byte *dest= cd->out;
+ uint h = cd->h;
+
+ if (!h || !cd->w)
+ return;
+
+ dest += cd->y * cd->pitch;
+
+ do {
+ byte color;
+ uint len, num;
+ uint x;
+ if ((uint)y >= (uint)cd->outheight) {
+ src += *(uint16*)(src) + 2;
+ continue;
+ }
+ len = cd->w;
+ x = cd->x;
+
+ src += 2;
+ do {
+ byte code = *src++;
+ num = (code>>1)+1;
+ if (num>len) num=len;
+ len -= num;
+ if (code&1) {
+ color = *src++;
+// if ((color = *src++)!=0) {
+ do {
+ if ((uint)x < (uint)cd->outwidth)
+ dest[x] = color;
+ } while (++x,--num);
+// } else {
+// x += num;
+// }
+ } else {
+ do {
+ color = *src++;
+ if (/*(color=*src++) != 0 &&*/ (uint)x < (uint)cd->outwidth)
+ dest[x] = color;
+ } while (++x,--num);
+ }
+ } while (len);
+ } while (dest += cd->pitch,y++,--h);
+}
+
+void codec37_bompdepack(byte *dst, byte *src, int len) {
+ byte code;
+ byte color;
+ int num;
+
+ do {
+ code = *src++;
+ if (code & 1) {
+ num = (code>>1) + 1;
+ color = *src++;
+ memset(dst, color, num);
+ dst += num;
+ } else {
+ num = (code>>1) + 1;
+ memcpy(dst,src,num);
+ dst += num;
+ src += num;
+ }
+ } while (len -= num);
+}
+
+void codec37_proc5(byte *dst, byte *src, int next_offs, int bw, int bh, int pitch, int16 *table) {
+ byte code, *tmp;
+ int i;
+
+ if (pitch != 320)
+ error("invalid pitch");
+
+ do {
+ i = bw;
+ do {
+ code = *src++;
+ if (code==0xFF) {
+ *(uint32*)(dst+0) = ((uint32*)src)[0];
+ *(uint32*)(dst+320) = ((uint32*)src)[1];
+ *(uint32*)(dst+320*2) = ((uint32*)src)[2];
+ *(uint32*)(dst+320*3) = ((uint32*)src)[3];
+ src += 16;
+ dst += 4;
+ } else {
+ tmp = dst + table[code] + next_offs;
+ *(uint32*)(dst+0) = *(uint32*)(tmp);
+ *(uint32*)(dst+320) = *(uint32*)(tmp+320);
+ *(uint32*)(dst+320*2) = *(uint32*)(tmp+320*2);
+ *(uint32*)(dst+320*3) = *(uint32*)(tmp+320*3);
+ dst += 4;
+ }
+ } while(--i);
+ dst += 320*4 - 320;
+ } while (--bh);
+}
+
+static const int8 maketable_bytes[] = {
+0, 0, 1, 0, 2, 0, 3, 0, 5, 0, 8, 0, 13, 0, 21, 0,
+-1, 0, -2, 0, -3, 0, -5, 0, -8, 0, -13, 0, -17, 0, -21, 0,
+0, 1, 1, 1, 2, 1, 3, 1, 5, 1, 8, 1, 13, 1, 21, 1,
+-1, 1, -2, 1, -3, 1, -5, 1, -8, 1, -13, 1, -17, 1, -21, 1,
+0, 2, 1, 2, 2, 2, 3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
+-1, 2, -2, 2, -3, 2, -5, 2, -8, 2, -13, 2, -17, 2, -21, 2,
+0, 3, 1, 3, 2, 3, 3, 3, 5, 3, 8, 3, 13, 3, 21, 3,
+-1, 3, -2, 3, -3, 3, -5, 3, -8, 3, -13, 3, -17, 3, -21, 3,
+0, 5, 1, 5, 2, 5, 3, 5, 5, 5, 8, 5, 13, 5, 21, 5,
+-1, 5, -2, 5, -3, 5, -5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
+0, 8, 1, 8, 2, 8, 3, 8, 5, 8, 8, 8, 13, 8, 21, 8,
+-1, 8, -2, 8, -3, 8, -5, 8, -8, 8, -13, 8, -17, 8, -21, 8,
+0, 13, 1, 13, 2, 13, 3, 13, 5, 13, 8, 13, 13, 13, 21, 13,
+-1, 13, -2, 13, -3, 13, -5, 13, -8, 13, -13, 13, -17, 13, -21, 13,
+0, 21, 1, 21, 2, 21, 3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
+-1, 21, -2, 21, -3, 21, -5, 21, -8, 21, -13, 21, -17, 21, -21, 21,
+0, -1, 1, -1, 2, -1, 3, -1, 5, -1, 8, -1, 13, -1, 21, -1,
+-1, -1, -2, -1, -3, -1, -5, -1, -8, -1, -13, -1, -17, -1, -21, -1,
+0, -2, 1, -2, 2, -2, 3, -2, 5, -2, 8, -2, 13, -2, 21, -2,
+-1, -2, -2, -2, -3, -2, -5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
+0, -3, 1, -3, 2, -3, 3, -3, 5, -3, 8, -3, 13, -3, 21, -3,
+-1, -3, -2, -3, -3, -3, -5, -3, -8, -3, -13, -3, -17, -3, -21, -3,
+0, -5, 1, -5, 2, -5, 3, -5, 5, -5, 8, -5, 13, -5, 21, -5,
+-1, -5, -2, -5, -3, -5, -5, -5, -8, -5, -13, -5, -17, -5, -21, -5,
+0, -8, 1, -8, 2, -8, 3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
+-1, -8, -2, -8, -3, -8, -5, -8, -8, -8, -13, -8, -17, -8, -21, -8,
+0, -13, 1, -13, 2, -13, 3, -13, 5, -13, 8, -13, 13, -13, 21, -13,
+-1, -13, -2, -13, -3, -13, -5, -13, -8, -13, -13, -13, -17, -13, -21, -13,
+0, -17, 1, -17, 2, -17, 3, -17, 5, -17, 8, -17, 13, -17, 21, -17,
+-1, -17, -2, -17, -3, -17, -5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
+0, -21, 1, -21, 2, -21, 3, -21, 5, -21, 8, -21, 13, -21, 21, -21,
+-1, -21, -2, -21, -3, -21, -5, -21, -8, -21, -13, -21, -17, -21, 0, 0,
+-8, -29, 8, -29, -18, -25, 17, -25, 0, -23, -6, -22, 6, -22, -13, -19,
+12, -19, 0, -18, 25, -18, -25, -17, -5, -17, 5, -17, -10, -15, 10, -15,
+0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
+2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9,
+1, -9, 6, -9, -29, -8, -11, -8, -8, -8, -3, -8, 3, -8, 8, -8,
+11, -8, 29, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6,
+-9, -6, -6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6,
+22, -6, -17, -5, -7, -5, -4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
+7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -1, -4, 0, -4,
+1, -4, 3, -4, 5, -4, 10, -4, 13, -4, -8, -3, -6, -3, -4, -3,
+-3, -3, -2, -3, -1, -3, 0, -3, 1, -3, 2, -3, 4, -3, 6, -3,
+8, -3, -11, -2, -7, -2, -5, -2, -3, -2, -2, -2, -1, -2, 0, -2,
+1, -2, 2, -2, 3, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
+-4, -1, -3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1,
+4, -1, 6, -1, 9, -1, -31, 0, -23, 0, -18, 0, -14, 0, -11, 0,
+-7, 0, -5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -31, 1, 0,
+2, 0, 3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0,
+23, 0, 31, 0, -9, 1, -6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
+0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 6, 1, 9, 1, -11, 2,
+-7, 2, -5, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2, 2, 2,
+3, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3, -4, 3, -2, 3,
+-1, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 6, 3, 8, 3,
+-13, 4, -10, 4, -5, 4, -3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
+5, 4, 10, 4, 13, 4, -17, 5, -7, 5, -4, 5, -2, 5, 0, 5,
+2, 5, 4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6,
+-1, 6, 1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7,
+0, 7, 2, 7, 5, 7, -29, 8, -11, 8, -8, 8, -3, 8, 3, 8,
+8, 8, 11, 8, 29, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
+-4, 10, 4, 10, 15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
+19, 12, -19, 13, -4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17,
+5, 17, 25, 17, -25, 18, 0, 18, -12, 19, 13, 19, -6, 22, 6, 22,
+0, 23, -17, 25, 18, 25, -8, 29, 8, 29, 0, 31, 0, 0, -6, -22,
+6, -22, -13, -19, 12, -19, 0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
+0, -14, -4, -13, 4, -13, 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
+2, -11, 8, -11, -15, -10, -4, -10, 4, -10, 15, -10, -6, -9, -1, -9,
+1, -9, 6, -9, -11, -8, -8, -8, -3, -8, 0, -8, 3, -8, 8, -8,
+11, -8, -5, -7, -2, -7, 0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
+-6, -6, -3, -6, -1, -6, 1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
+-17, -5, -7, -5, -4, -5, -2, -5, -1, -5, 0, -5, 1, -5, 2, -5,
+4, -5, 7, -5, 17, -5, -13, -4, -10, -4, -5, -4, -3, -4, -2, -4,
+-1, -4, 0, -4, 1, -4, 2, -4, 3, -4, 5, -4, 10, -4, 13, -4,
+-8, -3, -6, -3, -4, -3, -3, -3, -2, -3, -1, -3, 0, -3, 1, -3,
+2, -3, 3, -3, 4, -3, 6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
+-4, -2, -3, -2, -2, -2, -1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
+4, -2, 5, -2, 7, -2, 11, -2, -9, -1, -6, -1, -5, -1, -4, -1,
+-3, -1, -2, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1,
+5, -1, 6, -1, 9, -1, -23, 0, -18, 0, -14, 0, -11, 0, -7, 0,
+-5, 0, -4, 0, -3, 0, -2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
+3, 0, 4, 0, 5, 0, 7, 0, 11, 0, 14, 0, 18, 0, 23, 0,
+-9, 1, -6, 1, -5, 1, -4, 1, -3, 1, -2, 1, -1, 1, 0, 1,
+1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 9, 1, -11, 2,
+-7, 2, -5, 2, -4, 2, -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
+2, 2, 3, 2, 4, 2, 5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
+-4, 3, -3, 3, -2, 3, -1, 3, 0, 3, 1, 3, 2, 3, 3, 3,
+4, 3, 6, 3, 8, 3, -13, 4, -10, 4, -5, 4, -3, 4, -2, 4,
+-1, 4, 0, 4, 1, 4, 2, 4, 3, 4, 5, 4, 10, 4, 13, 4,
+-17, 5, -7, 5, -4, 5, -2, 5, -1, 5, 0, 5, 1, 5, 2, 5,
+4, 5, 7, 5, 17, 5, -22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
+1, 6, 3, 6, 6, 6, 9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
+2, 7, 5, 7, -11, 8, -8, 8, -3, 8, 0, 8, 3, 8, 8, 8,
+11, 8, -6, 9, -1, 9, 1, 9, 6, 9, -15, 10, -4, 10, 4, 10,
+15, 10, -8, 11, -2, 11, 0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
+-4, 13, 4, 13, 0, 14, -10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
+-12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
+};
+
+
+void codec37_maketable(PersistentCodecData37 *pcd, int pitch, byte index) {
+ int i,j;
+
+ if (pcd->table_last_pitch==pitch && pcd->table_last_flags==index)
+ return;
+ pcd->table_last_pitch = pitch;
+ pcd->table_last_flags = index;
+
+ assert(index*255 + 254 < sizeof(maketable_bytes)/2);
+
+ for(i=0; i<255; i++) {
+ j = i + index*255;
+ pcd->table1[i] = maketable_bytes[j*2+1] * pitch + maketable_bytes[j*2];
+ }
+
+}
+
+void codec37(CodecData *cd, PersistentCodecData37 *pcd) {
+ int width_in_blocks, height_in_blocks;
+ int src_pitch;
+ byte *src = cd->src, *curbuf;
+ uint size;
+ bool result = false;
+
+ width_in_blocks = (cd->w + 3) >> 2;
+ height_in_blocks = (cd->h + 3) >> 2;
+ src_pitch = width_in_blocks * 4;
+
+ codec37_maketable(pcd, src_pitch, cd->src[1]);
+
+ switch(cd->src[0]) {
+ case 0: {
+ curbuf = pcd->deltaBufs[pcd->curtable];
+ memset(pcd->deltaBuf, 0, curbuf - pcd->deltaBuf);
+ size = *(uint32*)(cd->src + 4);
+ memset(curbuf + size, 0, pcd->deltaBuf + pcd->deltaSize - curbuf - size);
+ memcpy(curbuf, cd->src + 16, size);
+ break;
+ }
+ case 2: {
+ size = *(uint32*)(cd->src + 4);
+ curbuf = pcd->deltaBufs[pcd->curtable];
+ codec37_bompdepack(curbuf, cd->src+16, size);
+ memset(pcd->deltaBuf, 0, curbuf - pcd->deltaBuf);
+ memset(curbuf + size, 0, pcd->deltaBuf + pcd->deltaSize - curbuf - size);
+ break;
+ }
+ case 3: {
+ uint16 number = *(uint16*)(cd->src + 2);
+ if ( number && pcd->flags+1 != number)
+ break;
+
+ if (number&1 && cd->src[12]&1 && cd->flags&0x10) {
+ result=true;
+ break;
+ }
+
+ if ((number&1) || !(cd->src[12]&1)) {
+ pcd->curtable ^= 1;
+ }
+
+ codec37_proc5(pcd->deltaBufs[pcd->curtable], cd->src+16,
+ pcd->deltaBufs[pcd->curtable^1] - pcd->deltaBufs[pcd->curtable],
+ width_in_blocks, height_in_blocks, src_pitch,
+ pcd->table1);
+ break;
+ }
+
+ case 1:
+ case 4:
+ printf("code %d", cd->src[0]);
+ return;
+ default:
+ error("codec37 default case");
+ }
+
+
+ pcd->flags = *(uint16*)(cd->src + 2);
+
+ if (result) {
+ pcd->curtable ^= 1;
+ } else {
+ memcpy(cd->out, pcd->deltaBufs[pcd->curtable], 320*200);
+ }
+
+}
+
+
+void codec37_init(PersistentCodecData37 *pcd, int width, int height) {
+ pcd->width = width;
+ pcd->height = height;
+ pcd->deltaSize = width*height*2+0x3E00+0xBA00;
+ pcd->deltaBuf = (byte*)calloc(pcd->deltaSize, 1);
+ pcd->deltaBufs[0] = pcd->deltaBuf + 0x3E00;
+ pcd->deltaBufs[1] = pcd->deltaBuf + width * height + 0xBA00;
+ pcd->curtable = 0;
+ pcd->table1 = (int16*)calloc(255,sizeof(uint16));
+}
+
+void SmushPlayer::parseFOBJ() {
+ byte codec;
+ CodecData cd;
+
+ cd.out = _renderBitmap;
+ cd.pitch = cd.outwidth = 320;
+ cd.outheight = 200;
+ cd.y = 0;
+ cd.x = 0;
+ cd.src = _cur + 0xE;
+ cd.w = *(uint16*)(_cur + 6);
+ cd.h = *(uint16*)(_cur + 8);
+
+ codec = _cur[0];
+
+ switch(codec) {
+ case 1:
+ codec1(&cd);
+ break;
+ case 37:
+ codec37(&cd, &pcd37);
+ break;
+ default:
+ error("invalid codec %d", codec);
+ }
+
+
+}
+
+void SmushPlayer::parsePSAD() {
+ //printf("parse PSAD\n");
+}
+
+void SmushPlayer::parseTRES() {
+// printf("parse TRES\n");
+}
+
+void SmushPlayer::parseXPAL() {
+ int num;
+ int i;
+
+ num = *(uint16*)(_cur + 2);
+
+ if (num==0 || num==0x200) {
+ if (num==0x200)
+ memcpy(_fluPalette, _cur + 0x604, 0x300);
+
+ for(i=0; i<0x300; i++) {
+ _fluPalMul129[i] = _fluPalette[i] * 129;
+ _fluPalWords[i] = *(uint16*)(_cur + 4 + i*2);
+ }
+ return;
+ }
+
+ for(i=0; i<0x300; i++) {
+ _fluPalMul129[i] += _fluPalWords[i];
+ _fluPalette[i] = _fluPalMul129[i]>>7;
+ }
+
+ _paletteChanged = true;
+}
+
+void SmushPlayer::parseFRME() {
+ _cur = _block;
+
+ do {
+ _frmeTag = nextBE32();
+ _frmeSize = nextBE32();
+
+ switch(_frmeTag) {
+ case 'NPAL':
+ parseNPAL();
+ break;
+ case 'FOBJ':
+ parseFOBJ();
+ break;
+ case 'PSAD':
+ parsePSAD();
+ break;
+ case 'TRES':
+ parseTRES();
+ break;
+ case 'XPAL':
+ parseXPAL();
+ break;
+ case 'IACT':
+ parseTRES();
+ break;
+ default:
+ invalidblock(_frmeTag);
+ }
+
+ _cur += (_frmeSize + 1) & ~1;
+
+ } while (_cur + 4 < _block + _blockSize);
+}
+
+void SmushPlayer::init() {
+ _renderBitmap = (byte*)malloc(320*200);
+ codec37_init(&pcd37, 320, 200);
+}
+
+void SmushPlayer::go() {
+ while (parseTag()) {}
+}
+
+
+void SmushPlayer::setPalette() {
+ int i;
+
+ for(i=0;i<768;i++)
+ sm->_currentPalette[i]=_fluPalette[i];
+}
+
+void SmushPlayer::startVideo(short int arg, byte* videoFile)
+{
+ int frameIndex=0;
+
+ _in=NULL;
+ _paletteChanged=0;
+ _block=NULL;
+ _blockTag=0;
+ _blockSize=0;
+ _cur=NULL;
+ _renderBitmap=NULL;
+ _frameSize=0;
+ _frmeTag=0;
+ _frmeSize=0;
+ _deltaBuf=NULL;
+ _deltaBufSize=0;
+
+ pcd37.deltaBuf=NULL;
+ pcd37.deltaBufs[0]=NULL;
+ pcd37.deltaBufs[1]=NULL;
+ pcd37.deltaSize=0;
+ pcd37.width=0;
+ pcd37.height=0;
+ pcd37.curtable=0;
+ pcd37.unk2=0;
+ pcd37.unk3=0;
+ pcd37.flags=0;
+ pcd37.table1=NULL;
+ pcd37.table_last_pitch=0;
+ pcd37.table_last_flags=0;
+
+
+
+ init();
+ openFile(videoFile);
+
+ if(_in==NULL)
+ return;
+
+ if (fileReadBE32() != 'ANIM')
+ error("file is not an anim");
+
+ fileSize=fileReadBE32();
+
+
+ do {
+ if(ftell(_in)>=fileSize )
+ return;
+
+ parseTag();
+
+ if (_paletteChanged) {
+ _paletteChanged = false;
+ setPalette();
+ sm->setDirtyColors(0, 255);
+ }
+
+ blitToScreen(sm,_renderBitmap, 0, 0, 320 ,200);
+
+ updateScreen(sm);
+
+ } while (1);
+}
+
diff --git a/script_v2.cpp b/script_v2.cpp
index 1fa4d4aeb9..11591fee53 100644
--- a/script_v2.cpp
+++ b/script_v2.cpp
@@ -2474,7 +2474,9 @@ void Scumm::o6_miscOps() {
grabCursor(args[1], args[2], args[3], args[4]);
break;
case 6:
- warning("o6_miscOps: startVideo(%d,%s)", args[1], getStringAddress(_vars[0xf6/2]));
+ SmushPlayer localSp;
+ localSp.sm=this;
+ localSp.startVideo(args[1], getStringAddress(_vars[0xf6/2]));
break;
case 7:
warning("o6_miscOps: stub7()");
diff --git a/scumm.h b/scumm.h
index faaa112bfa..1579ea0d71 100644
--- a/scumm.h
+++ b/scumm.h
@@ -21,7 +21,6 @@
#include "scummsys.h"
-
#define SCUMMVM_VERSION "0.1.0 devel"
#define SWAP(a,b) do{int tmp=a; a=b; b=tmp; } while(0)
@@ -30,6 +29,8 @@
struct Scumm;
struct Actor;
+#include "smush.h"
+
typedef void (Scumm::*OpcodeProc)();
/* System Wide Constants */
@@ -2069,6 +2070,8 @@ struct Scumm {
byte VAR_DEFAULT_TALK_DELAY;
byte VAR_CHARSET_MASK;
+
+ byte _videoPath[50];
};
enum AkosOpcodes{
diff --git a/scummvm.cpp b/scummvm.cpp
index f4b00c1b11..39ac2e5d80 100644
--- a/scummvm.cpp
+++ b/scummvm.cpp
@@ -222,6 +222,9 @@ void Scumm::scummMain(int argc, char **argv) {
else
setupScummVarsOld();
+ if(_gameId == GID_FT)
+ sprintf((char*)_videoPath,"VIDEO/");
+
if(_features & GF_AFTER_V7)
OF_OWNER_ROOM = 0xFF;
else
diff --git a/smush.h b/smush.h
new file mode 100644
index 0000000000..556fd4f064
--- /dev/null
+++ b/smush.h
@@ -0,0 +1,77 @@
+struct PersistentCodecData37 {
+ byte *deltaBuf;
+ byte *deltaBufs[2];
+ uint32 deltaSize;
+ uint width, height;
+ int curtable;
+ int unk2,unk3;
+
+ uint16 flags;
+
+ int16 *table1;
+ int table_last_pitch;
+ byte table_last_flags;
+};
+
+struct CodecData {
+ byte *out,*src;
+ int x,y;
+ int outwidth,outheight;
+ int w,h,pitch;
+
+ int flags;
+};
+
+
+struct SmushPlayer {
+ FILE *_in;
+ bool _paletteChanged;
+ byte * _block;
+ uint32 _blockTag;
+ uint32 _blockSize;
+ byte *_cur;
+ byte *_renderBitmap;
+ uint32 _frameSize;
+ uint32 _frmeTag, _frmeSize;
+
+ byte *_deltaBuf;
+ int _deltaBufSize;
+
+ PersistentCodecData37 pcd37;
+
+ byte _fluPalette[768];
+ uint16 _fluPalMul129[768];
+ uint16 _fluPalWords[768];
+
+ void openFile(byte* fileName);
+ void nextBlock();
+
+ uint32 fileReadBE32();
+ uint32 fileReadLE32();
+ void go();
+
+ bool parseTag();
+
+ void parseAHDR();
+ void parseFRME();
+
+ void parseNPAL();
+ void parseFOBJ();
+ void parsePSAD();
+ void parseTRES();
+ void parseXPAL();
+
+ void fileRead(void *mem, int len);
+
+ uint32 nextBE32();
+ void init();
+
+ void startVideo(short int arg, byte* videofile);
+
+ void setPalette();
+
+ long fileSize;
+
+ Scumm *sm;
+
+};