ILLUSIONS: Fix special code functions thread notifying (used wrong thread value)

- Add more script and sequence opcodes
This commit is contained in:
johndoe123 2014-04-02 10:53:40 +02:00 committed by Eugene Sandulenko
parent 7dc8533f73
commit 8d7d6599b9
8 changed files with 97 additions and 16 deletions

View File

@ -105,6 +105,8 @@ void BbdouSpecialCode::init() {
SPECIAL(0x0016001E, spcRemoveInventoryItem);
SPECIAL(0x0016001F, spcHasInventoryItem);
SPECIAL(0x00160025, spcCloseInventory);
SPECIAL(0x00160037, spcIsCursorHoldingObjectId);
SPECIAL(0x0016003A, spcSaladCtl);
}
void BbdouSpecialCode::run(uint32 specialCodeId, OpCall &opCall) {
@ -113,7 +115,7 @@ void BbdouSpecialCode::run(uint32 specialCodeId, OpCall &opCall) {
(*(*it)._value)(opCall);
} else {
debug("BbdouSpecialCode::run() Unimplemented special code %08X", specialCodeId);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
}
@ -129,19 +131,19 @@ void BbdouSpecialCode::spcInitCursor(OpCall &opCall) {
ARG_UINT32(progResKeywordId);
_cursor->init(objectId, progResKeywordId);
setCursorControlRoutine(objectId, 0);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcEnableCursor(OpCall &opCall) {
ARG_UINT32(objectId);
_cursor->enable(objectId);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcDisableCursor(OpCall &opCall) {
ARG_UINT32(objectId);
_cursor->disable(objectId);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcAddCursorSequence(OpCall &opCall) {
@ -149,7 +151,7 @@ void BbdouSpecialCode::spcAddCursorSequence(OpCall &opCall) {
ARG_UINT32(objectId);
ARG_UINT32(sequenceId);
_cursor->addCursorSequence(objectId, sequenceId);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcCursorStartHoldingObjectId(OpCall &opCall) {
@ -157,7 +159,7 @@ void BbdouSpecialCode::spcCursorStartHoldingObjectId(OpCall &opCall) {
ARG_UINT32(holdingObjectId);
ARG_INT16(doPlaySound);
startHoldingObjectId(objectId, holdingObjectId, doPlaySound != 0);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcCursorStopHoldingObjectId(OpCall &opCall) {
@ -165,12 +167,12 @@ void BbdouSpecialCode::spcCursorStopHoldingObjectId(OpCall &opCall) {
ARG_INT16(doPlaySound);
stopHoldingObjectId(objectId, doPlaySound != 0);
_cursor->_data._mode = 1;
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcInitBubble(OpCall &opCall) {
_bubble->init();
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcSetupBubble(OpCall &opCall) {
@ -181,7 +183,7 @@ void BbdouSpecialCode::spcSetupBubble(OpCall &opCall) {
ARG_INT16(count);
_bubble->addItem0(sequenceId1, sequenceId2, progResKeywordId, namedPointId,
count, (uint32*)opCall._code);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcSetObjectInteractMode(OpCall &opCall) {
@ -189,7 +191,7 @@ void BbdouSpecialCode::spcSetObjectInteractMode(OpCall &opCall) {
ARG_UINT32(objectId);
ARG_INT16(value);
_cursor->setStruct8bsValue(objectId, value);
_vm->notifyThreadId(opCall._callerThreadId);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcRegisterInventoryBag(OpCall &opCall) {
@ -225,12 +227,33 @@ void BbdouSpecialCode::spcRemoveInventoryItem(OpCall &opCall) {
void BbdouSpecialCode::spcHasInventoryItem(OpCall &opCall) {
ARG_UINT32(objectId);
_vm->_scriptMan->_stack.push(_inventory->hasInventoryItem(objectId) ? 1 : 0);
debug("_inventory->hasInventoryItem(%08X) = %d", objectId, _inventory->hasInventoryItem(objectId));
}
void BbdouSpecialCode::spcCloseInventory(OpCall &opCall) {
_inventory->close();
}
void BbdouSpecialCode::spcIsCursorHoldingObjectId(OpCall &opCall) {
ARG_UINT32(cursorObjectId);
ARG_UINT32(objectId);
_vm->_scriptMan->_stack.push(isHoldingObjectId(objectId) ? 1 : 0);
_vm->notifyThreadId(opCall._threadId);
}
void BbdouSpecialCode::spcSaladCtl(OpCall &opCall) {
ARG_UINT32(cmd);
ARG_UINT32(sequenceId);
switch (cmd) {
case 1:
initSalad();
break;
case 2:
addSalad(sequenceId);
break;
}
}
void BbdouSpecialCode::playSoundEffect(int soundIndex) {
static const uint32 kSoundEffectIds[] = {
0, 1,
@ -644,4 +667,30 @@ void BbdouSpecialCode::stopHoldingObjectId(uint32 objectId1, bool doPlaySound) {
_inventory->putBackInventoryItem(holdingObjectId, control->_actor->_position);
}
bool BbdouSpecialCode::isHoldingObjectId(uint32 objectId) {
return _cursor->_data._holdingObjectId == objectId;
}
void BbdouSpecialCode::initSalad() {
for (uint i = 0; i < 12; ++i) {
_saladObjectIds[i] = _vm->_controls->newTempObjectId();
_vm->_controls->placeActor(0x00050192, Common::Point(0, 0), 0x00060C26, _saladObjectIds[i], 0);
}
_saladCount = 0;
}
void BbdouSpecialCode::addSalad(uint32 sequenceId) {
if (_saladCount >= 12) {
Control *control = _vm->_dict->getObjectControl(_saladObjectIds[_saladCount - 1]);
control->unlinkObject();
} else {
++_saladCount;
}
Control *control = _vm->_dict->getObjectControl(_saladObjectIds[_saladCount - 1]);
control->linkToObject(0x00040309, _saladCount);
control->startSequenceActor(sequenceId, 2, 0);
control->setPriority(_saladCount + 9);
control->deactivateObject();
}
} // End of namespace Illusions

View File

@ -76,6 +76,11 @@ public:
BbdouCursor *_cursor;
BbdouBubble *_bubble;
BbdouInventory *_inventory;
// Salad
uint _saladCount;
uint32 _saladObjectIds[12];
// Special code interface functions
void spcInitCursor(OpCall &opCall);
void spcEnableCursor(OpCall &opCall);
@ -94,11 +99,14 @@ public:
void spcRemoveInventoryItem(OpCall &opCall);
void spcHasInventoryItem(OpCall &opCall);
void spcCloseInventory(OpCall &opCall);
void spcIsCursorHoldingObjectId(OpCall &opCall);
void spcSaladCtl(OpCall &opCall);
void playSoundEffect(int soundIndex);
void resetItem10(uint32 objectId, Item10 *item10);
void startHoldingObjectId(uint32 objectId1, uint32 holdingObjectId, bool doPlaySound);
void stopHoldingObjectId(uint32 objectId1, bool doPlaySound);
bool isHoldingObjectId(uint32 objectId);
protected:
// Internal functions
@ -116,6 +124,9 @@ protected:
bool runCause(Control *cursorControl, CursorData &cursorData,
uint32 verbId, uint32 objectId2, uint32 objectId, int soundIndex);
uint32 startCauseThread(uint32 cursorObjectId, uint32 sceneId, uint32 verbId, uint32 objectId2, uint32 objectId);
// Salad
void initSalad();
void addSalad(uint32 sequenceId);
};
} // End of namespace Illusions

View File

@ -109,6 +109,7 @@ void ScriptOpcodes::initOpcodes() {
OPCODE(37, opPanStop);
OPCODE(39, opSetDisplay);
OPCODE(42, opIncBlockCounter);
OPCODE(43, opClearBlockCounter);
OPCODE(45, opSetProperty);
OPCODE(46, opPlaceActor);
OPCODE(47, opFaceActor);
@ -263,13 +264,17 @@ void ScriptOpcodes::opEnterScene(ScriptThread *scriptThread, OpCall &opCall) {
}
//DEBUG Scenes
uint32 dsceneId = 0x00010031, dthreadId = 0x00020036;//MAP
//uint32 dsceneId = 0x00010031, dthreadId = 0x00020036;//MAP
//uint32 dsceneId = 0x00010028, dthreadId = 0x000202A1;
//uint32 dsceneId = 0x00010007, dthreadId = 0x0002000C;//Auditorium
//uint32 dsceneId = 0x0001000B, dthreadId = 0x00020010;
//uint32 dsceneId = 0x00010013, dthreadId = 0x00020018;//Therapist
//uint32 dsceneId = 0x00010016, dthreadId = 0x0002001B;//Dorms ext
//uint32 dsceneId = 0x00010017, dthreadId = 0x0002001C;//Dorms int
//uint32 dsceneId = 0x0001000D, dthreadId = 0x00020012;//Food minigame
//uint32 dsceneId = 0x00010067, dthreadId = 0x0002022A;
//uint32 dsceneId = 0x0001000C, dthreadId = 0x00020011;//Cafeteria
uint32 dsceneId = 0x0001000B, dthreadId = 0x00020010;
void ScriptOpcodes::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
@ -373,6 +378,11 @@ void ScriptOpcodes::opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall
_vm->_scriptMan->_scriptResource->_blockCounters.set(index, value);
}
void ScriptOpcodes::opClearBlockCounter(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(index);
_vm->_scriptMan->_scriptResource->_blockCounters.set(index, 0);
}
void ScriptOpcodes::opSetProperty(ScriptThread *scriptThread, OpCall &opCall) {
ARG_INT16(value);
ARG_UINT32(propertyId);
@ -690,7 +700,7 @@ void ScriptOpcodes::opCompareBlockCounter(ScriptThread *scriptThread, OpCall &op
void ScriptOpcodes::opDebug126(ScriptThread *scriptThread, OpCall &opCall) {
// NOTE Prints some debug text
debug("[DBG] %s", (char*)opCall._code);
debug(1, "[DBG] %s", (char*)opCall._code);
}
void ScriptOpcodes::opPlayVideo(ScriptThread *scriptThread, OpCall &opCall) {
@ -747,7 +757,7 @@ void ScriptOpcodes::opStartAbortableThread(ScriptThread *scriptThread, OpCall &o
ARG_INT16(codeOffs);
ARG_INT16(skipOffs);
_vm->_scriptMan->startAbortableThread(opCall._code + codeOffs,
opCall._code + skipOffs, opCall._callerThreadId);
opCall._code + skipOffs, opCall._threadId);
}
void ScriptOpcodes::opKillThread(ScriptThread *scriptThread, OpCall &opCall) {

View File

@ -83,6 +83,7 @@ protected:
void opPanStop(ScriptThread *scriptThread, OpCall &opCall);
void opSetDisplay(ScriptThread *scriptThread, OpCall &opCall);
void opIncBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
void opClearBlockCounter(ScriptThread *scriptThread, OpCall &opCall);
void opSetProperty(ScriptThread *scriptThread, OpCall &opCall);
void opPlaceActor(ScriptThread *scriptThread, OpCall &opCall);
void opFaceActor(ScriptThread *scriptThread, OpCall &opCall);

View File

@ -25,6 +25,7 @@
#include "illusions/actor.h"
#include "illusions/actorresource.h"
#include "illusions/dictionary.h"
#include "illusions/scriptman.h"
#include "illusions/scriptopcodes.h"
namespace Illusions {
@ -82,6 +83,7 @@ void SequenceOpcodes::initOpcodes() {
OPCODE(40, opSetPriorityLayer);
OPCODE(50, opPlaySound);
OPCODE(51, opStopSound);
OPCODE(52, opStartScriptThread);
OPCODE(53, opPlaceSubActor);
OPCODE(54, opStartSubSequence);
OPCODE(55, opStopSubSequence);
@ -311,6 +313,12 @@ void SequenceOpcodes::opStopSound(Control *control, OpCall &opCall) {
// TODO _vm->stopSound(soundEffectId);
}
void SequenceOpcodes::opStartScriptThread(Control *control, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(threadId);
_vm->_scriptMan->startScriptThread(threadId, 0, 0, 0, 0);
}
void SequenceOpcodes::opPlaceSubActor(Control *control, OpCall &opCall) {
ARG_INT16(linkIndex);
ARG_UINT32(actorTypeId);

View File

@ -72,6 +72,7 @@ protected:
void opSetPriorityLayer(Control *control, OpCall &opCall);
void opPlaySound(Control *control, OpCall &opCall);
void opStopSound(Control *control, OpCall &opCall);
void opStartScriptThread(Control *control, OpCall &opCall);
void opPlaceSubActor(Control *control, OpCall &opCall);
void opStartSubSequence(Control *control, OpCall &opCall);
void opStopSubSequence(Control *control, OpCall &opCall);

View File

@ -78,7 +78,8 @@ TalkThread::TalkThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThrea
if (callingThread)
_tag = callingThread->_tag;
}
//debug("New talk thread: %08X %08X", _threadId, _talkId);
}
int TalkThread::onUpdate() {
@ -307,7 +308,7 @@ static char *debugW2I(byte *wstr) {
int TalkThread::insertText() {
int charCount = 100;
debug("[%s]", debugW2I(_currEntryText));
debug("%08X %08X [%s]", _threadId, _talkId, debugW2I(_currEntryText));
_entryText = 0;
// TODO _vm->getDimensions1(&dimensions);

View File

@ -267,7 +267,7 @@ void ThreadList::killThread(uint32 threadId) {
if (childThread->_callingThreadId == threadId)
killThread(childThread->_threadId);
}
thread->onKill();
}