mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-23 02:44:56 +00:00
badb5218fa
element to the savefile, including data pointers. After reading the savefile, it would then test if ptr1 was NULL, to see if it should load the object. I've extended the savefile format with a byte to indicate whether or not ptr1 was non-NULL. This seems to fix the problems I had with with loading savegames, but of course any old savegame is now even more broken than before. I still can't seem to get out of the room with the machine, though. Another regression when migrating the code from cinE, or just my ability to get past this annoying, timed puzzle? svn-id: r21772
978 lines
21 KiB
C++
978 lines
21 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 "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);
|
|
|
|
ptr = dataPtr;
|
|
|
|
memcpy(&animHeader, ptr, sizeof(animHeaderStruct));
|
|
ptr += sizeof(animHeaderStruct);
|
|
|
|
animHeader.frameWidth = TO_BE_16(animHeader.frameWidth);
|
|
animHeader.frameHeight = TO_BE_16(animHeader.frameHeight);
|
|
animHeader.numFrames = TO_BE_16(animHeader.numFrames);
|
|
|
|
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);
|
|
|
|
ptr = dataPtr;
|
|
|
|
memcpy(&animHeader, ptr, sizeof(animHeaderStruct));
|
|
ptr += sizeof(animHeaderStruct);
|
|
|
|
animHeader.frameWidth = TO_BE_16(animHeader.frameWidth);
|
|
animHeader.frameHeight = TO_BE_16(animHeader.frameHeight);
|
|
animHeader.numFrames = TO_BE_16(animHeader.numFrames);
|
|
|
|
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 };
|
|
|
|
memcpy(&header2, ptr, 0x10);
|
|
ptr += 0x10;
|
|
|
|
header2.field_0 = TO_BE_32(header2.field_0);
|
|
header2.width = TO_BE_16(header2.width);
|
|
header2.height = TO_BE_16(header2.height);
|
|
header2.type = TO_BE_16(header2.type);
|
|
|
|
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 };
|
|
|
|
memcpy(&header2, ptr, 0x10);
|
|
ptr += 0x10;
|
|
|
|
header2.field_0 = TO_BE_32(header2.field_0);
|
|
header2.width = TO_BE_16(header2.width);
|
|
header2.height = TO_BE_16(header2.height);
|
|
header2.type = TO_BE_16(header2.type);
|
|
|
|
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;
|
|
}
|
|
|
|
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 (refreshAnimData[currentAnim] && 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 {
|
|
memcpy(&animHeader, ptr, sizeof(animHeaderStruct));
|
|
ptr += sizeof(animHeaderStruct);
|
|
|
|
animHeader.frameWidth = TO_BE_16(animHeader.frameWidth);
|
|
animHeader.frameHeight = TO_BE_16(animHeader.frameHeight);
|
|
animHeader.numFrames = TO_BE_16(animHeader.numFrames);
|
|
}
|
|
|
|
{
|
|
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
|