- Add support for the Lands of Lore outro TIM file
- Cleanup svn-id: r41053
This commit is contained in:
parent
f2516e648e
commit
bccca104d0
8 changed files with 312 additions and 85 deletions
|
@ -337,6 +337,10 @@ LoLEngine::~LoLEngine() {
|
||||||
delete *i;
|
delete *i;
|
||||||
_timIntroOpcodes.clear();
|
_timIntroOpcodes.clear();
|
||||||
|
|
||||||
|
for (Common::Array<const TIMOpcode*>::iterator i = _timOutroOpcodes.begin(); i != _timOutroOpcodes.end(); ++i)
|
||||||
|
delete *i;
|
||||||
|
_timOutroOpcodes.clear();
|
||||||
|
|
||||||
for (Common::Array<const TIMOpcode*>::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i)
|
for (Common::Array<const TIMOpcode*>::iterator i = _timIngameOpcodes.begin(); i != _timIngameOpcodes.end(); ++i)
|
||||||
delete *i;
|
delete *i;
|
||||||
_timIngameOpcodes.clear();
|
_timIngameOpcodes.clear();
|
||||||
|
|
|
@ -773,6 +773,16 @@ private:
|
||||||
int tlol_processWsaFrame(const TIM *tim, const uint16 *param);
|
int tlol_processWsaFrame(const TIM *tim, const uint16 *param);
|
||||||
int tlol_displayText(const TIM *tim, const uint16 *param);
|
int tlol_displayText(const TIM *tim, const uint16 *param);
|
||||||
|
|
||||||
|
Common::Array<const TIMOpcode*> _timOutroOpcodes;
|
||||||
|
int tlol_fadeInScene(const TIM *tim, const uint16 *param);
|
||||||
|
int tlol_unusedResourceFunc(const TIM *tim, const uint16 *param);
|
||||||
|
int tlol_fadeInPalette(const TIM *tim, const uint16 *param);
|
||||||
|
int tlol_fadeSoundOut(const TIM *tim, const uint16 *param);
|
||||||
|
int tlol_displayAnimFrame(const TIM *tim, const uint16 *param);
|
||||||
|
int tlol_delayForChat(const TIM *tim, const uint16 *param);
|
||||||
|
int tlol_fadeOutSound(const TIM *tim, const uint16 *param);
|
||||||
|
|
||||||
|
Common::Array<const TIMOpcode*> _timIngameOpcodes;
|
||||||
int tlol_initSceneWindowDialogue(const TIM *tim, const uint16 *param);
|
int tlol_initSceneWindowDialogue(const TIM *tim, const uint16 *param);
|
||||||
int tlol_restoreAfterSceneWindowDialogue(const TIM *tim, const uint16 *param);
|
int tlol_restoreAfterSceneWindowDialogue(const TIM *tim, const uint16 *param);
|
||||||
int tlol_giveItem(const TIM *tim, const uint16 *param);
|
int tlol_giveItem(const TIM *tim, const uint16 *param);
|
||||||
|
@ -790,8 +800,6 @@ private:
|
||||||
int tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param);
|
int tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param);
|
||||||
int tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param);
|
int tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param);
|
||||||
|
|
||||||
Common::Array<const TIMOpcode*> _timIngameOpcodes;
|
|
||||||
|
|
||||||
// translation
|
// translation
|
||||||
int _lang;
|
int _lang;
|
||||||
|
|
||||||
|
|
|
@ -738,6 +738,37 @@ void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x
|
||||||
addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
|
addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen_LoL::copyBlockAndApplyOverlayOutro(int srcPage, int dstPage, const uint8 *ovl) {
|
||||||
|
if (!ovl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const byte *src = getCPagePtr(srcPage);
|
||||||
|
byte *dst = getPagePtr(dstPage);
|
||||||
|
|
||||||
|
for (int y = 0; y < 200; ++y) {
|
||||||
|
for (int x = 0; x < 80; ++x) {
|
||||||
|
uint32 srcData = READ_LE_UINT32(src); src += 4;
|
||||||
|
uint32 dstData = READ_LE_UINT32(dst);
|
||||||
|
uint16 offset = 0;
|
||||||
|
|
||||||
|
offset = ((srcData & 0xFF) << 8) + (dstData & 0xFF);
|
||||||
|
*dst++ = ovl[offset];
|
||||||
|
|
||||||
|
offset = (srcData & 0xFF00) + ((dstData & 0xFF00) >> 8);
|
||||||
|
*dst++ = ovl[offset];
|
||||||
|
|
||||||
|
srcData >>= 16;
|
||||||
|
dstData >>= 16;
|
||||||
|
|
||||||
|
offset = ((srcData & 0xFF) << 8) + (dstData & 0xFF);
|
||||||
|
*dst++ = ovl[offset];
|
||||||
|
|
||||||
|
offset = (srcData & 0xFF00) + ((dstData & 0xFF00) >> 8);
|
||||||
|
*dst++ = ovl[offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Screen_LoL::calcBoundariesIntern(int dstX, int dstY, int width, int height) {
|
void Screen_LoL::calcBoundariesIntern(int dstX, int dstY, int width, int height) {
|
||||||
_internBlockWidth = _internBlockWidth2 = width;
|
_internBlockWidth = _internBlockWidth2 = width;
|
||||||
_internBlockHeight = height;
|
_internBlockHeight = height;
|
||||||
|
|
|
@ -82,6 +82,8 @@ public:
|
||||||
void copyBlockAndApplyOverlay(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl);
|
void copyBlockAndApplyOverlay(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl);
|
||||||
void applyOverlaySpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, int flag, uint8 *ovl);
|
void applyOverlaySpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, int flag, uint8 *ovl);
|
||||||
|
|
||||||
|
void copyBlockAndApplyOverlayOutro(int srcPage, int dstPage, const uint8 *ovl);
|
||||||
|
|
||||||
uint8 getShapePaletteSize(const uint8 *shp);
|
uint8 getShapePaletteSize(const uint8 *shp);
|
||||||
|
|
||||||
uint8 *_paletteOverlay1;
|
uint8 *_paletteOverlay1;
|
||||||
|
|
|
@ -2191,7 +2191,10 @@ int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
|
||||||
|
|
||||||
int LoLEngine::tlol_displayText(const TIM *tim, const uint16 *param) {
|
int LoLEngine::tlol_displayText(const TIM *tim, const uint16 *param) {
|
||||||
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayText(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], (int16)param[1]);
|
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayText(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], (int16)param[1]);
|
||||||
_tim->displayText(param[0], param[1]);
|
if (tim->isLoLOutro)
|
||||||
|
_tim->displayText(param[0], param[1], param[2]);
|
||||||
|
else
|
||||||
|
_tim->displayText(param[0], param[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2356,6 +2359,87 @@ int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int LoLEngine::tlol_fadeInScene(const TIM *tim, const uint16 *param) {
|
||||||
|
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInScene(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
|
||||||
|
const char *sceneFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
|
||||||
|
const char *overlayFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[1]<<1)));
|
||||||
|
|
||||||
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
|
||||||
|
|
||||||
|
char filename[32];
|
||||||
|
strcpy(filename, sceneFile);
|
||||||
|
strcat(filename, ".CPS");
|
||||||
|
|
||||||
|
_screen->loadBitmap(filename, 7, 5, _screen->getPalette(0));
|
||||||
|
|
||||||
|
filename[0] = 0;
|
||||||
|
|
||||||
|
if (_flags.isTalkie) {
|
||||||
|
strcpy(filename, _languageExt[_lang]);
|
||||||
|
strcat(filename, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
strcat(filename, overlayFile);
|
||||||
|
uint8 *overlay = _res->fileData(filename, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
uint32 endTime = _system->getMillis() + 10 * _tickLength;
|
||||||
|
_screen->copyBlockAndApplyOverlayOutro(4, 2, overlay);
|
||||||
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
|
||||||
|
_screen->updateScreen();
|
||||||
|
delayUntil(endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 2, Screen::CR_NO_P_CHECK);
|
||||||
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 4, 0, Screen::CR_NO_P_CHECK);
|
||||||
|
_screen->updateScreen();
|
||||||
|
delete[] overlay;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoLEngine::tlol_unusedResourceFunc(const TIM *tim, const uint16 *param) {
|
||||||
|
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_unusedResourceFunc(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
|
||||||
|
// The original used 0x6 / 0x7 for some resource caching, we don't need this.
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoLEngine::tlol_fadeInPalette(const TIM *tim, const uint16 *param) {
|
||||||
|
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeInPalette(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
|
||||||
|
const char *bitmap = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
|
||||||
|
uint8 palette[768];
|
||||||
|
_screen->loadBitmap(bitmap, 3, 3, palette);
|
||||||
|
_screen->fadePalette(palette, param[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoLEngine::tlol_fadeOutSound(const TIM *tim, const uint16 *param) {
|
||||||
|
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_fadeOutSound(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
|
||||||
|
_sound->beginFadeOut();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoLEngine::tlol_displayAnimFrame(const TIM *tim, const uint16 *param) {
|
||||||
|
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayAnimFrame(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
|
||||||
|
|
||||||
|
TIMInterpreter::Animation *anim = (TIMInterpreter::Animation *)tim->wsa[param[0]].anim;
|
||||||
|
if (param[1] == 0xFFFF) {
|
||||||
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
|
||||||
|
} else {
|
||||||
|
anim->wsa->displayFrame(param[1], 2, anim->x, anim->y, 0);
|
||||||
|
_screen->copyRegion(anim->wsa->xAdd(), anim->wsa->yAdd(), anim->wsa->xAdd(), anim->wsa->yAdd(), anim->wsa->width(), anim->wsa->height(), 2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LoLEngine::tlol_delayForChat(const TIM *tim, const uint16 *param) {
|
||||||
|
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_delayForChat(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
|
||||||
|
if (!speechEnabled())
|
||||||
|
delay(param[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
||||||
typedef Common::Functor1Mem<EMCState*, int, LoLEngine> OpcodeV2;
|
typedef Common::Functor1Mem<EMCState*, int, LoLEngine> OpcodeV2;
|
||||||
|
@ -2678,6 +2762,33 @@ void LoLEngine::setupOpcodeTable() {
|
||||||
OpcodeTimUnImpl();
|
OpcodeTimUnImpl();
|
||||||
OpcodeTimUnImpl();
|
OpcodeTimUnImpl();
|
||||||
|
|
||||||
|
_timOutroOpcodes.reserve(16);
|
||||||
|
SetTimOpcodeTable(_timOutroOpcodes);
|
||||||
|
|
||||||
|
// 0x00
|
||||||
|
OpcodeTim(tlol_setupPaletteFade);
|
||||||
|
OpcodeTimUnImpl();
|
||||||
|
OpcodeTim(tlol_loadPalette);
|
||||||
|
OpcodeTim(tlol_setupPaletteFadeEx);
|
||||||
|
|
||||||
|
// 0x04
|
||||||
|
OpcodeTimUnImpl();
|
||||||
|
OpcodeTim(tlol_fadeInScene);
|
||||||
|
OpcodeTim(tlol_unusedResourceFunc);
|
||||||
|
OpcodeTim(tlol_unusedResourceFunc);
|
||||||
|
|
||||||
|
// 0x08
|
||||||
|
OpcodeTim(tlol_fadeInPalette);
|
||||||
|
OpcodeTimUnImpl();
|
||||||
|
OpcodeTimUnImpl();
|
||||||
|
OpcodeTim(tlol_fadeOutSound);
|
||||||
|
|
||||||
|
// 0x0C
|
||||||
|
OpcodeTim(tlol_displayAnimFrame);
|
||||||
|
OpcodeTim(tlol_delayForChat);
|
||||||
|
OpcodeTim(tlol_displayText);
|
||||||
|
OpcodeTimUnImpl();
|
||||||
|
|
||||||
_timIngameOpcodes.reserve(17);
|
_timIngameOpcodes.reserve(17);
|
||||||
SetTimOpcodeTable(_timIngameOpcodes);
|
SetTimOpcodeTable(_timIngameOpcodes);
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys
|
||||||
_textDisplayed = false;
|
_textDisplayed = false;
|
||||||
_textAreaBuffer = new uint8[320*40];
|
_textAreaBuffer = new uint8[320*40];
|
||||||
assert(_textAreaBuffer);
|
assert(_textAreaBuffer);
|
||||||
_drawPage2 = (vm()->gameFlags().isDemo && vm()->gameFlags().gameID == GI_LOL) ? 0 : 8;
|
_drawPage2 = (_vm->gameFlags().isDemo && _vm->gameFlags().gameID == GI_LOL) ? 0 : 8;
|
||||||
|
|
||||||
_palDelayInc = _palDiff = _palDelayAcc = 0;
|
_palDelayInc = _palDiff = _palDelayAcc = 0;
|
||||||
_abortFlag = 0;
|
_abortFlag = 0;
|
||||||
|
@ -117,10 +117,10 @@ TIMInterpreter::~TIMInterpreter() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode *> *opcodes) {
|
TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode *> *opcodes) {
|
||||||
if (!vm()->resource()->exists(filename))
|
if (!_vm->resource()->exists(filename))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Common::SeekableReadStream *stream = vm()->resource()->createReadStream(filename);
|
Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
|
||||||
if (!stream)
|
if (!stream)
|
||||||
error("Couldn't open TIM file '%s'", filename);
|
error("Couldn't open TIM file '%s'", filename);
|
||||||
|
|
||||||
|
@ -176,6 +176,9 @@ TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpc
|
||||||
strncpy(tim->filename, filename, 13);
|
strncpy(tim->filename, filename, 13);
|
||||||
tim->filename[12] = 0;
|
tim->filename[12] = 0;
|
||||||
|
|
||||||
|
tim->isLoLOutro = (_vm->gameFlags().gameID == GI_LOL) && !scumm_stricmp(filename, "LOLFINAL.TIM");
|
||||||
|
tim->lolCharacter = 0;
|
||||||
|
|
||||||
return tim;
|
return tim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +194,7 @@ void TIMInterpreter::unload(TIM *&tim) const {
|
||||||
|
|
||||||
void TIMInterpreter::setLangData(const char *filename) {
|
void TIMInterpreter::setLangData(const char *filename) {
|
||||||
delete[] _langData;
|
delete[] _langData;
|
||||||
_langData = vm()->resource()->fileData(filename, 0);
|
_langData = _vm->resource()->fileData(filename, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TIMInterpreter::exec(TIM *tim, bool loop) {
|
int TIMInterpreter::exec(TIM *tim, bool loop) {
|
||||||
|
@ -254,11 +257,11 @@ int TIMInterpreter::exec(TIM *tim, bool loop) {
|
||||||
if (cur.ip) {
|
if (cur.ip) {
|
||||||
cur.ip += cur.ip[0];
|
cur.ip += cur.ip[0];
|
||||||
cur.lastTime = cur.nextTime;
|
cur.lastTime = cur.nextTime;
|
||||||
cur.nextTime += (cur.ip[1] ) * vm()->tickLength();
|
cur.nextTime += (cur.ip[1] ) * _vm->tickLength();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (loop && !vm()->shouldQuit());
|
} while (loop && !_vm->shouldQuit());
|
||||||
|
|
||||||
return _currentTim->clickedButton;
|
return _currentTim->clickedButton;
|
||||||
}
|
}
|
||||||
|
@ -279,7 +282,7 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
|
||||||
char *text = getTableEntry(textId);
|
char *text = getTableEntry(textId);
|
||||||
|
|
||||||
if (_textDisplayed) {
|
if (_textDisplayed) {
|
||||||
screen()->copyBlockToPage(0, 0, 160, 320, 40, _textAreaBuffer);
|
_screen->copyBlockToPage(0, 0, 160, 320, 40, _textAreaBuffer);
|
||||||
_textDisplayed = false;
|
_textDisplayed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +301,7 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filename[0])
|
if (filename[0])
|
||||||
vm()->sound()->voicePlay(filename);
|
_vm->sound()->voicePlay(filename);
|
||||||
|
|
||||||
if (text[0] == '$')
|
if (text[0] == '$')
|
||||||
text = strchr(text + 1, '$') + 1;
|
text = strchr(text + 1, '$') + 1;
|
||||||
|
@ -308,13 +311,13 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
|
||||||
if (flags < 0) {
|
if (flags < 0) {
|
||||||
static const uint8 colorMap[] = { 0x00, 0xF0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
static const uint8 colorMap[] = { 0x00, 0xF0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
screen()->setFont(Screen::FID_8_FNT);
|
_screen->setFont(Screen::FID_8_FNT);
|
||||||
screen()->setTextColorMap(colorMap);
|
_screen->setTextColorMap(colorMap);
|
||||||
screen()->_charWidth = -2;
|
_screen->_charWidth = -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen()->_charOffset = -4;
|
_screen->_charOffset = -4;
|
||||||
screen()->copyRegionToBuffer(0, 0, 160, 320, 40, _textAreaBuffer);
|
_screen->copyRegionToBuffer(0, 0, 160, 320, 40, _textAreaBuffer);
|
||||||
_textDisplayed = true;
|
_textDisplayed = true;
|
||||||
|
|
||||||
char backupChar = 0;
|
char backupChar = 0;
|
||||||
|
@ -330,14 +333,14 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
|
||||||
nextLine[0] = '\0';
|
nextLine[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
int width = screen()->getTextWidth(str);
|
int width = _screen->getTextWidth(str);
|
||||||
|
|
||||||
if (flags >= 0)
|
if (flags >= 0)
|
||||||
screen()->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00);
|
_screen->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00);
|
||||||
else
|
else
|
||||||
screen()->printText(str, (320 - width) >> 1, 188, 0xF0, 0x00);
|
_screen->printText(str, (320 - width) >> 1, 188, 0xF0, 0x00);
|
||||||
|
|
||||||
heightAdd += screen()->getFontHeight();
|
heightAdd += _screen->getFontHeight();
|
||||||
str += strlen(str);
|
str += strlen(str);
|
||||||
|
|
||||||
if (backupChar) {
|
if (backupChar) {
|
||||||
|
@ -346,14 +349,66 @@ void TIMInterpreter::displayText(uint16 textId, int16 flags) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen()->_charOffset = 0;
|
_screen->_charOffset = 0;
|
||||||
|
|
||||||
if (flags < 0) {
|
if (flags < 0) {
|
||||||
static const uint8 colorMap[] = { 0x00, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00 };
|
static const uint8 colorMap[] = { 0x00, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
screen()->setFont(Screen::FID_INTRO_FNT);
|
_screen->setFont(Screen::FID_INTRO_FNT);
|
||||||
screen()->setTextColorMap(colorMap);
|
_screen->setTextColorMap(colorMap);
|
||||||
screen()->_charWidth = 0;
|
_screen->_charWidth = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIMInterpreter::displayText(uint16 textId, int16 flags, uint8 color) {
|
||||||
|
if (!_vm->textEnabled() && !(textId & 0x8000))
|
||||||
|
return;
|
||||||
|
|
||||||
|
char *text = getTableEntry(textId & 0x7FFF);
|
||||||
|
|
||||||
|
if (flags > 0)
|
||||||
|
_screen->copyBlockToPage(0, 0, 0, 320, 40, _textAreaBuffer);
|
||||||
|
|
||||||
|
if (flags == 255)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_screen->setFont(Screen::FID_INTRO_FNT);
|
||||||
|
|
||||||
|
static const uint8 colorMap[] = { 0x00, 0xA0, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
_screen->setTextColorMap(colorMap);
|
||||||
|
_screen->_charWidth = 0;
|
||||||
|
_screen->_charOffset = -4;
|
||||||
|
|
||||||
|
if (!flags)
|
||||||
|
_screen->copyRegionToBuffer(0, 0, 0, 320, 40, _textAreaBuffer);
|
||||||
|
|
||||||
|
char backupChar = 0;
|
||||||
|
char *str = text;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
while (str[0]) {
|
||||||
|
char *nextLine = strchr(str, '\r');
|
||||||
|
|
||||||
|
backupChar = 0;
|
||||||
|
if (nextLine) {
|
||||||
|
backupChar = nextLine[0];
|
||||||
|
nextLine[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = _screen->getTextWidth(str);
|
||||||
|
|
||||||
|
if (flags >= 0)
|
||||||
|
_screen->printText(str, (320 - width) >> 1, y, color, 0x00);
|
||||||
|
else
|
||||||
|
_screen->printText(str, 0, y, color, 0x00);
|
||||||
|
|
||||||
|
y += _screen->getFontHeight() - 4;
|
||||||
|
str += strlen(str);
|
||||||
|
|
||||||
|
if (backupChar) {
|
||||||
|
nextLine[0] = backupChar;
|
||||||
|
++str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +423,7 @@ void TIMInterpreter::setupTextPalette(uint index, int fadePalette) {
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < 15; ++i) {
|
for (int i = 0; i < 15; ++i) {
|
||||||
uint8 *palette = screen()->getPalette(0) + (240 + i) * 3;
|
uint8 *palette = _screen->getPalette(0) + (240 + i) * 3;
|
||||||
|
|
||||||
uint8 c1 = (((15 - i) << 2) * palTable[index*3+0]) / 100;
|
uint8 c1 = (((15 - i) << 2) * palTable[index*3+0]) / 100;
|
||||||
uint8 c2 = (((15 - i) << 2) * palTable[index*3+1]) / 100;
|
uint8 c2 = (((15 - i) << 2) * palTable[index*3+1]) / 100;
|
||||||
|
@ -380,29 +435,21 @@ void TIMInterpreter::setupTextPalette(uint index, int fadePalette) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fadePalette && !_palDiff) {
|
if (!fadePalette && !_palDiff) {
|
||||||
screen()->setScreenPalette(screen()->getPalette(0));
|
_screen->setScreenPalette(_screen->getPalette(0));
|
||||||
} else {
|
} else {
|
||||||
screen()->getFadeParams(screen()->getPalette(0), fadePalette, _palDelayInc, _palDiff);
|
_screen->getFadeParams(_screen->getPalette(0), fadePalette, _palDelayInc, _palDiff);
|
||||||
_palDelayAcc = 0;
|
_palDelayAcc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KyraEngine_v1 *TIMInterpreter::vm() {
|
|
||||||
return _vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
Screen_v2 *TIMInterpreter::screen() {
|
|
||||||
return _screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) {
|
TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) {
|
||||||
Animation *anim = &_animations[index];
|
Animation *anim = &_animations[index];
|
||||||
anim->x = x;
|
anim->x = x;
|
||||||
anim->y = y;
|
anim->y = y;
|
||||||
anim->wsaCopyParams = wsaFlags;
|
anim->wsaCopyParams = wsaFlags;
|
||||||
const bool isLoLDemo = vm()->gameFlags().isDemo && vm()->gameFlags().gameID == GI_LOL;
|
const bool isLoLDemo = _vm->gameFlags().isDemo && _vm->gameFlags().gameID == GI_LOL;
|
||||||
|
|
||||||
_drawPage2 = isLoLDemo ? 0 : 8;
|
_drawPage2 = (isLoLDemo || _currentTim->isLoLOutro) ? 0 : 8;
|
||||||
|
|
||||||
uint16 wsaOpenFlags = 0;
|
uint16 wsaOpenFlags = 0;
|
||||||
if (isLoLDemo) {
|
if (isLoLDemo) {
|
||||||
|
@ -420,14 +467,14 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
|
||||||
char file[32];
|
char file[32];
|
||||||
snprintf(file, 32, "%s.WSA", filename);
|
snprintf(file, 32, "%s.WSA", filename);
|
||||||
|
|
||||||
if (vm()->resource()->exists(file)) {
|
if (_vm->resource()->exists(file)) {
|
||||||
if (isLoLDemo)
|
if (isLoLDemo)
|
||||||
anim->wsa = new WSAMovie_v1(_vm);
|
anim->wsa = new WSAMovie_v1(_vm);
|
||||||
else
|
else
|
||||||
anim->wsa = new WSAMovie_v2(_vm, _screen);
|
anim->wsa = new WSAMovie_v2(_vm, _screen);
|
||||||
assert(anim->wsa);
|
assert(anim->wsa);
|
||||||
|
|
||||||
anim->wsa->open(file, wsaOpenFlags, (index == 1) ? screen()->getPalette(0) : 0);
|
anim->wsa->open(file, wsaOpenFlags, (index == 1) ? _screen->getPalette(0) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anim->wsa && anim->wsa->opened()) {
|
if (anim->wsa && anim->wsa->opened()) {
|
||||||
|
@ -453,50 +500,50 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wsaFlags & 2) {
|
if (wsaFlags & 2) {
|
||||||
screen()->fadePalette(screen()->getPalette(1), 15, 0);
|
_screen->fadePalette(_screen->getPalette(1), 15, 0);
|
||||||
screen()->clearPage(_drawPage2);
|
_screen->clearPage(_drawPage2);
|
||||||
if (_drawPage2)
|
if (_drawPage2)
|
||||||
screen()->checkedPageUpdate(8, 4);
|
_screen->checkedPageUpdate(8, 4);
|
||||||
screen()->updateScreen();
|
_screen->updateScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wsaFlags & 4) {
|
if (wsaFlags & 4) {
|
||||||
snprintf(file, 32, "%s.CPS", filename);
|
snprintf(file, 32, "%s.CPS", filename);
|
||||||
|
|
||||||
if (vm()->resource()->exists(file)) {
|
if (_vm->resource()->exists(file)) {
|
||||||
screen()->loadBitmap(file, 3, 3, screen()->getPalette(0));
|
_screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
|
||||||
screen()->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
|
||||||
if (_drawPage2)
|
if (_drawPage2)
|
||||||
screen()->checkedPageUpdate(8, 4);
|
_screen->checkedPageUpdate(8, 4);
|
||||||
screen()->updateScreen();
|
_screen->updateScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
anim->wsa->displayFrame(0, 0, x, y, 0);
|
anim->wsa->displayFrame(0, 0, x, y, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wsaFlags & 2)
|
if (wsaFlags & 2)
|
||||||
screen()->fadePalette(screen()->getPalette(0), 30, 0);
|
_screen->fadePalette(_screen->getPalette(0), 30, 0);
|
||||||
} else {
|
} else {
|
||||||
if (wsaFlags & 2) {
|
if (wsaFlags & 2) {
|
||||||
screen()->fadePalette(screen()->getPalette(1), 15, 0);
|
_screen->fadePalette(_screen->getPalette(1), 15, 0);
|
||||||
screen()->clearPage(_drawPage2);
|
_screen->clearPage(_drawPage2);
|
||||||
if (_drawPage2)
|
if (_drawPage2)
|
||||||
screen()->checkedPageUpdate(8, 4);
|
_screen->checkedPageUpdate(8, 4);
|
||||||
screen()->updateScreen();
|
_screen->updateScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(file, 32, "%s.CPS", filename);
|
snprintf(file, 32, "%s.CPS", filename);
|
||||||
|
|
||||||
if (vm()->resource()->exists(file)) {
|
if (_vm->resource()->exists(file)) {
|
||||||
screen()->loadBitmap(file, 3, 3, screen()->getPalette(0));
|
_screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
|
||||||
screen()->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
|
_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, _drawPage2, Screen::CR_NO_P_CHECK);
|
||||||
if (_drawPage2)
|
if (_drawPage2)
|
||||||
screen()->checkedPageUpdate(8, 4);
|
_screen->checkedPageUpdate(8, 4);
|
||||||
screen()->updateScreen();
|
_screen->updateScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wsaFlags & 2)
|
if (wsaFlags & 2)
|
||||||
screen()->fadePalette(screen()->getPalette(0), 30, 0);
|
_screen->fadePalette(_screen->getPalette(0), 30, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return anim;
|
return anim;
|
||||||
|
@ -636,12 +683,15 @@ int TIMInterpreter::cmd_wsaDisplayFrame(const uint16 *param) {
|
||||||
if (anim.wsa)
|
if (anim.wsa)
|
||||||
anim.wsa->displayFrame(frame, page, anim.x, anim.y, anim.wsaCopyParams & 0xF0FF, 0, 0);
|
anim.wsa->displayFrame(frame, page, anim.x, anim.y, anim.wsaCopyParams & 0xF0FF, 0, 0);
|
||||||
if (!page)
|
if (!page)
|
||||||
screen()->updateScreen();
|
_screen->updateScreen();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TIMInterpreter::cmd_displayText(const uint16 *param) {
|
int TIMInterpreter::cmd_displayText(const uint16 *param) {
|
||||||
displayText(param[0], param[1]);
|
if (_currentTim->isLoLOutro)
|
||||||
|
displayText(param[0], param[1], 0xF2);
|
||||||
|
else
|
||||||
|
displayText(param[0], param[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,6 +700,32 @@ int TIMInterpreter::cmd_loadVocFile(const uint16 *param) {
|
||||||
const int index = param[1];
|
const int index = param[1];
|
||||||
|
|
||||||
_vocFiles[index] = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (stringId << 1)));
|
_vocFiles[index] = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (stringId << 1)));
|
||||||
|
|
||||||
|
if (index == 2 && _currentTim->isLoLOutro) {
|
||||||
|
_vocFiles[index] = "CONGRATA.VOC";
|
||||||
|
|
||||||
|
switch (_currentTim->lolCharacter) {
|
||||||
|
case 0:
|
||||||
|
_vocFiles[index].setChar('K', 7);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
_vocFiles[index].setChar('A', 7);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
_vocFiles[index].setChar('M', 7);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
_vocFiles[index].setChar('C', 7);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
_vocFiles[index].deleteLastChar();
|
_vocFiles[index].deleteLastChar();
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -666,11 +742,11 @@ int TIMInterpreter::cmd_playVocFile(const uint16 *param) {
|
||||||
const int volume = (param[1] * 255) / 100;
|
const int volume = (param[1] * 255) / 100;
|
||||||
|
|
||||||
if (index < ARRAYSIZE(_vocFiles) && !_vocFiles[index].empty())
|
if (index < ARRAYSIZE(_vocFiles) && !_vocFiles[index].empty())
|
||||||
vm()->sound()->voicePlay(_vocFiles[index].c_str(), 0, volume, true);
|
_vm->sound()->voicePlay(_vocFiles[index].c_str(), 0, volume, true);
|
||||||
else if (index == 7 && !_vm->gameFlags().isTalkie)
|
else if (index == 7 && !_vm->gameFlags().isTalkie)
|
||||||
vm()->sound()->playTrack(index);
|
_vm->sound()->playTrack(index);
|
||||||
else
|
else
|
||||||
vm()->sound()->playSoundEffect(index);
|
_vm->sound()->playSoundEffect(index);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -678,15 +754,15 @@ int TIMInterpreter::cmd_playVocFile(const uint16 *param) {
|
||||||
int TIMInterpreter::cmd_loadSoundFile(const uint16 *param) {
|
int TIMInterpreter::cmd_loadSoundFile(const uint16 *param) {
|
||||||
const char *file = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (param[0]<<1)));
|
const char *file = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (param[0]<<1)));
|
||||||
|
|
||||||
vm()->sound()->loadSoundFile(file);
|
_vm->sound()->loadSoundFile(file);
|
||||||
if (vm()->gameFlags().gameID == GI_LOL)
|
if (_vm->gameFlags().gameID == GI_LOL)
|
||||||
vm()->sound()->loadSfxFile(file);
|
_vm->sound()->loadSfxFile(file);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TIMInterpreter::cmd_playMusicTrack(const uint16 *param) {
|
int TIMInterpreter::cmd_playMusicTrack(const uint16 *param) {
|
||||||
vm()->sound()->playTrack(param[0]);
|
_vm->sound()->playTrack(param[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -705,9 +781,9 @@ int TIMInterpreter::cmd_continueLoop(const uint16 *param) {
|
||||||
|
|
||||||
uint16 factor = param[0];
|
uint16 factor = param[0];
|
||||||
if (factor) {
|
if (factor) {
|
||||||
const uint32 random = vm()->_rnd.getRandomNumberRng(0, 0x8000);
|
const uint32 random = _vm->_rnd.getRandomNumberRng(0, 0x8000);
|
||||||
uint32 waitTime = (random * factor) / 0x8000;
|
uint32 waitTime = (random * factor) / 0x8000;
|
||||||
func.nextTime += waitTime * vm()->tickLength();
|
func.nextTime += waitTime * _vm->tickLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
return -2;
|
return -2;
|
||||||
|
@ -764,7 +840,7 @@ int TIMInterpreter::cmd_stopFuncNow(const uint16 *param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int TIMInterpreter::cmd_stopAllFuncs(const uint16 *param) {
|
int TIMInterpreter::cmd_stopAllFuncs(const uint16 *param) {
|
||||||
while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !vm()->shouldQuit()) {
|
while (_currentTim->dlgFunc == -1 && _currentTim->clickedButton == 0 && !_vm->shouldQuit()) {
|
||||||
update();
|
update();
|
||||||
_currentTim->clickedButton = processDialogue();
|
_currentTim->clickedButton = processDialogue();
|
||||||
}
|
}
|
||||||
|
@ -905,14 +981,6 @@ int TIMInterpreter_LoL::freeAnimStruct(int index) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
KyraEngine_v1 *TIMInterpreter_LoL::vm() {
|
|
||||||
return _vm;
|
|
||||||
}
|
|
||||||
|
|
||||||
Screen_v2 *TIMInterpreter_LoL::screen() {
|
|
||||||
return _screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TIMInterpreter_LoL::advanceToOpcode(int opcode) {
|
void TIMInterpreter_LoL::advanceToOpcode(int opcode) {
|
||||||
TIM::Function *f = &_currentTim->func[_currentTim->dlgFunc];
|
TIM::Function *f = &_currentTim->func[_currentTim->dlgFunc];
|
||||||
uint16 len = f->ip[0];
|
uint16 len = f->ip[0];
|
||||||
|
|
|
@ -80,6 +80,11 @@ struct TIM {
|
||||||
uint8 *text;
|
uint8 *text;
|
||||||
|
|
||||||
const Common::Array<const TIMOpcode*> *opcodes;
|
const Common::Array<const TIMOpcode*> *opcodes;
|
||||||
|
|
||||||
|
// TODO: Get rid of this ugly HACK to allow the
|
||||||
|
// Lands of Lore outro to be working properly.
|
||||||
|
bool isLoLOutro;
|
||||||
|
uint8 lolCharacter;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TIMInterpreter {
|
class TIMInterpreter {
|
||||||
|
@ -134,6 +139,7 @@ public:
|
||||||
void refreshTimersAfterPause(uint32 elapsedTime);
|
void refreshTimersAfterPause(uint32 elapsedTime);
|
||||||
|
|
||||||
void displayText(uint16 textId, int16 flags);
|
void displayText(uint16 textId, int16 flags);
|
||||||
|
void displayText(uint16 textId, int16 flags, uint8 color);
|
||||||
void setupTextPalette(uint index, int fadePalette);
|
void setupTextPalette(uint index, int fadePalette);
|
||||||
|
|
||||||
virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {}
|
virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {}
|
||||||
|
@ -154,9 +160,6 @@ public:
|
||||||
int _abortFlag;
|
int _abortFlag;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual KyraEngine_v1 *vm();
|
|
||||||
virtual Screen_v2 *screen();
|
|
||||||
|
|
||||||
KyraEngine_v1 *_vm;
|
KyraEngine_v1 *_vm;
|
||||||
Screen_v2 *_screen;
|
Screen_v2 *_screen;
|
||||||
OSystem *_system;
|
OSystem *_system;
|
||||||
|
@ -242,9 +245,6 @@ public:
|
||||||
int resetAnimationLastPart(int animIndex);
|
int resetAnimationLastPart(int animIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KyraEngine_v1 *vm();
|
|
||||||
Screen_v2 *screen();
|
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
void checkSpeechProgress();
|
void checkSpeechProgress();
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,9 @@ public:
|
||||||
|
|
||||||
virtual bool opened() { return _opened; }
|
virtual bool opened() { return _opened; }
|
||||||
|
|
||||||
|
virtual int xAdd() const { return 0; }
|
||||||
|
virtual int yAdd() const { return 0; }
|
||||||
|
|
||||||
virtual int width() const = 0;
|
virtual int width() const = 0;
|
||||||
virtual int height() const = 0;
|
virtual int height() const = 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue