scummvm/engines/cine/anim.cpp
2006-11-23 06:43:18 +00:00

1034 lines
23 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2006 The ScummVM project
*
* cinE Engine is (C) 2004-2005 by CinE Team
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/stdafx.h"
#include "common/endian.h"
#include "common/stream.h"
#include "cine/cine.h"
#include "cine/anim.h"
#include "cine/gfx.h"
#include "cine/pal.h"
#include "cine/part.h"
#include "cine/various.h"
namespace Cine {
struct animHeader2Struct {
uint32 field_0;
uint16 width;
uint16 height;
uint16 type;
uint16 field_A;
uint16 field_C;
uint16 field_E;
};
uint16 frameVar0 = 0;
animHeaderStruct animHeader;
animDataEntry animData[] = {
{"ALPHA", 0xF},
{"TITRE2", 0xF},
{"ET", 0xC},
{"L311", 0x3},
{"L405", 0x1},
{"L515", 0xC},
{"L009", 0xE},
{"L010", 0xE},
{"FUTUR", 0x6},
{"PAYSAN3", 0xB},
{"L801", 0xC},
{"L802", 0xC},
{"L803", 0xC},
{"L901", 0xD},
{"L902", 0x8},
{"L903", 0xD},
{"L904", 0xD},
{"L905", 0xD},
{"L906", 0xD},
{"L907", 0xD},
{"LA03", 0x4},
{"MOINE", 0xB},
{"L908", 0x8},
{"L909", 0x8},
{"L807", 0xC},
{"L808", 0xC},
{"LA01", 0xB},
{"L1201", 0xC},
{"L1202", 0xC},
{"L1203", 0xC},
{"L1210", 0x5},
{"L1211", 0xC},
{"L1214", 0xC},
{"L1215", 0xC},
{"L1216", 0xC},
{"L1217", 0xC},
{"L1218", 0xC},
{"L1219", 0xC},
{"L1220", 0xC},
{"SEIGNEUR", 0x6},
{"PERE0", 0xD},
{"L1302", 0x4},
{"L1303", 0x4},
{"L1304", 0x4},
{"L1401", 0xF},
{"L1402", 0xF},
{"L1501", 0x8},
{"L1503", 0x8},
{"L1504", 0x4},
{"L1505", 0x8},
{"L1506", 0x8},
{"L1601", 0xB},
{"L1602", 0xB},
{"L1603", 0xB},
{"L1604", 0x4},
{"L1605", 0x4},
{"L1701", 0x4},
{"L1702", 0x4},
{"L1801", 0x6},
{"L1904", 0x8},
{"L2002", 0x8},
{"L2003", 0x8},
{"L2101", 0x4},
{"L2102", 0x4},
{"L2201", 0x7},
{"L2202", 0x7},
{"L2203", 0xE},
{"L2305", 0x9},
{"L2306", 0x9},
{"GARDE1", 0x7},
{"L2402", 0x7},
{"L2407", 0x7},
{"L2408", 0x7},
{"GARDE2", 0x6},
{"L2601", 0x6},
{"L2602", 0x6},
{"L2603", 0x6},
{"L2604", 0x6},
{"L2605", 0x8},
{"L2606", 0x8},
{"L2607", 0x8},
{"L2610", 0x6},
{"L2611", 0x6},
{"L2612", 0x6},
{"L2613", 0x8},
{"L2614", 0x6},
{"VOYAGEUR", 0x6},
{"L2701", 0xD},
{"L2702", 0xD},
{"L2703", 0x6},
{"L2801", 0xD},
{"L2802", 0xD},
{"L2803", 0xD},
{"L2804", 0xD},
{"L2807", 0xD},
{"L2902", 0x8},
{"L2903", 0x8},
{"L3101", 0xA},
{"L3102", 0xA},
{"L3103", 0xA},
{"L3203", 0xF},
{"L3204", 0xF},
{"L3001", 0x7},
{"L3002", 0x7},
{"L3416", 0xC},
{"L3601", 0x5},
{"L3602", 0x5},
{"L3603", 0x5},
{"L3607", 0x5},
{"L3701", 0x8},
{"L3702", 0x8},
{"L3703", 0x8},
{"L4001", 0xD},
{"L4002", 0xD},
{"L4103", 0xF},
{"L4106", 0xF},
{"CRUGHON1", 0xC},
{"L4203", 0xC},
{"L4301", 0xC},
{"L4302", 0xC},
{"L4303", 0xC},
{"FUTUR2", 0x6},
{"L4601", 0xE},
{"L4603", 0x1},
{"L4106", 0xF},
{"L4801", 0xD},
{"L4802", 0xD},
{"FIN01", 0xB},
{"FIN02", 0xB},
{"FIN03", 0xB},
{"FIN", 0x9},
};
byte getAnimTransparentColor(const char *animName) {
char name[15];
removeExtention(name, animName);
for (int i = 0; i < ARRAYSIZE(animData); i++) {
if (!strcmp(name, animData[i].name)) {
return animData[i].color;
}
}
return 0;
}
int16 allocFrame(uint16 width, uint16 height, int8 isMask) {
uint16 i;
uint32 frameSize;
for (i = 0; i < NUM_MAX_ANIMDATA; i++) {
if (!animDataTable[i].ptr1)
break;
}
if (i == NUM_MAX_ANIMDATA)
return -1;
if (!isMask) { // sprite + generated mask
frameSize = width * height;
animDataTable[i].ptr1 = (byte *)malloc(frameSize);
animDataTable[i].ptr2 = (byte *)malloc(frameSize);
animDataTable[i].width = width;
animDataTable[i].var1 = width >> 3;
animDataTable[i].bpp = 4;
animDataTable[i].height = height;
animDataTable[i].fileIdx = -1;
animDataTable[i].frameIdx = -1;
} else {
// mask
frameSize = width * height * 8;
animDataTable[i].ptr1 = (byte *)malloc(frameSize);
animDataTable[i].ptr2 = NULL;
animDataTable[i].width = width;
animDataTable[i].var1 = width >> 3;
animDataTable[i].bpp = 4;
animDataTable[i].height = height;
animDataTable[i].fileIdx = -1;
animDataTable[i].frameIdx = -1;
}
frameVar0++;
return i;
}
int16 allocFrame2(uint16 width, uint16 height, uint16 type) {
uint16 i;
uint32 frameSize;
for (i = 0; i < NUM_MAX_ANIMDATA; i++) {
if (!animDataTable[i].ptr1)
break;
}
if (i == NUM_MAX_ANIMDATA)
return -1;
frameSize = width * height;
if (type == 4) { // 16 color sprites to 256
frameSize *= 2;
type = 8;
width *= 2;
}
if (type == 5) {
frameSize += 16;
}
frameSize *= 2;
animDataTable[i].ptr1 = (byte *)malloc(frameSize);
assert(animDataTable[i].ptr1);
animDataTable[i].width = width;
if (type == 5) {
animDataTable[i].var1 = width / 8;
} else {
animDataTable[i].var1 = width / 16;
}
animDataTable[i].bpp = type;
animDataTable[i].height = height;
animDataTable[i].fileIdx = -1;
animDataTable[i].frameIdx = -1;
frameVar0++;
return i;
}
int16 reserveFrame(uint16 width, uint16 height, uint16 type, uint16 idx) {
uint16 i;
uint32 frameSize;
i = idx;
frameSize = width * height;
if (type == 4) { // 256 color sprites
frameSize *= 2;
type = 8;
width *= 2;
}
if (type == 5) {
frameSize += 16;
}
frameSize *= 2;
animDataTable[i].ptr1 = (byte *)malloc(frameSize);
assert(animDataTable[i].ptr1);
animDataTable[i].width = width;
if (type == 5) {
animDataTable[i].var1 = width / 8;
} else {
animDataTable[i].var1 = width / 16;
}
animDataTable[i].bpp = type;
animDataTable[i].height = height;
animDataTable[i].fileIdx = -1;
animDataTable[i].frameIdx = -1;
frameVar0++;
return i;
}
void generateMask(byte * sprite, byte * mask, uint16 size, byte transparency) {
uint16 i;
for (i = 0; i < size; i++) {
if (*(sprite++) != transparency) {
*(mask++) = 0;
} else {
*(mask++) = 1;
}
}
}
void convertMask(byte * dest, byte * source, int16 width, int16 height) {
int16 i;
int16 j;
for (i = 0; i < width * height; i++) {
byte maskEntry = *(source++);
for (j = 0; j < 8; j++) {
if (maskEntry & 0x80) {
*(dest++) = 0;
} else {
*(dest++) = 1;
}
maskEntry <<= 1;
}
}
}
void convert4BBP(byte * dest, byte * source, int16 width, int16 height) {
int16 i;
for (i = 0; i < width * height; i++) {
byte maskEntry = *(source++);
*(dest++) = (maskEntry & 0xF0) >> 4;
*(dest++) = (maskEntry & 0xF);
}
}
void loadSpl(const char *resourceName) {
int16 foundFileIdx;
byte *dataPtr;
int16 entry;
foundFileIdx = findFileInBundle(resourceName);
dataPtr = readBundleFile(foundFileIdx);
entry = allocFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, -1);
assert(entry != -1);
memcpy(animDataTable[entry].ptr1, dataPtr, (uint16) partBuffer[foundFileIdx].unpackedSize);
animDataTable[entry].fileIdx = foundFileIdx;
animDataTable[entry].frameIdx = 0;
strcpy(animDataTable[entry].name, currentPartName);
}
void loadMsk(const char *resourceName) {
int16 foundFileIdx;
byte *dataPtr;
int16 entry;
byte *ptr;
int16 i;
foundFileIdx = findFileInBundle(resourceName);
dataPtr = readBundleFile(foundFileIdx);
Common::MemoryReadStream readS(dataPtr, 0x16);
animHeader.field_0 = readS.readByte();
animHeader.field_1 = readS.readByte();
animHeader.field_2 = readS.readByte();
animHeader.field_3 = readS.readByte();
animHeader.frameWidth = readS.readUint16BE();
animHeader.frameHeight = readS.readUint16BE();
animHeader.field_8 = readS.readByte();
animHeader.field_9 = readS.readByte();
animHeader.field_A = readS.readByte();
animHeader.field_B = readS.readByte();
animHeader.field_C = readS.readByte();
animHeader.field_D = readS.readByte();
animHeader.numFrames = readS.readUint16BE();
animHeader.field_10 = readS.readByte();
animHeader.field_11 = readS.readByte();
animHeader.field_12 = readS.readByte();
animHeader.field_13 = readS.readByte();
animHeader.field_14 = readS.readUint16BE();
ptr = dataPtr + 0x16;
for (i = 0; i < animHeader.numFrames; i++) {
entry = allocFrame(animHeader.frameWidth * 2, animHeader.frameHeight, 1);
assert(entry != -1);
convertMask(animDataTable[entry].ptr1, ptr, animHeader.frameWidth, animHeader.frameHeight);
ptr += animHeader.frameWidth * animHeader.frameHeight;
animDataTable[entry].fileIdx = foundFileIdx;
animDataTable[entry].frameIdx = i;
strcpy(animDataTable[entry].name, currentPartName);
}
}
void loadAni(const char *resourceName) {
int16 foundFileIdx;
byte *dataPtr;
int16 entry;
byte *ptr;
int16 i;
byte transparentColor;
uint32 fullSize;
foundFileIdx = findFileInBundle(resourceName);
dataPtr = readBundleFile(foundFileIdx);
Common::MemoryReadStream readS(dataPtr, 0x16);
animHeader.field_0 = readS.readByte();
animHeader.field_1 = readS.readByte();
animHeader.field_2 = readS.readByte();
animHeader.field_3 = readS.readByte();
animHeader.frameWidth = readS.readUint16BE();
animHeader.frameHeight = readS.readUint16BE();
animHeader.field_8 = readS.readByte();
animHeader.field_9 = readS.readByte();
animHeader.field_A = readS.readByte();
animHeader.field_B = readS.readByte();
animHeader.field_C = readS.readByte();
animHeader.field_D = readS.readByte();
animHeader.numFrames = readS.readUint16BE();
animHeader.field_10 = readS.readByte();
animHeader.field_11 = readS.readByte();
animHeader.field_12 = readS.readByte();
animHeader.field_13 = readS.readByte();
animHeader.field_14 = readS.readUint16BE();
ptr = dataPtr + 0x16;
transparentColor = getAnimTransparentColor(resourceName);
fullSize = animHeader.frameWidth * animHeader.frameHeight;
for (i = 0; i < animHeader.numFrames; i++) {
byte *animPtr;
entry = allocFrame(animHeader.frameWidth * 2, animHeader.frameHeight, 0);
assert(entry != -1);
// special case transparency handling
if (!strcmp(resourceName, "L2202.ANI")) {
if (i < 2) {
transparentColor = 0;
} else {
transparentColor = 7;
}
}
if (!strcmp(resourceName, "L4601.ANI")) {
if (i < 1) {
transparentColor = 0xE;
} else {
transparentColor = 0;
}
}
animPtr = (byte *)malloc(fullSize);
memcpy(animPtr, ptr, fullSize);
ptr += fullSize;
gfxConvertSpriteToRaw(animDataTable[entry].ptr1, animPtr, animHeader.frameWidth, animHeader.frameHeight);
generateMask(animDataTable[entry].ptr1, animDataTable[entry].ptr2, animHeader.frameWidth * 2 * animHeader.frameHeight, transparentColor);
free(animPtr);
animDataTable[entry].fileIdx = foundFileIdx;
animDataTable[entry].frameIdx = i;
strcpy(animDataTable[entry].name, currentPartName);
}
}
void convert8BBP(byte * dest, byte * source, int16 width, int16 height) {
uint16 i;
byte table[16];
memcpy(table, source, 16);
source += 16;
for (i = 0; i < width * height; i++) {
byte color = *(source++);
*(dest++) = table[color >> 4];
*(dest++) = table[color & 0xF];
}
}
void convert8BBP2(byte * dest, byte * source, int16 width, int16 height) {
uint16 i;
uint16 j;
byte al;
byte ah;
byte bl;
byte bh;
byte cl;
byte ch;
byte dl;
byte dh;
byte color;
for (j = 0; j < (width * height) / 16; j++) {
al = *(source);
ah = *(source + 2);
bl = *(source + 4);
bh = *(source + 6);
cl = *(source + 8);
ch = *(source + 0xA);
dl = *(source + 0xC);
dh = *(source + 0xE);
for (i = 0; i < 8; i++) {
color = 0;
color |= ((dh & 0x080) >> 7);
dh <<= 1;
color <<= 1;
color |= ((dl & 0x080) >> 7);
dl <<= 1;
color <<= 1;
color |= ((ch & 0x080) >> 7);
ch <<= 1;
color <<= 1;
color |= ((cl & 0x080) >> 7);
cl <<= 1;
color <<= 1;
color |= ((bh & 0x080) >> 7);
bh <<= 1;
color <<= 1;
color |= ((bl & 0x080) >> 7);
bl <<= 1;
color <<= 1;
color |= ((ah & 0x080) >> 7);
ah <<= 1;
color <<= 1;
color |= ((al & 0x080) >> 7);
al <<= 1;
*(dest++) = color;
}
al = *(source + 1);
ah = *(source + 3);
bl = *(source + 5);
bh = *(source + 7);
cl = *(source + 9);
ch = *(source + 0xB);
dl = *(source + 0xD);
dh = *(source + 0xF);
for (i = 0; i < 8; i++) {
color = 0;
color |= ((dh & 0x080) >> 7);
dh <<= 1;
color <<= 1;
color |= ((dl & 0x080) >> 7);
dl <<= 1;
color <<= 1;
color |= ((ch & 0x080) >> 7);
ch <<= 1;
color <<= 1;
color |= ((cl & 0x080) >> 7);
cl <<= 1;
color <<= 1;
color |= ((bh & 0x080) >> 7);
bh <<= 1;
color <<= 1;
color |= ((bl & 0x080) >> 7);
bl <<= 1;
color <<= 1;
color |= ((ah & 0x080) >> 7);
ah <<= 1;
color <<= 1;
color |= ((al & 0x080) >> 7);
al <<= 1;
*(dest++) = color;
}
source += 0x10;
}
}
void loadSet(const char *resourceName) {
animHeader2Struct header2;
int16 foundFileIdx;
byte *dataPtr;
int16 entry;
byte *ptr;
int16 i;
uint32 fullSize;
uint16 numSpriteInAnim;
byte *startOfDataPtr;
foundFileIdx = findFileInBundle(resourceName);
dataPtr = readBundleFile(foundFileIdx);
assert(!memcmp(dataPtr, "SET", 3));
ptr = dataPtr + 4;
numSpriteInAnim = READ_BE_UINT16(ptr); ptr += 2;
startOfDataPtr = ptr + numSpriteInAnim * 0x10;
for (i = 0; i < numSpriteInAnim; i++) {
int16 typeParam;
byte table[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStream readS(ptr, 0x10);
header2.field_0 = readS.readUint32BE();
header2.width = readS.readUint16BE();
header2.height = readS.readUint16BE();
header2.type = readS.readUint16BE();
header2.field_A = readS.readUint16BE();
header2.field_C = readS.readUint16BE();
header2.field_E = readS.readUint16BE();
ptr += 0x10;
fullSize = header2.width * header2.height;
typeParam = 0;
if (header2.type == 5) {
fullSize += 16;
}
if (header2.type == 4) {
header2.type = 5;
typeParam = 1;
}
if (typeParam) {
entry = allocFrame2(header2.width * 2, header2.height, header2.type);
} else {
if (header2.type == 1) {
entry = allocFrame2(header2.width * 2, header2.height, header2.type);
} else {
entry = allocFrame2(header2.width * 2, header2.height, header2.type);
}
}
assert(entry != -1);
dataPtr = startOfDataPtr + header2.field_0;
if (typeParam) {
memcpy(animDataTable[entry].ptr1, table, 0x10);
gfxConvertSpriteToRaw(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
//memcpy(animDataTable[entry].ptr1 + 0x10, dataPtr, fullSize);
} else {
if (header2.type == 1) {
convert4BBP(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
} else if (header2.type == 5) {
convert8BBP(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
} else if (header2.type == 4) {
error("loadSet: header2.type == 4");
} else {
convert8BBP2(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
}
}
animDataTable[entry].fileIdx = foundFileIdx;
animDataTable[entry].frameIdx = i;
strcpy(animDataTable[entry].name, currentPartName);
}
}
void loadSetAbs(const char *resourceName, uint16 idx) {
animHeader2Struct header2;
int16 foundFileIdx;
byte *dataPtr;
int16 entry;
byte *ptr;
int16 i;
uint32 fullSize;
uint16 numSpriteInAnim;
byte *startOfDataPtr;
foundFileIdx = findFileInBundle(resourceName);
dataPtr = readBundleFile(foundFileIdx);
assert(!memcmp(dataPtr, "SET", 3));
ptr = dataPtr + 4;
numSpriteInAnim = READ_BE_UINT16(ptr); ptr += 2;
startOfDataPtr = ptr + numSpriteInAnim * 0x10;
for (i = 0; i < numSpriteInAnim; i++) {
int16 typeParam;
byte table[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
Common::MemoryReadStream readS(ptr, 0x10);
header2.field_0 = readS.readUint32BE();
header2.width = readS.readUint16BE();
header2.height = readS.readUint16BE();
header2.type = readS.readUint16BE();
header2.field_A = readS.readUint16BE();
header2.field_C = readS.readUint16BE();
header2.field_E = readS.readUint16BE();
ptr += 0x10;
fullSize = header2.width * header2.height;
typeParam = 0;
if (header2.type == 5) {
fullSize += 16;
}
if (header2.type == 4) {
header2.type = 5;
typeParam = 1;
}
if (typeParam) {
entry = reserveFrame(header2.width * 2, header2.height, header2.type, idx + i);
} else {
if (header2.type == 1) {
entry = reserveFrame(header2.width * 2, header2.height, header2.type, idx + i);
} else {
entry = reserveFrame(header2.width * 2, header2.height, header2.type, idx + i);
}
}
assert(entry != -1);
dataPtr = startOfDataPtr + header2.field_0;
if (typeParam) {
memcpy(animDataTable[entry].ptr1, table, 0x10);
gfxConvertSpriteToRaw(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
//memcpy(animDataTable[entry].ptr1 + 0x10, dataPtr, fullSize);
} else {
if (header2.type == 1) {
convert4BBP(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
} else if (header2.type == 5) {
convert8BBP(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
} else if (header2.type == 4) {
error("loadSetAbs: header2.type == 4");
} else {
convert8BBP2(animDataTable[entry].ptr1, dataPtr, header2.width, header2.height);
}
}
animDataTable[entry].fileIdx = foundFileIdx;
animDataTable[entry].frameIdx = i;
strcpy(animDataTable[entry].name, currentPartName);
}
}
void loadSeq(const char *resourceName) {
int16 foundFileIdx;
byte *dataPtr;
int16 entry;
foundFileIdx = findFileInBundle(resourceName);
dataPtr = readBundleFile(foundFileIdx);
entry = allocFrame2((uint16) partBuffer[foundFileIdx].unpackedSize, 1, 0);
memcpy(animDataTable[entry].ptr1, dataPtr + 0x16, (uint16) partBuffer[foundFileIdx].unpackedSize - 0x16);
}
void loadSeqAbs(const char *resourceName, uint16 idx) {
int16 foundFileIdx;
byte *dataPtr;
int16 entry;
foundFileIdx = findFileInBundle(resourceName);
dataPtr = readBundleFile(foundFileIdx);
entry = reserveFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, 0, idx);
memcpy(animDataTable[entry].ptr1, dataPtr + 0x16, (uint16) partBuffer[foundFileIdx].unpackedSize - 0x16);
}
void loadResource(const char *resourceName) {
/* byte isMask = 0; */
/* byte isSpl = 0; */
if (strstr(resourceName, ".SPL")) {
loadSpl(resourceName);
return;
} else if (strstr(resourceName, ".MSK")) {
loadMsk(resourceName);
return;
} else if (strstr(resourceName, ".ANI")) {
loadAni(resourceName);
return;
} else if (strstr(resourceName, ".ANM")) {
loadAni(resourceName);
return;
} else if (strstr(resourceName, ".SET")) {
loadSet(resourceName);
return;
} else if (strstr(resourceName, ".SEQ")) {
loadSeq(resourceName);
return;
} else if (strstr(resourceName, "ECHEC")) {
exitEngine = 1;
return;
}
error("loadResource: Cannot determine type for '%s'", resourceName);
}
void loadAbs(const char *resourceName, uint16 idx) {
/* byte isMask = 0; */
/* byte isSpl = 0; */
if (strstr(resourceName, ".SET")) {
loadSetAbs(resourceName, idx);
return;
} else if (strstr(resourceName, ".H32")) {
return;
} else if (strstr(resourceName, ".SEQ")) {
loadSeqAbs(resourceName, idx);
return;
} else if (strstr(resourceName, ".SPL")) {
return;
} else if (strstr(resourceName, ".AMI")) {
return;
} else if (strstr(resourceName, ".ANI")) {
return;
}
error("loadAbs: Cannot determine type for '%s'", resourceName);
}
void loadResourcesFromSave() {
char part[256];
int16 currentAnim;
strcpy(part, currentPartName);
for (currentAnim = 0; currentAnim < NUM_MAX_ANIMDATA; currentAnim++) {
AnimData *currentPtr = &animDataTable[currentAnim];
if (currentPtr->refresh && currentPtr->fileIdx != -1) {
int8 isMask = 0;
int8 isSpl = 0;
int16 foundFileIdx;
byte *dataPtr;
byte *ptr;
char animName[256];
if (strcmp(currentPartName, currentPtr->name)) {
closePart();
loadPart(currentPtr->name);
}
foundFileIdx = currentPtr->fileIdx;
strcpy(animName, partBuffer[foundFileIdx].partName);
if (strstr(animName, ".SPL")) {
isSpl = 1;
} else {
isSpl = 0;
}
dataPtr = readBundleFile(foundFileIdx);
ptr = dataPtr;
if (strstr(animName, ".MSK")) {
isMask = 1;
}
if (isSpl) {
animHeader.frameWidth = (uint16) partBuffer[foundFileIdx].unpackedSize;
animHeader.frameHeight = 1;
animHeader.numFrames = 1;
isMask = -1;
} else {
Common::MemoryReadStream readS(ptr, 0x22);
animHeader.field_0 = readS.readByte();
animHeader.field_1 = readS.readByte();
animHeader.field_2 = readS.readByte();
animHeader.field_3 = readS.readByte();
animHeader.frameWidth = readS.readUint16BE();
animHeader.frameHeight = readS.readUint16BE();
animHeader.field_8 = readS.readByte();
animHeader.field_9 = readS.readByte();
animHeader.field_A = readS.readByte();
animHeader.field_B = readS.readByte();
animHeader.field_C = readS.readByte();
animHeader.field_D = readS.readByte();
animHeader.numFrames = readS.readUint16BE();
animHeader.field_10 = readS.readByte();
animHeader.field_11 = readS.readByte();
animHeader.field_12 = readS.readByte();
animHeader.field_13 = readS.readByte();
animHeader.field_14 = readS.readUint16BE();
ptr += 0x16;
}
{
uint16 fullSize;
uint16 i;
byte transparentColor;
fullSize = animHeader.frameWidth * animHeader.frameHeight;
loadRelatedPalette(animName);
transparentColor = getAnimTransparentColor(animName);
for (i = 0; i < animHeader.numFrames; i++) { // load all the frames
int16 entry;
byte *animPtr;
// special case transparency handling
if (!strcmp(animName, "L2202.ANI")) {
if (i < 2) {
transparentColor = 0;
} else {
transparentColor = 7;
}
}
if (!strcmp(animName, "L4601.ANI")) {
if (i < 1) {
transparentColor = 0xE;
} else {
transparentColor = 0;
}
}
currentPtr[i].ptr1 = NULL;
entry = allocFrame(animHeader.frameWidth * 2, animHeader.frameHeight, isMask);
currentPtr->fileIdx = foundFileIdx;
assert(entry != -1);
if (isSpl) {
memcpy(animDataTable[entry].ptr1, ptr, fullSize);
ptr += fullSize;
} else {
if (!isMask) {
animPtr = (byte *)malloc(fullSize);
memcpy(animPtr, ptr, fullSize);
ptr += fullSize;
gfxConvertSpriteToRaw(animDataTable[entry].ptr1, animPtr,
animHeader.frameWidth, animHeader.frameHeight);
generateMask(animDataTable[entry].ptr1, animDataTable[entry].ptr2,
animHeader.frameWidth * 2 *animHeader.frameHeight, transparentColor);
free(animPtr);
} else {
convertMask(animDataTable[entry].ptr1, ptr, animHeader.frameWidth,
animHeader.frameHeight);
ptr += fullSize;
}
}
//animDataTable[entry].fileIdx = foundFileIdx; // Only when reading from bundles
animDataTable[entry].frameIdx = i;
strcpy(animDataTable[entry].name, currentPartName);
}
}
}
}
loadPart(part);
}
} // End of namespace Cine