aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/lol.cpp8
-rw-r--r--engines/kyra/lol.h4
-rw-r--r--engines/kyra/scene_lol.cpp70
-rw-r--r--engines/kyra/screen_lol.cpp102
-rw-r--r--engines/kyra/screen_lol.h4
-rw-r--r--engines/kyra/script_lol.cpp44
-rw-r--r--engines/kyra/sound_towns.cpp13
-rw-r--r--engines/kyra/sprites_lol.cpp2
8 files changed, 222 insertions, 25 deletions
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index f29499d67e..950dee57ae 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -1795,6 +1795,8 @@ void LoLEngine::snd_playSoundEffect(int track, int volume) {
return;
_lastSfxTrack = track;
+ if (track == -1)
+ return;
int16 volIndex = (int16)READ_LE_UINT16(&_ingameSoundIndex[track * 2 + 1]);
@@ -2133,7 +2135,7 @@ int LoLEngine::castSpell(int charNum, int spellType, int spellLevel) {
if (_activeSpell.p->hpRequired[spellLevel] >= _characters[charNum].hitPointsCur)
return 0;
- //setCharacterMagicOrHitPoints(charNum, 1, -_activeSpell.p->mpRequired[spellLevel], 1);
+ setCharacterMagicOrHitPoints(charNum, 1, -_activeSpell.p->mpRequired[spellLevel], 1);
setCharacterMagicOrHitPoints(charNum, 0, -_activeSpell.p[1].hpRequired[spellLevel], 1);
gui_drawCharPortraitWithStats(charNum);
@@ -3178,10 +3180,6 @@ void LoLEngine::level11specialUnk() {
}
-void LoLEngine::distObj1Sub(int a, int b, int c, int d) {
-
-}
-
void LoLEngine::launchMagicViper() {
}
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index a842c573ef..c4d849ca6e 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -694,6 +694,7 @@ private:
int olol_enableSysTimer(EMCState *script);
int olol_checkNeedSceneRestore(EMCState *script);
int olol_castSpell(EMCState *script);
+ int olol_pitDrop(EMCState *script);
int olol_paletteFlash(EMCState *script);
int olol_disableControls(EMCState *script);
int olol_enableControls(EMCState *script);
@@ -927,6 +928,9 @@ private:
void movePartySmoothScrollTurnLeft(int speed);
void movePartySmoothScrollTurnRight(int speed);
+ void pitDropScroll(int numSteps);
+ void shakeScene(int duration, int width, int height, int restore);
+
int smoothScrollDrawSpecialShape(int pageNum);
OpenDoorState _openDoorState[3];
diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp
index 38227cfae5..a92f3f8240 100644
--- a/engines/kyra/scene_lol.cpp
+++ b/engines/kyra/scene_lol.cpp
@@ -1228,6 +1228,76 @@ void LoLEngine::movePartySmoothScrollTurnRight(int speed) {
}
}
+void LoLEngine::pitDropScroll(int numSteps) {
+ _screen->copyRegionSpecial(0, 320, 200, 112, 0, 6, 176, 120, 0, 0, 176, 120, 0);
+ uint32 ctime = 0;
+ int del = 0;
+
+ for (int i = 0; i < numSteps; i++) {
+ ctime = _system->getMillis();
+ int ys = ((30720 / numSteps) * i) >> 8;
+ _screen->copyRegionSpecial(6, 176, 120, 0, ys, 0, 320, 200, 112, 0, 176, 120 - ys, 0);
+ _screen->copyRegionSpecial(2, 320, 200, 112, 0, 0, 320, 200, 112, 120 - ys, 176, ys, 0);
+ _screen->updateScreen();
+
+ del = _tickLength - (_system->getMillis() - ctime);
+ if (del > 0)
+ delay(del, false, true);
+ }
+
+ _screen->copyRegionSpecial(2, 320, 200, 112, 0, 0, 320, 200, 112, 0, 176, 120, 0);
+ _screen->updateScreen();
+
+ del = _tickLength - (_system->getMillis() - ctime);
+ if (del > 0)
+ delay(del, false, true);
+ updateDrawPage2();
+}
+
+void LoLEngine::shakeScene(int duration, int width, int height, int restore) {
+ _screen->copyRegion(112, 0, 112, 0, 176, 120, 0, 6, Screen::CR_NO_P_CHECK);
+ uint32 endTime = _system->getMillis() + duration * _tickLength;
+
+ while (endTime > _system->getMillis()) {
+ _smoothScrollTimer = _system->getMillis() + 2 * _tickLength;
+
+ int s1 = width ? (getRandomNumberSpecial() % (width << 1)) - width : 0;
+ int s2 = height ? (getRandomNumberSpecial() % (height << 1)) - height : 0;
+
+ int x1, y1, x2, y2, w, h;
+ if (s1 >= 0) {
+ x1 = 112;
+ x2 = 112;
+ w = 176 - s1;
+ } else {
+ x1 = 112 - s1;
+ x2 = 112 + s1;
+ w = 176 + s1;
+ }
+
+ if (s2 >= 0) {
+ y1 = 0;
+ y2 = 0;
+ h = 120 - s2;
+ } else {
+ y1 = -s2;
+ y2 = s2;
+ h = 120 + s2;
+ }
+
+ _screen->copyRegion(x1, y1, x2, y2, w, h, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+
+ delayUntil(_smoothScrollTimer);
+ }
+
+ if (restore) {
+ _screen->copyRegion(112, 0, 112, 0, 176, 120, 6, 0, Screen::CR_NO_P_CHECK);
+ _screen->updateScreen();
+ updateDrawPage2();
+ }
+}
+
int LoLEngine::smoothScrollDrawSpecialShape(int pageNum) {
// TODO
if(!_scriptAssignedLevelShape)
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index 81bad0522d..47d526f915 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -528,6 +528,96 @@ void Screen_LoL::smoothScrollTurnStep3(int srcPage1Num, int srcPage2Num, int dst
}
}
+void Screen_LoL::copyRegionSpecial(int page1, int w1, int h1, int x1, int y1, int page2, int w2, int h2, int x2, int y2, int w3, int h3, int mode, ...) {
+ if (!w3 || !h3)
+ return;
+
+ uint8 *table1 = 0;
+ uint8 *table2 = 0;
+
+ if (mode == 2) {
+ va_list args;
+ va_start(args, mode);
+ table1 = va_arg(args, uint8*);
+ table2 = va_arg(args, uint8*);
+ va_end(args);
+ }
+
+ _internDimX = _internDimY = 0;
+ _internDimW = w1;
+ _internDimH = h1;
+ calcBoundariesIntern(x1, y1, w3, h3);
+ if (_internBlockWidth == -1)
+ return;
+
+ int iu5_1 = _internDimU5;
+ int iu6_1 = _internDimU6;
+ int ibw_1 = _internBlockWidth;
+ int ibh_1 = _internBlockHeight;
+ int dx_1 = _internDimDstX;
+ int dy_1 = _internDimDstY;
+
+ _internDimX = _internDimY = 0;
+ _internDimW = w2;
+ _internDimH = h2;
+
+ calcBoundariesIntern(x2, y2, ibw_1, ibh_1);
+ if (_internBlockWidth == -1)
+ return;
+
+ int iu5_2 = _internDimU5;
+ int iu6_2 = _internDimU6;
+ int ibw_2 = _internBlockWidth;
+ int ibh_2 = _internBlockHeight;
+ int dx_2 = _internDimDstX;
+ int dy_2 = _internDimDstY;
+
+ uint8 *src = getPagePtr(page1) + (dy_1 + iu6_2) * w1;
+ uint8 *dst = getPagePtr(page2) + (dy_2 + iu6_1) * w2;
+
+ for (int i = 0; i < ibh_2; i++) {
+ uint8 *s = src + iu5_2 + dx_1;
+ uint8 *d = dst + iu5_1 + dx_2;
+
+ if (mode == 0) {
+ memcpy(d, s, ibw_2);
+
+ } else if (mode == 1) {
+ if (!(i & 1)) {
+ s++;
+ d++;
+ }
+
+ for (int ii = (i & 1) ^ 1; ii < ibw_2; ii += 2 ) {
+ *d = *s;
+ d += 2;
+ s += 2;
+ }
+
+ } else if (mode == 2) {
+ for (int ii = 0; ii < ibw_2; ii++) {
+ uint8 cmd = *s++;
+ uint8 offs = table1[cmd];
+ if (!(offs & 0x80))
+ cmd = table2[(offs << 8) | *d];
+ *d++ = cmd;
+ }
+
+ } else if (mode == 3) {
+ s = s - iu5_2 + ibw_1;
+ s = s - iu5_2 - 1;
+ for (int ii = 0; ii < ibw_2; ii++)
+ *d++ = *s--;
+ }
+
+ dst += w2;
+ src += w1;
+ }
+
+ if (!page2)
+ addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
+}
+
void Screen_LoL::copyBlockSpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl) {
if (!w || !h || !ovl)
return;
@@ -538,7 +628,7 @@ void Screen_LoL::copyBlockSpecial(int page1, int x1, int y1, int page2, int x2,
_internDimW = cdim->w << 3;
_internDimH = cdim->h;
- calcMapBoundaries(x2, y2, w, h);
+ calcBoundariesIntern(x2, y2, w, h);
if (_internBlockWidth == -1)
return;
@@ -560,7 +650,8 @@ void Screen_LoL::copyBlockSpecial(int page1, int x1, int y1, int page2, int x2,
src += 320;
}
- addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
+ if (!page2)
+ addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
}
void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, int flag, uint8 *ovl) {
@@ -573,7 +664,7 @@ void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x
_internDimW = cdim->w << 3;
_internDimH = cdim->h;
- calcMapBoundaries(x2, y2, w, h);
+ calcBoundariesIntern(x2, y2, w, h);
if (_internBlockWidth == -1)
return;
@@ -597,10 +688,11 @@ void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x
src += 320;
}
- addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
+ if (!page2)
+ addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
}
-void Screen_LoL::calcMapBoundaries(int dstX, int dstY, int width, int height) {
+void Screen_LoL::calcBoundariesIntern(int dstX, int dstY, int width, int height) {
_internBlockWidth = _internBlockWidth2 = width;
_internBlockHeight = height;
_internDimDstX = dstX;
diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h
index e839f31752..2f230d79a6 100644
--- a/engines/kyra/screen_lol.h
+++ b/engines/kyra/screen_lol.h
@@ -62,6 +62,8 @@ public:
void smoothScrollTurnStep2(int srcPage1Num, int srcPage2Num, int dstPageNum);
void smoothScrollTurnStep3(int srcPage1Num, int srcPage2Num, int dstPageNum);
+ void copyRegionSpecial(int page1, int w1, int h1, int x1, int y1, int page2, int w2, int h2, int x2, int y2, int w3, int h3, int mode, ...);
+
// palette stuff
void fadeToBlack(int delay=0x54, const UpdateFunctor *upFunc = 0);
void fadeToPalette1(int delay);
@@ -99,7 +101,7 @@ private:
uint8 *_levelOverlays[8];
// magic atlas
- void calcMapBoundaries(int dstX, int dstY, int c, int d);
+ void calcBoundariesIntern(int dstX, int dstY, int c, int d);
int _internDimX;
int _internDimY;
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index 8a44e3c0d3..41dc2b8ef0 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -1663,6 +1663,39 @@ int LoLEngine::olol_castSpell(EMCState *script) {
return castSpell(stackPos(0), stackPos(1), stackPos(2));
}
+int LoLEngine::olol_pitDrop(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_pitDrop(%p) (%d)", (const void *)script, stackPos(0));
+ int m = stackPos(0);
+ _screen->updateScreen();
+ if (m) {
+ gui_drawScene(2);
+ pitDropScroll(9);
+ snd_playSoundEffect(-1, -1);
+ shakeScene(30, 4, 0, 1);
+
+ } else {
+ int t = -1;
+ for (int i = 0; i < 4; i++) {
+ if (!(_characters[i].flags & 1) || (_characters[i].id >= 0))
+ continue;
+ if (_characters[i].id == -1)
+ t = 54;
+ else if (_characters[i].id == -5)
+ t = 53;
+ else if (_characters[i].id == -8)
+ t = 52;
+ else if (_characters[i].id == -9)
+ t = 51;
+ }
+
+ _screen->fillRect(112, 0, 288, 120, 0, 2);
+ snd_playSoundEffect(t, -1);
+ pitDropScroll(12);
+ }
+
+ return 1;
+}
+
int LoLEngine::olol_paletteFlash(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_paletteFlash(%p) (%d)", (const void *)script, stackPos(0));
uint8 *s = _screen->getPalette(1);
@@ -1686,13 +1719,10 @@ int LoLEngine::olol_paletteFlash(EMCState *script) {
delay(2 * _tickLength);
_screen->setScreenPalette(s);
- _screen->updateScreen();
-
- if (_smoothScrollModeNormal) {
+ if (_smoothScrollModeNormal)
_screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
- _screen->updateScreen();
- }
-
+
+ _screen->updateScreen();
return 0;
}
@@ -2247,7 +2277,7 @@ void LoLEngine::setupOpcodeTable() {
// 0xAC
OpcodeUnImpl();
Opcode(olol_castSpell);
- OpcodeUnImpl();
+ Opcode(olol_pitDrop);
OpcodeUnImpl();
// 0xB0
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index de81b667f4..9f15d94518 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -1485,7 +1485,7 @@ private:
class TownsPC98_OpnSquareSineSource {
public:
- TownsPC98_OpnSquareSineSource(const uint32 timerbase);
+ TownsPC98_OpnSquareSineSource(const uint32 timerbase, const uint8 levelOutModifier);
~TownsPC98_OpnSquareSineSource();
void init(const int *rsTable, const int *rseTable);
@@ -1516,6 +1516,7 @@ private:
int32 *_tleTable;
const uint32 _tickLength;
+ const uint8 _levelOutModifier;
uint32 _timer;
struct Channel {
@@ -2553,8 +2554,8 @@ bool TownsPC98_OpnChannelPCM::control_ff_endOfTrack(uint8 para) {
}
}
-TownsPC98_OpnSquareSineSource::TownsPC98_OpnSquareSineSource(const uint32 timerbase) : _tlTable(0),
- _tleTable(0), _updateRequest(-1), _tickLength(timerbase * 27), _ready(0), _reg(0), _rand(1), _outN(1),
+TownsPC98_OpnSquareSineSource::TownsPC98_OpnSquareSineSource(const uint32 timerbase, const uint8 levelOutModifier) : _tlTable(0),
+ _tleTable(0), _updateRequest(-1), _tickLength(timerbase * 27), _levelOutModifier(levelOutModifier), _ready(0), _reg(0), _rand(1), _outN(1),
_nTick(0), _evpUpdateCnt(0), _evpTimer(0x1f), _pReslt(0x1f), _attack(0), _cont(false), _evpUpdate(true),
_timer(0), _noiseGenerator(0), _chanEnable(0) {
@@ -2714,7 +2715,7 @@ void TownsPC98_OpnSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) {
finOut += _tlTable[_channels[ii].out ? (_channels[ii].vol & 0x0f) : 0];
}
- finOut >>= 1;
+ finOut >>= _levelOutModifier;
buffer[i << 1] += finOut;
buffer[(i << 1) + 1] += finOut;
}
@@ -2887,7 +2888,7 @@ void TownsPC98_OpnPercussionSource::nextTick(int32 *buffer, uint32 bufferSize) {
finOut += _rhChan[ii].out;
}
- finOut <<= 2;
+ finOut <<= 1;
buffer[i << 1] += finOut;
buffer[(i << 1) + 1] += finOut;
@@ -2968,7 +2969,7 @@ bool TownsPC98_OpnCore::init() {
}
if (_numSSG) {
- _ssg = new TownsPC98_OpnSquareSineSource(_timerbase);
+ _ssg = new TownsPC98_OpnSquareSineSource(_timerbase, _numChan / 3);
_ssg->init(&_ssgTables[0], &_ssgTables[16]);
}
diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp
index f9890ea9b1..06e974963a 100644
--- a/engines/kyra/sprites_lol.cpp
+++ b/engines/kyra/sprites_lol.cpp
@@ -1255,7 +1255,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) {
if (flyingObject == 1) {
snd_playSoundEffect(147, -1);
- distObj1Sub(10, 2, 2, 1);
+ shakeScene(10, 2, 2, 1);
for (int i = 0; i < 4; i++) {
if (!(_characters[i].flags & 1))