svn-id: r31431

This commit is contained in:
Florian Kagerer 2008-04-06 14:57:01 +00:00
parent ebe249f4f7
commit 22efb801d4
6 changed files with 367 additions and 185 deletions

View File

@ -215,18 +215,19 @@ void KyraEngine_v2::updateItemAnimations() {
if (_itemAnimData[0].itemIndex == -1 || _inventorySaved)
return;
ItemAnimData *s = &_itemAnimData[_nextAnimItem++];
const ItemAnimData_v2 *s = &_itemAnimData[_nextAnimItem];
ActiveItemAnim *a = &_activeItemAnim[_nextAnimItem];
if (s->itemIndex == -1) {
if (++_nextAnimItem == 14) {
_nextAnimItem = 0;
return;
}
uint32 ctime = _system->getMillis();
if (ctime < s->nextFrame)
if (ctime < a->nextFrame)
return;
uint16 shpIdx = READ_LE_UINT16(s->frames + (s->curFrame << 2)) + 64;
uint16 shpIdx = s->frames[a->currentFrame].index + 64;
if ((s->itemIndex == _handItemSet || s->itemIndex == _itemInHand) && (!_mouseState && _screen->isMouseVisible())) {
nextFrame = true;
_screen->setMouseCursor(8, 15, getShapePtr(shpIdx));
@ -264,8 +265,8 @@ void KyraEngine_v2::updateItemAnimations() {
}
if (nextFrame) {
s->nextFrame = _system->getMillis() + READ_LE_UINT16(s->frames + (s->curFrame << 2) + 2) * _tickLength;
s->curFrame = ++s->curFrame % s->numFrames;
a->nextFrame = _system->getMillis() + (s->frames[a->currentFrame].delay * _tickLength);
a->currentFrame = ++a->currentFrame % s->numFrames;
}
}

View File

@ -51,8 +51,6 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngi
_activeText = 0;
_seqWsa = 0;
_sequences = 0;
_nSequences = 0;
_demoShapeDefs = 0;
_sequenceSoundList = 0;
_showCredits = false;
@ -97,8 +95,12 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngi
_currentTalkSections.ENDTim = NULL;
memset(&_invWsa, 0, sizeof(_invWsa));
_itemAnimTable = 0;
_itemAnimData = 0;
_demoAnimData = 0;
_nextAnimItem = 0;
for (int i = 0; i < 15; i++)
memset(&_activeItemAnim[i], 0, sizeof(ActiveItemAnim));
_colorCodeFlag1 = 0;
_colorCodeFlag2 = -1;
@ -150,11 +152,6 @@ KyraEngine_v2::~KyraEngine_v2() {
cleanup();
seq_uninit();
if (_sequences)
delete [] _sequences;
if (_nSequences)
delete [] _nSequences;
delete [] _mouseSHPBuf;
delete _screen;
delete _text;
@ -186,6 +183,8 @@ Movie *KyraEngine_v2::createWSAMovie() {
int KyraEngine_v2::init() {
_screen = new Screen_v2(this, _system);
assert(_screen);
if (!_screen->init())
error("_screen->init() failed");
KyraEngine::init();
initStaticResource();

View File

@ -100,7 +100,12 @@ class KyraEngine_v2;
class TextDisplayer_v2;
class Debugger_v2;
typedef int (KyraEngine_v2::*Seqproc)(WSAMovieV2*, int, int, int);
typedef int (KyraEngine_v2::*SeqProc)(WSAMovieV2*, int, int, int);
struct FrameControl {
uint16 index;
uint16 delay;
};
struct ActiveWSA {
int16 flags;
@ -108,13 +113,13 @@ struct ActiveWSA {
uint16 startFrame;
uint16 endFrame;
uint16 frameDelay;
Seqproc callback;
SeqProc callback;
uint32 nextFrame;
uint16 currentFrame;
uint16 lastFrame;
uint16 x;
uint16 y;
const uint16 *control;
const FrameControl *control;
uint16 startupCommand;
uint16 finalCommand;
};
@ -142,7 +147,6 @@ struct Sequence {
uint16 frameDelay;
uint16 xPos;
uint16 yPos;
Seqproc callback;
uint16 duration;
};
@ -152,14 +156,37 @@ struct NestedSequence {
uint16 startframe;
uint16 endFrame;
uint16 frameDelay;
Seqproc callback;
uint16 x;
uint16 y;
const uint16 * wsaControl;
const FrameControl *wsaControl;
uint16 startupCommand;
uint16 finalCommand;
};
struct HofSeqData {
const Sequence *seq;
int numSeq;
const NestedSequence *seqn;
int numSeqn;
};
struct ItemAnimData_v1 {
int16 itemIndex;
uint16 y;
const uint16 *frames;
};
struct ItemAnimData_v2 {
int16 itemIndex;
uint8 numFrames;
const FrameControl *frames;
};
struct ActiveItemAnim {
uint16 currentFrame;
uint32 nextFrame;
};
class KyraEngine_v2 : public KyraEngine {
friend class Debugger_v2;
friend class TextDisplayer_v2;
@ -597,14 +624,7 @@ protected:
void scrollInventoryWheel();
int findFreeVisibleInventorySlot();
struct ItemAnimData {
int16 itemIndex;
uint8 numFrames;
uint8 curFrame;
uint32 nextFrame;
const uint8 *frames;
} _itemAnimData[15];
ActiveItemAnim _activeItemAnim[15];
int _nextAnimItem;
// gui
@ -1145,9 +1165,13 @@ protected:
const uint16 *_ingameTalkObjIndex;
int _ingameTalkObjIndexSize;
const char *const *_ingameTimJpStr;
int _ingameTimJpStrSize;
const uint8 *_itemAnimTable;
uint8 *_demoShapeDefs;
int _ingameTimJpStrSize;
const HofSeqData *_sequences;
const ItemAnimData_v2 *_itemAnimData;
int _itemAnimDataSize;
const ItemAnimData_v1 *_demoAnimData;
int _demoAnimSize;
int _sequenceStringsDuration[33];
static const uint8 _seqTextColorPresets[];
@ -1168,8 +1192,8 @@ protected:
uint8 _seqTextColor[2];
uint8 _seqTextColorMap[16];
Sequence *_sequences;
NestedSequence *_nSequences;
const SeqProc *_callbackS;
const SeqProc *_callbackN;
static const uint8 _rainbowRoomData[];

View File

@ -37,6 +37,7 @@
#include "common/ptr.h"
#include "kyra/kyra.h"
#include "kyra/kyra_v2.h"
namespace Kyra {
@ -215,7 +216,7 @@ enum kKyraResources {
k2SeqplayFinaleTracks,
k2SeqplayIntroCDA,
k2SeqplayFinaleCDA,
k2SeqplayShapeDefs,
k2SeqplayShapeAnimData,
k2IngamePakFiles,
k2IngameSfxFiles,
@ -224,7 +225,7 @@ enum kKyraResources {
k2IngameCDA,
k2IngameTalkObjIndex,
k2IngameTimJpStrings,
k2IngameItemAnimTable,
k2IngameShapeAnimData,
kMaxResIDs
};
@ -249,6 +250,9 @@ public:
const Shape *loadShapeTable(int id, int &entries);
const Room *loadRoomTable(int id, int &entries);
const uint8 * const*loadPaletteTable(int id, int &entries);
const HofSeqData *loadHofSequenceData(int id, int &entries);
const ItemAnimData_v1 *loadHofShapeAnimDataV1(int id, int &entries);
const ItemAnimData_v2 *loadHofShapeAnimDataV2(int id, int &entries);
// use '-1' to prefetch/unload all ids
// prefetchId retruns false if only on of the resources
@ -275,12 +279,18 @@ private:
bool loadShapeTable(const char *filename, void *&ptr, int &size);
bool loadRoomTable(const char *filename, void *&ptr, int &size);
bool loadPaletteTable(const char *filename, void *&ptr, int &size);
bool loadHofSequenceData(const char *filename, void *&ptr, int &size);
bool loadHofShapeAnimDataV1(const char *filename, void *&ptr, int &size);
bool loadHofShapeAnimDataV2(const char *filename, void *&ptr, int &size);
void freeRawData(void *&ptr, int &size);
void freeStringTable(void *&ptr, int &size);
void freeShapeTable(void *&ptr, int &size);
void freeRoomTable(void *&ptr, int &size);
void freePaletteTable(void *&ptr, int &size);
void freeHofSequenceData(void *&ptr, int &size);
void freeHofShapeAnimDataV1(void *&ptr, int &size);
void freeHofShapeAnimDataV2(void *&ptr, int &size);
const char *getFilename(const char *name);
uint8 *getFile(const char *name, int &size);
@ -293,7 +303,9 @@ private:
kRawData,
kPaletteTable,
k2SeqData
k2SeqData,
k2ShpAnimDataV1,
k2ShpAnimDataV2
};
struct BuiltinRes {

View File

@ -83,8 +83,11 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
allowSkip = (!(_flags.isDemo && !_flags.isTalkie) && (seqNum == kSequenceTitle)) ? false : true;
if (_sequences[seqNum].flags & 2) {
_screen->loadBitmap(_sequences[seqNum].cpsFile, 2, 2, _screen->getPalette(0));
Sequence cseq = _sequences->seq[seqNum];
SeqProc cb = _callbackS[seqNum];
if (cseq.flags & 2) {
_screen->loadBitmap(cseq.cpsFile, 2, 2, _screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
} else {
_screen->setCurPage(2);
@ -92,29 +95,29 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
_screen->loadPalette("goldfont.col", _screen->getPalette(0));
}
if (_sequences[seqNum].callback && !(_flags.isDemo && !_flags.isTalkie))
(this->*_sequences[seqNum].callback)(0, 0, 0, -1);
if (cb && !(_flags.isDemo && !_flags.isTalkie))
(this->*cb)(0, 0, 0, -1);
if (_sequences[seqNum].flags & 1) {
if (cseq.flags & 1) {
_seqWsa->close();
_seqWsa->open(_sequences[seqNum].wsaFile, 0, _screen->getPalette(0));
_seqWsa->open(cseq.wsaFile, 0, _screen->getPalette(0));
_screen->setScreenPalette(_screen->getPalette(0));
_seqWsa->setX(_sequences[seqNum].xPos);
_seqWsa->setY(_sequences[seqNum].yPos);
_seqWsa->setX(cseq.xPos);
_seqWsa->setY(cseq.yPos);
_seqWsa->setDrawPage(2);
_seqWsa->displayFrame(0, 0);
}
if (_sequences[seqNum].flags & 4) {
if (cseq.flags & 4) {
int cp = _screen->setCurPage(2);
Screen::FontId cf = _screen->setFont(Screen::FID_GOLDFONT_FNT);
if (_sequences[seqNum].stringIndex1 != -1) {
int sX = (320 - _screen->getTextWidth(_sequenceStrings[_sequences[seqNum].stringIndex1])) / 2;
_screen->printText(_sequenceStrings[_sequences[seqNum].stringIndex1], sX, 100 - _screen->getFontHeight(), 1, 0);
if (cseq.stringIndex1 != -1) {
int sX = (320 - _screen->getTextWidth(_sequenceStrings[cseq.stringIndex1])) / 2;
_screen->printText(_sequenceStrings[cseq.stringIndex1], sX, 100 - _screen->getFontHeight(), 1, 0);
}
if (_sequences[seqNum].stringIndex2 != -1) {
int sX = (320 - _screen->getTextWidth(_sequenceStrings[_sequences[seqNum].stringIndex2])) / 2;
_screen->printText(_sequenceStrings[_sequences[seqNum].stringIndex2], sX, 100, 1, 0);
if (cseq.stringIndex2 != -1) {
int sX = (320 - _screen->getTextWidth(_sequenceStrings[cseq.stringIndex2])) / 2;
_screen->printText(_sequenceStrings[cseq.stringIndex2], sX, 100, 1, 0);
}
_screen->setFont(cf);
_screen->setCurPage(cp);
@ -125,20 +128,20 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
_screen->copyPage(2, 10);
_screen->copyPage(12, 2);
seq_sequenceCommand(_sequences[seqNum].startupCommand);
seq_sequenceCommand(cseq.startupCommand);
if (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_screen->copyPage(2, 0);
_screen->updateScreen();
}
if (_sequences[seqNum].flags & 1) {
if (cseq.flags & 1) {
int w2 = _seqWsa->width();
int h2 = _seqWsa->height();
int x = _sequences[seqNum].xPos;
int y = _sequences[seqNum].yPos;
int x = cseq.xPos;
int y = cseq.yPos;
_seqFrameDelay = _sequences[seqNum].frameDelay;
_seqFrameDelay = cseq.frameDelay;
if (_seqWsa) {
if (x < 0) {
@ -151,31 +154,31 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
h2 = 0;
}
if (_sequences[seqNum].xPos + _seqWsa->width() > 319)
_seqWsa->setWidth(320 - _sequences[seqNum].xPos);
if (cseq.xPos + _seqWsa->width() > 319)
_seqWsa->setWidth(320 - cseq.xPos);
if (_sequences[seqNum].yPos + _seqWsa->height() > 199)
_seqWsa->setHeight(199 - _sequences[seqNum].yPos);
if (cseq.yPos + _seqWsa->height() > 199)
_seqWsa->setHeight(199 - cseq.yPos);
}
uint8 dir = (_sequences[seqNum].startFrame > _sequences[seqNum].numFrames) ? 0 : 1;
_seqWsaCurrentFrame = _sequences[seqNum].startFrame;
uint8 dir = (cseq.startFrame > cseq.numFrames) ? 0 : 1;
_seqWsaCurrentFrame = cseq.startFrame;
bool loop = true;
while (loop && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength;
if (_seqWsa || !_sequences[seqNum].callback)
if (_seqWsa || !cb)
_screen->copyPage(12, 2);
if (_sequences[seqNum].callback) {
if (cb) {
int f = _seqWsaCurrentFrame % _seqWsa->frames();
(this->*_sequences[seqNum].callback)(_seqWsa, _sequences[seqNum].xPos, _sequences[seqNum].yPos, f);
(this->*cb)(_seqWsa, cseq.xPos, cseq.yPos, f);
}
if (_seqWsa) {
int f = _seqWsaCurrentFrame % _seqWsa->frames();
_seqWsa->setX(_sequences[seqNum].xPos);
_seqWsa->setY(_sequences[seqNum].yPos);
_seqWsa->setX(cseq.xPos);
_seqWsa->setY(cseq.yPos);
_seqWsa->setDrawPage(2);
_seqWsa->displayFrame(f, 0);
}
@ -185,7 +188,7 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
seq_processWSAs();
seq_processText();
if ((_seqWsa || !_sequences[seqNum].callback) && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
if ((_seqWsa || !cb) && !((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
_screen->copyPage(2, 0);
_screen->updateScreen();
}
@ -214,23 +217,23 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
if (loop) {
if (dir == 1) {
if (++_seqWsaCurrentFrame >= _sequences[seqNum].numFrames)
if (++_seqWsaCurrentFrame >= cseq.numFrames)
loop = false;
} else {
if (--_seqWsaCurrentFrame < _sequences[seqNum].numFrames)
if (--_seqWsaCurrentFrame < cseq.numFrames)
loop = false;
}
}
}
_seqWsa->close();
} else {
_seqFrameDelay = _sequences[seqNum].frameDelay;
_seqFrameDelay = cseq.frameDelay;
_seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength;
while (!((skipFlag() && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
uint32 starttime = _system->getMillis();
seq_processWSAs();
if (_sequences[seqNum].callback)
(this->*_sequences[seqNum].callback)(0, 0, 0, 0);
if (cb)
(this->*cb)(0, 0, 0, 0);
seq_processText();
@ -249,11 +252,11 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
}
}
if (_sequences[seqNum].callback && !(_flags.isDemo && !_flags.isTalkie))
(this->*_sequences[seqNum].callback)(0, 0, 0, -2);
if (cb && !(_flags.isDemo && !_flags.isTalkie))
(this->*cb)(0, 0, 0, -2);
uint32 ct = seq_activeTextsTimeLeft();
uint32 dl = _sequences[seqNum].duration * _tickLength;
uint32 dl = cseq.duration * _tickLength;
if (dl < ct)
dl = ct;
_seqEndTime = _system->getMillis() + dl;
@ -277,7 +280,7 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
delay(MIN<uint32>(dly, tdiff));
}
seq_sequenceCommand(_sequences[seqNum].finalCommand);
seq_sequenceCommand(cseq.finalCommand);
seq_resetAllTextEntries();
if (_flags.isDemo && !_flags.isTalkie) {
@ -2038,7 +2041,7 @@ void KyraEngine_v2::seq_loadNestedSequence(int wsaNum, int seqNum) {
if (_activeWSA[wsaNum].flags != -1)
return;
NestedSequence s = _nSequences[seqNum];
NestedSequence s = _sequences->seqn[seqNum];
if (!_activeWSA[wsaNum].movie) {
_activeWSA[wsaNum].movie = new WSAMovieV2(this);
@ -2061,7 +2064,7 @@ void KyraEngine_v2::seq_loadNestedSequence(int wsaNum, int seqNum) {
_activeWSA[wsaNum].movie->setX(0);
_activeWSA[wsaNum].movie->setY(0);
_activeWSA[wsaNum].movie->setDrawPage(_screen->_curPage);
_activeWSA[wsaNum].callback = s.callback;
_activeWSA[wsaNum].callback = _callbackN[seqNum];
_activeWSA[wsaNum].control = s.wsaControl;
_activeWSA[wsaNum].flags = s.flags | 1;
@ -2232,8 +2235,8 @@ bool KyraEngine_v2::seq_processNextSubFrame(int wsaNum) {
_activeWSA[wsaNum].movie->setY(_activeWSA[wsaNum].y);
if (_activeWSA[wsaNum].flags & 0x20) {
_activeWSA[wsaNum].movie->displayFrame(READ_LE_UINT16(&_activeWSA[wsaNum].control[currentFrame * 2]), 0x4000);
_activeWSA[wsaNum].frameDelay = READ_LE_UINT16(&_activeWSA[wsaNum].control[currentFrame * 2 + 1]);
_activeWSA[wsaNum].movie->displayFrame(_activeWSA[wsaNum].control[currentFrame].index, 0x4000);
_activeWSA[wsaNum].frameDelay = _activeWSA[wsaNum].control[currentFrame].delay;
} else {
_activeWSA[wsaNum].movie->displayFrame(currentFrame % _activeWSA[wsaNum].movie->frames(), 0x4000);
}
@ -2555,14 +2558,14 @@ void KyraEngine_v2::seq_scrollPage() {
if (dstH > 0) {
for (int i = 0; i < 4; i++) {
int p = _screen->setCurPage(4);
uint8 *def = _demoShapeDefs + 46 * i;
_screen->drawBox(12, READ_LE_UINT16(def + 2) - 8, 28, READ_LE_UINT16(def + 2) + 8, 0);
const ItemAnimData_v1 *def = &_demoAnimData[i];
ActiveItemAnim *a = &_activeItemAnim[i];
_screen->drawBox(12, def->y - 8, 28, def->y + 8, 0);
_screen->setCurPage(p);
_screen->drawShape(4, _defaultShapeTable[READ_LE_UINT16(def) + READ_LE_UINT16(def + 6 + (READ_LE_UINT16(def + 4) << 1))], 12, READ_LE_UINT16(def + 2) - 8, 0, 0);
if(_seqFrameCounter % 2 == 0){
uint16 frame = READ_LE_UINT16(def + 4);
WRITE_LE_UINT16(def + 4, ++frame % 20);
}
_screen->drawShape(4, _defaultShapeTable[def->itemIndex + def->frames[a->currentFrame]], 12, def->y - 8, 0, 0);
if(_seqFrameCounter % 2 == 0)
a->currentFrame = ++a->currentFrame % 20;
}
_screen->copyRegionEx(4, 0, srcH, 2, 2, dstY + 24, 320, dstH, &d);
}
@ -2621,12 +2624,7 @@ void KyraEngine_v2::seq_init() {
int numShp = -1;
if (_flags.isDemo && !_flags.isTalkie) {
int size;
const uint8 *tmp = _staticres->loadRawData(k2SeqplayShapeDefs, size);
_demoShapeDefs = new uint8[size];
memcpy(_demoShapeDefs, tmp, size);
_staticres->unloadId(k2SeqplayShapeDefs);
_demoAnimData = _staticres->loadHofShapeAnimDataV1(k2SeqplayShapeAnimData, _itemAnimDataSize);
uint8 *shp = _res->fileData("icons.shp", 0);
uint32 outsize = READ_LE_UINT16(shp + 4);
_newShapeFiledata = new uint8[outsize];
@ -2653,14 +2651,12 @@ void KyraEngine_v2::seq_uninit() {
delete _seqWsa;
_seqWsa = NULL;
if (_demoShapeDefs) {
delete [] _demoShapeDefs;
_demoShapeDefs = 0;
}
delete [] _newShapeFiledata;
_newShapeFiledata = 0;
if (_flags.isDemo && !_flags.isTalkie)
_staticres->unloadId(k2SeqplayShapeAnimData);
memset(&_defaultShapeTable, 0, sizeof(_defaultShapeTable));
}

View File

@ -36,7 +36,7 @@
namespace Kyra {
#define RESFILE_VERSION 22
#define RESFILE_VERSION 23
bool StaticResource::checkKyraDat() {
Common::File kyraDat;
@ -134,6 +134,11 @@ bool StaticResource::init() {
{ kShapeList, proc(loadShapeTable), proc(freeShapeTable) },
{ kRawData, proc(loadRawData), proc(freeRawData) },
{ kPaletteTable, proc(loadPaletteTable), proc(freePaletteTable) },
{ k2SeqData, proc(loadHofSequenceData), proc(freeHofSequenceData) },
{ k2ShpAnimDataV1, proc(loadHofShapeAnimDataV1), proc(freeHofShapeAnimDataV1) },
{ k2ShpAnimDataV2, proc(loadHofShapeAnimDataV2), proc(freeHofShapeAnimDataV2) },
{ 0, 0, 0 }
};
#undef proc
@ -233,12 +238,12 @@ bool StaticResource::init() {
{ k2SeqplayStrings, kLanguageList, "S_STRINGS." },
{ k2SeqplaySfxFiles, kStringList, "S_SFXFILES.TXT" },
{ k2SeqplayTlkFiles, kLanguageList, "S_TLKFILES." },
{ k2SeqplaySeqData, kRawData, "S_DATA.SEQ" },
{ k2SeqplaySeqData, k2SeqData, "S_DATA.SEQ" },
{ k2SeqplayIntroTracks, kStringList, "S_INTRO.TRA" },
{ k2SeqplayFinaleTracks, kStringList, "S_FINALE.TRA" },
{ k2SeqplayIntroCDA, kRawData, "S_INTRO.CDA" },
{ k2SeqplayFinaleCDA, kRawData, "S_FINALE.CDA" },
{ k2SeqplayShapeDefs, kRawData, "S_DEMO.SHP" },
{ k2SeqplayShapeAnimData, k2ShpAnimDataV1, "S_DEMO.SHP" },
// Ingame
{ k2IngamePakFiles, kStringList, "I_PAKFILES.TXT" },
@ -248,7 +253,7 @@ bool StaticResource::init() {
{ k2IngameCDA, kRawData, "I_TRACKS.CDA" },
{ k2IngameTalkObjIndex, kRawData, "I_TALKOBJECTS.MAP" },
{ k2IngameTimJpStrings, kStringList, "I_TIMJPSTR.TXT" },
{ k2IngameItemAnimTable, kRawData, "I_INVANIM.SHP" },
{ k2IngameShapeAnimData, k2ShpAnimDataV2, "I_INVANIM.SHP" },
{ 0, 0, 0 }
};
@ -327,6 +332,18 @@ const uint8 * const*StaticResource::loadPaletteTable(int id, int &entries) {
return (const uint8* const*)getData(id, kPaletteTable, entries);
}
const HofSeqData *StaticResource::loadHofSequenceData(int id, int &entries) {
return (const HofSeqData*)getData(id, k2SeqData, entries);
}
const ItemAnimData_v1 *StaticResource::loadHofShapeAnimDataV1(int id, int &entries) {
return (const ItemAnimData_v1*)getData(id, k2ShpAnimDataV1, entries);
}
const ItemAnimData_v2 *StaticResource::loadHofShapeAnimDataV2(int id, int &entries) {
return (const ItemAnimData_v2*)getData(id, k2ShpAnimDataV2, entries);
}
bool StaticResource::prefetchId(int id) {
if (id == -1) {
for (int i = 0; _filenameTable[i].filename; ++i)
@ -605,6 +622,175 @@ bool StaticResource::loadPaletteTable(const char *filename, void *&ptr, int &siz
return true;
}
bool StaticResource::loadHofSequenceData(const char *filename, void *&ptr, int &size) {
int filesize;
uint8 *filePtr = getFile(filename, filesize);
if (!filePtr)
return false;
uint16 *hdr = (uint16 *) filePtr;
int numSeq = READ_BE_UINT16(hdr++);
Sequence *tmp_s = new Sequence[numSeq];
char *tmp_c = 0;
size = sizeof(HofSeqData) + numSeq * (sizeof(Sequence) + 28);
for (int i = 0; i < numSeq; i++) {
const uint8 *offset = (const uint8 *)(filePtr + READ_BE_UINT16(hdr++));
tmp_s[i].flags = READ_BE_UINT16(offset);
offset += 2;
tmp_c = new char[14];
memcpy(tmp_c, offset, 14);
tmp_s[i].wsaFile = tmp_c;
offset += 14;
tmp_c = new char[14];
memcpy(tmp_c, offset, 14);
tmp_s[i].cpsFile = tmp_c;
offset += 14;
tmp_s[i].startupCommand = *offset++;
tmp_s[i].finalCommand = *offset++;
tmp_s[i].stringIndex1 = READ_BE_UINT16(offset);
offset += 2;
tmp_s[i].stringIndex2 = READ_BE_UINT16(offset);
offset += 2;
tmp_s[i].startFrame = READ_BE_UINT16(offset);
offset += 2;
tmp_s[i].numFrames = READ_BE_UINT16(offset);
offset += 2;
tmp_s[i].frameDelay = READ_BE_UINT16(offset);
offset += 2;
tmp_s[i].xPos = READ_BE_UINT16(offset);
offset += 2;
tmp_s[i].yPos = READ_BE_UINT16(offset);
offset += 2;
tmp_s[i].duration = READ_BE_UINT16(offset);
}
int numSeqN = READ_BE_UINT16(hdr++);
NestedSequence *tmp_n = new NestedSequence[numSeqN];
size += (numSeqN * (sizeof(NestedSequence) + 14));
for (int i = 0; i < numSeqN; i++) {
const uint8 *offset = (const uint8 *)(filePtr + READ_BE_UINT16(hdr++));
tmp_n[i].flags = READ_BE_UINT16(offset);
offset += 2;
tmp_c = new char[14];
memcpy(tmp_c, offset, 14);
tmp_n[i].wsaFile = tmp_c;
offset += 14;
tmp_n[i].startframe = READ_BE_UINT16(offset);
offset += 2;
tmp_n[i].endFrame = READ_BE_UINT16(offset);
offset += 2;
tmp_n[i].frameDelay = READ_BE_UINT16(offset);
offset += 2;
tmp_n[i].x = READ_BE_UINT16(offset);
offset += 2;
tmp_n[i].y = READ_BE_UINT16(offset);
offset += 2;
uint16 ctrlOffs = READ_BE_UINT16(offset);
offset += 2;
tmp_n[i].startupCommand = READ_BE_UINT16(offset);
offset += 2;
tmp_n[i].finalCommand = READ_BE_UINT16(offset);
if (ctrlOffs) {
int num_c = *(filePtr + ctrlOffs);
const uint16 *in_c = (uint16*) (filePtr + ctrlOffs + 1);
FrameControl *tmp_f = new FrameControl[num_c];
for (int ii = 0; ii < num_c; ii++) {
tmp_f[ii].index = READ_BE_UINT16(in_c++);
tmp_f[ii].delay = READ_BE_UINT16(in_c++);
}
tmp_n[i].wsaControl = (const FrameControl*) tmp_f;
size += (num_c * sizeof(FrameControl));
} else {
tmp_n[i].wsaControl = 0;
}
}
delete [] filePtr;
HofSeqData *loadTo = new HofSeqData;
assert(loadTo);
loadTo->seq = tmp_s;
loadTo->seqn = tmp_n;
loadTo->numSeq = numSeq;
loadTo->numSeqn = numSeqN;
ptr = loadTo;
return true;
}
bool StaticResource::loadHofShapeAnimDataV1(const char *filename, void *&ptr, int &size) {
int filesize;
uint8 *filePtr = getFile(filename, filesize);
uint8 *src = filePtr;
if (!filePtr)
return false;
size = *src++;
ItemAnimData_v1 *loadTo = new ItemAnimData_v1[size];
assert(loadTo);
for (int i = 0; i < size; i++) {
loadTo[i].itemIndex = (int16) READ_BE_UINT16(src);
src += 2;
loadTo[i].y = READ_BE_UINT16(src);
src += 2;
uint16 *tmp_f = new uint16[20];
for (int ii = 0; ii < 20; ii++) {
tmp_f[ii] = READ_BE_UINT16(src);
src += 2;
}
loadTo[i].frames = tmp_f;
}
delete [] filePtr;
ptr = loadTo;
return true;
}
bool StaticResource::loadHofShapeAnimDataV2(const char *filename, void *&ptr, int &size) {
int filesize;
uint8 *filePtr = getFile(filename, filesize);
uint8 *src = filePtr;
if (!filePtr)
return false;
size = *src++;
ItemAnimData_v2 *loadTo = new ItemAnimData_v2[size];
assert(loadTo);
for (int i = 0; i < size; i++) {
loadTo[i].itemIndex = (int16) READ_BE_UINT16(src);
src += 2;
loadTo[i].numFrames = *src++;
FrameControl *tmp_f = new FrameControl[loadTo[i].numFrames];
for (int ii = 0; ii < loadTo[i].numFrames; ii++) {
tmp_f[ii].index = READ_BE_UINT16(src);
src += 2;
tmp_f[ii].delay = READ_BE_UINT16(src);
src += 2;
}
loadTo[i].frames = tmp_f;
}
delete [] filePtr;
ptr = loadTo;
return true;
}
void StaticResource::freeRawData(void *&ptr, int &size) {
uint8 *data = (uint8*)ptr;
delete [] data;
@ -634,6 +820,44 @@ void StaticResource::freeRoomTable(void *&ptr, int &size) {
size = 0;
}
void StaticResource::freeHofSequenceData(void *&ptr, int &size) {
HofSeqData *h = (HofSeqData*) ptr;
for (int i = 0; i < h->numSeq; i++) {
delete [] h->seq[i].wsaFile;
delete [] h->seq[i].cpsFile;
}
delete [] h->seq;
for (int i = 0; i < h->numSeqn; i++) {
delete [] h->seqn[i].wsaFile;
delete [] h->seqn[i].wsaControl;
}
delete [] h->seqn;
delete h;
ptr = 0;
size = 0;
}
void StaticResource::freeHofShapeAnimDataV1(void *&ptr, int &size) {
ItemAnimData_v1 *d= (ItemAnimData_v1*) ptr;
for (int i = 0; i < size; i++)
delete [] d[i].frames;
delete [] d;
ptr = 0;
size = 0;
}
void StaticResource::freeHofShapeAnimDataV2(void *&ptr, int &size) {
ItemAnimData_v2 *d= (ItemAnimData_v2*) ptr;
for (int i = 0; i < size; i++)
delete [] d[i].frames;
delete [] d;
ptr = 0;
size = 0;
}
void StaticResource::freePaletteTable(void *&ptr, int &size) {
uint8 **data = (uint8**)ptr;
while (size--)
@ -941,18 +1165,7 @@ void KyraEngine_v2::initStaticResource() {
_cdaTrackTableFinale = _staticres->loadRawData(k2SeqplayFinaleCDA, _cdaTrackTableFinaleSize);
_ingameTalkObjIndex = (const uint16*) _staticres->loadRawData(k2IngameTalkObjIndex, _ingameTalkObjIndexSize);
_ingameTimJpStr = _staticres->loadStrings(k2IngameTimJpStrings, _ingameTimJpStrSize);
_itemAnimTable = _staticres->loadRawData(k2IngameItemAnimTable, tmpSize);
if (_itemAnimTable) {
for (int i = 0; i < 15; i++) {
const uint8 *tmp = _itemAnimTable + 56 * i;
_itemAnimData[i].itemIndex = (int16) READ_LE_UINT16(tmp);
_itemAnimData[i].numFrames = tmp[2];
_itemAnimData[i].curFrame = tmp[3];
_itemAnimData[i].nextFrame = READ_LE_UINT32(&tmp[4]);
_itemAnimData[i].frames = &tmp[8];
}
}
_itemAnimData = _staticres->loadHofShapeAnimDataV2(k2IngameShapeAnimData, _itemAnimDataSize);
// replace sequence talkie files with localized versions and cut off .voc
// suffix from voc files so as to allow compression specific file extensions
@ -1006,9 +1219,9 @@ void KyraEngine_v2::initStaticResource() {
_soundData = (_flags.platform == Common::kPlatformPC) ? soundData_PC : soundData_TOWNS;
// setup sequence data
const uint8 *seqData = _staticres->loadRawData(k2SeqplaySeqData, tmpSize);
_sequences = _staticres->loadHofSequenceData(k2SeqplaySeqData, tmpSize);
static const Seqproc hofSequenceCallbacks[] = { 0,
static const SeqProc hofSequenceCallbacks[] = { 0,
&KyraEngine_v2::seq_introWestwood,
&KyraEngine_v2::seq_introTitle, &KyraEngine_v2::seq_introOverview,
&KyraEngine_v2::seq_introLibrary, &KyraEngine_v2::seq_introHand,
@ -1019,7 +1232,7 @@ void KyraEngine_v2::initStaticResource() {
&KyraEngine_v2::seq_finaleFirates, &KyraEngine_v2::seq_finaleFrash
};
static const Seqproc hofNestedSequenceCallbacks[] = {
static const SeqProc hofNestedSequenceCallbacks[] = {
&KyraEngine_v2::seq_finaleFiggle, &KyraEngine_v2::seq_introOver1,
&KyraEngine_v2::seq_introOver2, &KyraEngine_v2::seq_introForest,
&KyraEngine_v2::seq_introDragon, &KyraEngine_v2::seq_introDarm,
@ -1029,84 +1242,21 @@ void KyraEngine_v2::initStaticResource() {
&KyraEngine_v2::seq_introHand2, &KyraEngine_v2::seq_introHand3, 0
};
static const Seqproc hofDemoSequenceCallbacks[] = {
static const SeqProc hofDemoSequenceCallbacks[] = {
&KyraEngine_v2::seq_demoVirgin, &KyraEngine_v2::seq_demoWestwood,
&KyraEngine_v2::seq_demoTitle, &KyraEngine_v2::seq_demoHill,
&KyraEngine_v2::seq_demoOuthome, &KyraEngine_v2::seq_demoWharf,
&KyraEngine_v2::seq_demoDinob, &KyraEngine_v2::seq_demoFisher, 0
};
static const Seqproc hofDemoNestedSequenceCallbacks[] = {
static const SeqProc hofDemoNestedSequenceCallbacks[] = {
&KyraEngine_v2::seq_demoWharf2, &KyraEngine_v2::seq_demoDinob2,
&KyraEngine_v2::seq_demoWater, &KyraEngine_v2::seq_demoBail,
&KyraEngine_v2::seq_demoDig, 0
};
const uint16 *hdr = (const uint16 *) seqData;
uint16 numSeq = READ_LE_UINT16(hdr++);
uint16 hdrSize = READ_LE_UINT16(hdr) - 1;
const Seqproc *cb = (_flags.isDemo && !_flags.isTalkie) ? hofDemoSequenceCallbacks : hofSequenceCallbacks;
const Seqproc *ncb = (_flags.isDemo && !_flags.isTalkie) ? hofDemoNestedSequenceCallbacks : hofNestedSequenceCallbacks;
_sequences = new Sequence[numSeq];
for (int i = 0; i < numSeq; i++) {
const uint8 *offset = (const uint8 *)(seqData + READ_LE_UINT16(hdr++));
_sequences[i].flags = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].wsaFile = (const char *)offset;
offset += 14;
_sequences[i].cpsFile = (const char *)offset;
offset += 14;
_sequences[i].startupCommand = *offset++;
_sequences[i].finalCommand = *offset++;
_sequences[i].stringIndex1 = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].stringIndex2 = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].startFrame = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].numFrames = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].frameDelay = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].xPos = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].yPos = READ_LE_UINT16(offset);
offset += 2;
_sequences[i].duration = READ_LE_UINT16(offset);
_sequences[i].callback = cb[i];
}
if (hdr > ((const uint16*)(seqData + hdrSize)))
return;
numSeq = READ_LE_UINT16(hdr++);
_nSequences = new NestedSequence[numSeq];
for (int i = 0; i < numSeq; i++) {
const uint8 *offset = (const uint8 *)(seqData + READ_LE_UINT16(hdr++));
_nSequences[i].flags = READ_LE_UINT16(offset);
offset += 2;
_nSequences[i].wsaFile = (const char *)offset;
offset += 14;
_nSequences[i].startframe = READ_LE_UINT16(offset);
offset += 2;
_nSequences[i].endFrame = READ_LE_UINT16(offset);
offset += 2;
_nSequences[i].frameDelay = READ_LE_UINT16(offset);
offset += 2;
_nSequences[i].x = READ_LE_UINT16(offset);
offset += 2;
_nSequences[i].y = READ_LE_UINT16(offset);
offset += 2;
uint16 ctrlOffs = READ_LE_UINT16(offset);
offset += 2;
_nSequences[i].startupCommand = READ_LE_UINT16(offset);
offset += 2;
_nSequences[i].finalCommand = READ_LE_UINT16(offset);
_nSequences[i].callback = ncb[i];
_nSequences[i].wsaControl = ctrlOffs ? (const uint16*) (seqData + ctrlOffs) : 0;
}
_callbackS = (_flags.isDemo && !_flags.isTalkie) ? hofDemoSequenceCallbacks : hofSequenceCallbacks;
_callbackN = (_flags.isDemo && !_flags.isTalkie) ? hofDemoNestedSequenceCallbacks : hofNestedSequenceCallbacks;
}
const ScreenDim Screen::_screenDimTable[] = {