aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232014-04-15 13:21:00 +0200
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commit1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6 (patch)
treed8a58e89f20839b2853551bf41b28a9623a0e2af
parentb1927ca30458226ad7ed52cc85d37416261d444d (diff)
downloadscummvm-rg350-1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6.tar.gz
scummvm-rg350-1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6.tar.bz2
scummvm-rg350-1f74de6a4679cecba4fd77e9c79cfaee9c3dd0f6.zip
ILLUSIONS: More work on Duckman
- Implement palette fader - Add more inventory functions - Add more script opcodes
-rw-r--r--engines/illusions/illusions.cpp26
-rw-r--r--engines/illusions/illusions.h7
-rw-r--r--engines/illusions/illusions_bbdou.cpp4
-rw-r--r--engines/illusions/illusions_duckman.cpp76
-rw-r--r--engines/illusions/illusions_duckman.h9
-rw-r--r--engines/illusions/screen.cpp46
-rw-r--r--engines/illusions/screen.h20
-rw-r--r--engines/illusions/scriptopcodes_duckman.cpp31
-rw-r--r--engines/illusions/scriptopcodes_duckman.h2
9 files changed, 197 insertions, 24 deletions
diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp
index 8a350961e2..afaaa00a3a 100644
--- a/engines/illusions/illusions.cpp
+++ b/engines/illusions/illusions.cpp
@@ -141,6 +141,7 @@ int IllusionsEngine::updateGraphics() {
uint32 currTime = getCurrentTime();
_camera->update(currTime);
+ updateFader();
// TODO Move to BackgroundItems class
BackgroundItem *backgroundItem = _backgroundItems->findActiveBackground();
@@ -177,8 +178,6 @@ int IllusionsEngine::updateGraphics() {
*/
if (actor->_surfInfo._dimensions._width && actor->_surfInfo._dimensions._height) {
uint32 priority = control->getPriority();
-//if (control->_objectId == 0x0004001B) continue;
-//debug("objectId: %08X; priority: %d (%d)", control->_objectId, priority, control->_priority);
_screen->_drawQueue->insertSprite(&actor->_drawFlags, actor->_surface,
actor->_surfInfo._dimensions, drawPosition, control->_position,
priority, actor->_scale, actor->_spriteFlags);
@@ -268,6 +267,29 @@ bool IllusionsEngine::isVoicePlaying() {
return false;
}
+void IllusionsEngine::updateFader() {
+ if (_fader && !_fader->_paused && _fader->_active) {
+ int32 currTime = getCurrentTime();
+ int32 currDuration = currTime - _fader->_startTime;
+ if (currDuration) {
+ int newValue;
+ if (currDuration >= _fader->_duration) {
+ newValue = _fader->_maxValue;
+ } else {
+ newValue = (currDuration * (_fader->_maxValue - _fader->_minValue) / _fader->_duration) + _fader->_minValue;
+ }
+ if (_fader->_currValue != newValue) {
+ _fader->_currValue = newValue;
+ _screen->setFader(newValue, _fader->_firstIndex, _fader->_lastIndex);
+ }
+ if (_fader->_currValue == _fader->_maxValue) {
+ _fader->_active = false;
+ notifyThreadId(_fader->_notifyThreadId);
+ }
+ }
+ }
+}
+
void IllusionsEngine::setCurrFontId(uint32 fontId) {
_fontId = fontId;
}
diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h
index 63fb3f6d3e..4ef193156d 100644
--- a/engines/illusions/illusions.h
+++ b/engines/illusions/illusions.h
@@ -61,6 +61,7 @@ class Control;
class Controls;
class Cursor;
class Dictionary;
+struct Fader;
class FramesList;
class Input;
class Screen;
@@ -111,7 +112,9 @@ public:
ThreadList *_threads;
ScriptResource *_scriptResource;
-
+
+ Fader *_fader;
+
int _resGetCtr;
uint32 _resGetTime;
bool _unpauseControlActorFlag;
@@ -146,6 +149,8 @@ public:
void stopVoice();
bool isVoicePlaying();
+ void updateFader();
+
void setCurrFontId(uint32 fontId);
bool checkActiveTalkThreads();
uint32 clipTextDuration(uint32 duration);
diff --git a/engines/illusions/illusions_bbdou.cpp b/engines/illusions/illusions_bbdou.cpp
index 931db5c2ee..3b78e1ab7f 100644
--- a/engines/illusions/illusions_bbdou.cpp
+++ b/engines/illusions/illusions_bbdou.cpp
@@ -214,6 +214,8 @@ Common::Error IllusionsEngine_BBDOU::run() {
_triggerFunctions = new TriggerFunctions();
_threads = new ThreadList(this);
+ _fader = 0;
+
_scriptOpcodes = new ScriptOpcodes_BBDOU(this);
_stack = new ScriptStack();
@@ -229,7 +231,7 @@ Common::Error IllusionsEngine_BBDOU::run() {
_globalSceneId = 0x00010003;
- setDefaultTextCoords();
+ setDefaultTextCoords();
_resSys->loadResource(0x000D0001, 0, 0);
diff --git a/engines/illusions/illusions_duckman.cpp b/engines/illusions/illusions_duckman.cpp
index 9f67d6bb93..1c9d30a535 100644
--- a/engines/illusions/illusions_duckman.cpp
+++ b/engines/illusions/illusions_duckman.cpp
@@ -105,6 +105,8 @@ Common::Error IllusionsEngine_Duckman::run() {
_talkItems = new TalkItems(this);
_threads = new ThreadList(this);
+ _fader = new Fader();
+
_scriptOpcodes = new ScriptOpcodes_Duckman(this);
_stack = new ScriptStack();
@@ -150,6 +152,8 @@ Common::Error IllusionsEngine_Duckman::run() {
delete _stack;
delete _scriptOpcodes;
+ delete _fader;
+
delete _threads;
delete _talkItems;
delete _controls;
@@ -177,6 +181,19 @@ bool IllusionsEngine_Duckman::hasFeature(EngineFeature f) const {
*/
}
+
+void IllusionsEngine_Duckman::startFader(int duration, int minValue, int maxValue, int firstIndex, int lastIndex, uint32 threadId) {
+ _fader->_active = true;
+ _fader->_currValue = minValue;
+ _fader->_minValue = minValue;
+ _fader->_maxValue = maxValue;
+ _fader->_firstIndex = firstIndex;
+ _fader->_lastIndex = lastIndex;
+ _fader->_startTime = getCurrentTime();
+ _fader->_duration = duration;
+ _fader->_notifyThreadId = threadId;
+}
+
void IllusionsEngine_Duckman::setDefaultTextCoords() {
WidthHeight dimensions;
dimensions._width = 300;
@@ -1038,6 +1055,34 @@ void IllusionsEngine_Duckman::addInventoryItem(uint32 objectId) {
control->appearActor();
}
+void IllusionsEngine_Duckman::clearInventorySlot(uint32 objectId) {
+ for (uint i = 0; i < _inventorySlots.size(); ++i)
+ if (_inventorySlots[i]._objectId == objectId)
+ _inventorySlots[i]._objectId = 0;
+}
+
+void IllusionsEngine_Duckman::putBackInventoryItem() {
+ Common::Point mousePos = _input->getCursorPosition();
+ if (_cursor._objectId) {
+ DMInventorySlot *inventorySlot = findInventorySlot(_cursor._objectId);
+ if (inventorySlot)
+ inventorySlot->_objectId = 0;
+ inventorySlot = findClosestInventorySlot(mousePos);
+ inventorySlot->_objectId = _cursor._objectId;
+ Control *control = getObjectControl(_cursor._objectId);
+ control->setActorPosition(inventorySlot->_position);
+ control->appearActor();
+ _cursor._actorIndex = 7;
+ stopCursorHoldingObject();
+ _cursor._actorIndex = 2;
+ _cursor._control->startSequenceActor(_cursor._sequenceId1, 2, 0);
+ if (_cursor._currOverlappedControl)
+ setCursorActorIndex(_cursor._actorIndex, 2, 0);
+ else
+ setCursorActorIndex(_cursor._actorIndex, 1, 0);
+ }
+}
+
DMInventorySlot *IllusionsEngine_Duckman::findInventorySlot(uint32 objectId) {
for (uint i = 0; i < _inventorySlots.size(); ++i)
if (_inventorySlots[i]._objectId == objectId)
@@ -1052,6 +1097,24 @@ DMInventoryItem *IllusionsEngine_Duckman::findInventoryItem(uint32 objectId) {
return 0;
}
+DMInventorySlot *IllusionsEngine_Duckman::findClosestInventorySlot(Common::Point pos) {
+ int minDistance = 0xFFFFFF;
+ DMInventorySlot *minInventorySlot = 0;
+ for (uint i = 0; i < _inventorySlots.size(); ++i) {
+ DMInventorySlot *inventorySlot = &_inventorySlots[i];
+ if (inventorySlot->_objectId == 0) {
+ int16 deltaX = ABS(inventorySlot->_position.x - pos.x);
+ int16 deltaY = ABS(inventorySlot->_position.y - pos.y);
+ int distance = deltaX * deltaX + deltaY * deltaY;
+ if (inventorySlot->_objectId == 0 && distance < minDistance) {
+ minDistance = distance;
+ minInventorySlot = inventorySlot;
+ }
+ }
+ }
+ return minInventorySlot;
+}
+
// Special code
typedef Common::Functor1Mem<OpCall&, void, IllusionsEngine_Duckman> SpecialCodeFunctionDM;
@@ -1060,6 +1123,8 @@ typedef Common::Functor1Mem<OpCall&, void, IllusionsEngine_Duckman> SpecialCodeF
void IllusionsEngine_Duckman::initSpecialCode() {
SPECIAL(0x00160002, spcSetCursorHandMode);
SPECIAL(0x00160005, spcOpenInventory);
+ SPECIAL(0x00160007, spcPutBackInventoryItem);
+ SPECIAL(0x00160008, spcClearInventorySlot);
SPECIAL(0x00160010, spcCenterNewspaper);
SPECIAL(0x00160014, spcUpdateObject272Sequence);
SPECIAL(0x0016001C, spcSetCursorInventoryMode);
@@ -1086,6 +1151,17 @@ void IllusionsEngine_Duckman::spcOpenInventory(OpCall &opCall) {
notifyThreadId(opCall._threadId);
}
+void IllusionsEngine_Duckman::spcPutBackInventoryItem(OpCall &opCall) {
+ putBackInventoryItem();
+ notifyThreadId(opCall._threadId);
+}
+
+void IllusionsEngine_Duckman::spcClearInventorySlot(OpCall &opCall) {
+ ARG_UINT32(objectId);
+ clearInventorySlot(objectId);
+ notifyThreadId(opCall._threadId);
+}
+
void IllusionsEngine_Duckman::spcCenterNewspaper(OpCall &opCall) {
Control *control = getObjectControl(0x40017);
control->_flags |= 8;
diff --git a/engines/illusions/illusions_duckman.h b/engines/illusions/illusions_duckman.h
index 3b369b9b75..0502089479 100644
--- a/engines/illusions/illusions_duckman.h
+++ b/engines/illusions/illusions_duckman.h
@@ -109,6 +109,8 @@ public:
Common::Array<DMInventoryItem> _inventoyItems;
SpecialCodeMap _specialCodeMap;
+
+ void startFader(int duration, int minValue, int maxValue, int firstIndex, int lastIndex, uint32 threadId);
void setDefaultTextCoords();
@@ -185,15 +187,20 @@ public:
void initInventory();
void openInventory();
+ void addInventoryItem(uint32 objectId);
+ void clearInventorySlot(uint32 objectId);
+ void putBackInventoryItem();
DMInventorySlot *findInventorySlot(uint32 objectId);
DMInventoryItem *findInventoryItem(uint32 objectId);
- void addInventoryItem(uint32 objectId);
+ DMInventorySlot *findClosestInventorySlot(Common::Point pos);
// Special code
void initSpecialCode();
void runSpecialCode(uint32 specialCodeId, OpCall &opCall);
void spcSetCursorHandMode(OpCall &opCall);
void spcOpenInventory(OpCall &opCall);
+ void spcPutBackInventoryItem(OpCall &opCall);
+ void spcClearInventorySlot(OpCall &opCall);
void spcCenterNewspaper(OpCall &opCall);
void spcSetCursorInventoryMode(OpCall &opCall);
void spcUpdateObject272Sequence(OpCall &opCall);
diff --git a/engines/illusions/screen.cpp b/engines/illusions/screen.cpp
index 35e8b59271..2ac1a44eaf 100644
--- a/engines/illusions/screen.cpp
+++ b/engines/illusions/screen.cpp
@@ -237,6 +237,8 @@ Screen::Screen(IllusionsEngine *vm, int16 width, int16 height, int bpp)
_needRefreshPalette = false;
memset(_mainPalette, 0, sizeof(_mainPalette));
+ _isFaderActive = false;
+
}
Screen::~Screen() {
@@ -372,12 +374,52 @@ void Screen::shiftPalette(int16 fromIndex, int16 toIndex) {
void Screen::updatePalette() {
if (_needRefreshPalette) {
- // TODO Update fader palette
- setSystemPalette(_mainPalette);
+ if (_isFaderActive) {
+ updateFaderPalette();
+ setSystemPalette(_faderPalette);
+ } else {
+ setSystemPalette(_mainPalette);
+ }
_needRefreshPalette = false;
}
}
+void Screen::updateFaderPalette() {
+ if (_newFaderValue >= 255) {
+ _newFaderValue -= 256;
+ for (int i = _firstFaderIndex; i <= _lastFaderIndex; ++i) {
+ byte r = _mainPalette[i * 3 + 0];
+ byte g = _mainPalette[i * 3 + 1];
+ byte b = _mainPalette[i * 3 + 2];
+ _faderPalette[i * 3 + 0] = r - (((_newFaderValue * (255 - r)) >> 8) & 0xFF);
+ _faderPalette[i * 3 + 1] = g - (((_newFaderValue * (255 - g)) >> 8) & 0xFF);
+ _faderPalette[i * 3 + 2] = b - (((_newFaderValue * (255 - b)) >> 8) & 0xFF);
+ }
+ } else {
+ for (int i = _firstFaderIndex; i <= _lastFaderIndex; ++i) {
+ byte r = _mainPalette[i * 3 + 0];
+ byte g = _mainPalette[i * 3 + 1];
+ byte b = _mainPalette[i * 3 + 2];
+ _faderPalette[i * 3 + 0] = _newFaderValue * r / 255;
+ _faderPalette[i * 3 + 1] = _newFaderValue * g / 255;
+ _faderPalette[i * 3 + 2] = _newFaderValue * b / 255;
+ }
+ }
+}
+
+void Screen::setFader(int newValue, int firstIndex, int lastIndex) {
+ if (newValue == 255) {
+ _isFaderActive = false;
+ _needRefreshPalette = true;
+ } else {
+ _isFaderActive = true;
+ _needRefreshPalette = true;
+ _newFaderValue = newValue;
+ _firstFaderIndex = firstIndex - 1;
+ _lastFaderIndex = lastIndex;
+ }
+}
+
void Screen::buildColorTransTbl() {
const int cr = _mainPalette[3 * 1 + 0];
const int cg = _mainPalette[3 * 1 + 1];
diff --git a/engines/illusions/screen.h b/engines/illusions/screen.h
index bdecda48a5..15a703c46c 100644
--- a/engines/illusions/screen.h
+++ b/engines/illusions/screen.h
@@ -97,6 +97,20 @@ protected:
bool calcItemRect(SpriteDrawQueueItem *item, Common::Rect &srcRect, Common::Rect &dstRect);
};
+struct Fader {
+ bool _active;
+ int _currValue;
+ bool _paused;
+ int _minValue;
+ int _maxValue;
+ int _firstIndex;
+ int _lastIndex;
+ uint32 _startTime;
+ int _duration;
+ uint32 _notifyThreadId;
+ Fader() : _active(false), _paused(false) {}
+};
+
// TODO Split into two classes (8bit and 16bit)?
class Screen {
@@ -116,6 +130,8 @@ public:
void getPalette(byte *colors);
void shiftPalette(int16 fromIndex, int16 toIndex);
void updatePalette();
+ void updateFaderPalette();
+ void setFader(int newValue, int firstIndex, int lastIndex);
void drawText(FontResource *font, Graphics::Surface *surface, int16 x, int16 y, uint16 *text, uint count);
int16 drawChar(FontResource *font, Graphics::Surface *surface, int16 x, int16 y, uint16 c);
int16 getScreenWidth() const { return _backSurface->w; }
@@ -133,6 +149,10 @@ public:
byte _mainPalette[768];
byte _colorTransTbl[256];
+ bool _isFaderActive;
+ byte _faderPalette[768];
+ int _newFaderValue, _firstFaderIndex, _lastFaderIndex;
+
void setSystemPalette(byte *palette);
void buildColorTransTbl();
diff --git a/engines/illusions/scriptopcodes_duckman.cpp b/engines/illusions/scriptopcodes_duckman.cpp
index b932037f00..3b90e0c5e3 100644
--- a/engines/illusions/scriptopcodes_duckman.cpp
+++ b/engines/illusions/scriptopcodes_duckman.cpp
@@ -74,6 +74,7 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(32, opPanCenterObject);
OPCODE(33, opPanTrackObject);
OPCODE(34, opPanToObject);
+ OPCODE(35, opPanToNamedPoint);
OPCODE(36, opPanToPoint);
OPCODE(37, opPanStop);
OPCODE(38, opStartFade);
@@ -134,7 +135,6 @@ void ScriptOpcodes_Duckman::initOpcodes() {
OPCODE(20, opEnterScene);
OPCODE(30, opEnterCloseUpScene);
OPCODE(31, opExitCloseUpScene);
- OPCODE(35, opPanToNamedPoint);
OPCODE(53, opSetActorToNamedPoint);
OPCODE(63, opSetSelectSfx);
OPCODE(64, opSetMoveSfx);
@@ -336,6 +336,13 @@ void ScriptOpcodes_Duckman::opPanToObject(ScriptThread *scriptThread, OpCall &op
_vm->_camera->panToPoint(pos, speed, opCall._threadId);
}
+void ScriptOpcodes_Duckman::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) {
+ ARG_INT16(speed);
+ ARG_UINT32(namedPointId);
+ Common::Point pos = _vm->getNamedPointPosition(namedPointId);
+ _vm->_camera->panToPoint(pos, speed, opCall._threadId);
+}
+
void ScriptOpcodes_Duckman::opPanToPoint(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(speed);
ARG_INT16(x);
@@ -348,15 +355,14 @@ void ScriptOpcodes_Duckman::opPanStop(ScriptThread *scriptThread, OpCall &opCall
}
void ScriptOpcodes_Duckman::opStartFade(ScriptThread *scriptThread, OpCall &opCall) {
- ARG_INT16(arg1);
- ARG_INT16(arg2);
- ARG_INT16(arg3);
- ARG_INT16(arg4);
- ARG_INT16(arg5);
- // TODO
-
+ ARG_INT16(duration);
+ ARG_INT16(minValue);
+ ARG_INT16(maxValue);
+ ARG_INT16(firstIndex);
+ ARG_INT16(lastIndex);
+ _vm->startFader(duration, minValue, maxValue, firstIndex, lastIndex, opCall._threadId);
//DEBUG Resume calling thread, later done when the fading is finished
- _vm->notifyThreadId(opCall._threadId);
+ //_vm->notifyThreadId(opCall._threadId);
}
void ScriptOpcodes_Duckman::opSetDisplay(ScriptThread *scriptThread, OpCall &opCall) {
@@ -794,13 +800,6 @@ void ScriptOpcodes_Duckman::opExitCloseUpScene(ScriptThread *scriptThread, OpCal
opCall._result = kTSYield;
}
-void ScriptOpcodes_Duckman::opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) {
- ARG_INT16(speed);
- ARG_UINT32(namedPointId);
- Common::Point pos = _vm->getNamedPointPosition(namedPointId);
- _vm->_camera->panToPoint(pos, speed, opCall._threadId);
-}
-
void ScriptOpcodes_Duckman::opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(objectId);
diff --git a/engines/illusions/scriptopcodes_duckman.h b/engines/illusions/scriptopcodes_duckman.h
index 4c66d346d9..77050deb3f 100644
--- a/engines/illusions/scriptopcodes_duckman.h
+++ b/engines/illusions/scriptopcodes_duckman.h
@@ -61,6 +61,7 @@ protected:
void opPanCenterObject(ScriptThread *scriptThread, OpCall &opCall);
void opPanTrackObject(ScriptThread *scriptThread, OpCall &opCall);
void opPanToObject(ScriptThread *scriptThread, OpCall &opCall);
+ void opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);
void opPanToPoint(ScriptThread *scriptThread, OpCall &opCall);
void opPanStop(ScriptThread *scriptThread, OpCall &opCall);
void opStartFade(ScriptThread *scriptThread, OpCall &opCall);
@@ -121,7 +122,6 @@ protected:
void opEnterScene(ScriptThread *scriptThread, OpCall &opCall);
void opEnterCloseUpScene(ScriptThread *scriptThread, OpCall &opCall);
void opExitCloseUpScene(ScriptThread *scriptThread, OpCall &opCall);
- void opPanToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);
void opSetActorToNamedPoint(ScriptThread *scriptThread, OpCall &opCall);
void opSetSelectSfx(ScriptThread *scriptThread, OpCall &opCall);
void opSetMoveSfx(ScriptThread *scriptThread, OpCall &opCall);