aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232015-12-15 11:39:21 +0100
committerEugene Sandulenko2018-07-20 06:43:33 +0000
commit48011948d60f700676629e157de75475d52c8abc (patch)
tree7fc6cd14c8e1297bd29261904814dd5ddcf88f57
parent4aed366334c4ca2651eef87734f1c4d1d41a1ba2 (diff)
downloadscummvm-rg350-48011948d60f700676629e157de75475d52c8abc.tar.gz
scummvm-rg350-48011948d60f700676629e157de75475d52c8abc.tar.bz2
scummvm-rg350-48011948d60f700676629e157de75475d52c8abc.zip
ILLUSIONS: BBDOU: Implement food/cafeteria minigame
-rw-r--r--engines/illusions/bbdou/bbdou_foodctl.cpp149
-rw-r--r--engines/illusions/bbdou/bbdou_foodctl.h71
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.cpp59
-rw-r--r--engines/illusions/bbdou/bbdou_specialcode.h5
-rw-r--r--engines/illusions/bbdou/scriptopcodes_bbdou.cpp3
-rw-r--r--engines/illusions/module.mk1
6 files changed, 285 insertions, 3 deletions
diff --git a/engines/illusions/bbdou/bbdou_foodctl.cpp b/engines/illusions/bbdou/bbdou_foodctl.cpp
new file mode 100644
index 0000000000..89c22d385c
--- /dev/null
+++ b/engines/illusions/bbdou/bbdou_foodctl.cpp
@@ -0,0 +1,149 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "illusions/bbdou/illusions_bbdou.h"
+#include "illusions/bbdou/bbdou_foodctl.h"
+#include "illusions/actor.h"
+#include "illusions/dictionary.h"
+#include "illusions/textdrawer.h"
+#include "illusions/time.h"
+#include "illusions/resources/scriptresource.h"
+
+namespace Illusions {
+
+BbdouFoodCtl::BbdouFoodCtl(IllusionsEngine_BBDOU *vm)
+ : _vm(vm) {
+}
+
+BbdouFoodCtl::~BbdouFoodCtl() {
+}
+
+void BbdouFoodCtl::placeFood(uint totalRoundsCount, uint maxRequestedFoodCount) {
+ _totalRoundsCount = totalRoundsCount;
+ _maxRequestedFoodCount = maxRequestedFoodCount;
+ _requestedFoodCount = 0;
+ _requestedFoodIndex = 0;
+ placeActors();
+}
+
+void BbdouFoodCtl::addFood(uint32 propertyId) {
+ _foodPropertyIds[_requestedFoodCount++] = propertyId;
+}
+
+void BbdouFoodCtl::requestFirstFood() {
+ _requestedFoodIndex = 1;
+ _vm->_scriptResource->_properties.set(_foodPropertyIds[0], true);
+}
+
+void BbdouFoodCtl::requestNextFood() {
+ uint32 propertyId = _foodPropertyIds[_requestedFoodIndex++];
+ _vm->_scriptResource->_properties.set(propertyId, true);
+}
+
+void BbdouFoodCtl::nextRound() {
+ --_totalRoundsCount;
+}
+
+bool BbdouFoodCtl::hasReachedRequestedFoodCount() {
+ return _requestedFoodIndex > _requestedFoodCount;
+}
+
+bool BbdouFoodCtl::hasRoundFinished() {
+ return _totalRoundsCount == 0 || _requestedFoodCount > _maxRequestedFoodCount;
+}
+
+void BbdouFoodCtl::serveFood() {
+ uint32 foodSequenceId = getFoodSequenceId();
+ uint32 studentObjectId = getCurrentStudentObjectId();
+ uint32 foodObjectId = _foodItems[_servedFoodCount++].objectId;
+ Control *foodControl = _vm->_dict->getObjectControl(foodObjectId);
+ foodControl->startSequenceActor(foodSequenceId, 2, 0);
+ foodControl->linkToObject(studentObjectId, _servedFoodCount);
+}
+
+void BbdouFoodCtl::resetFood() {
+ for (uint i = 0; i < _servedFoodCount; ++i) {
+ Control *control = _vm->_dict->getObjectControl(_foodItems[i].objectId);
+ control->unlinkObject();
+ _foodItems[i].value = 0;
+ }
+ _servedFoodCount = 0;
+ resetFoodControls();
+}
+
+void BbdouFoodCtl::placeActors() {
+ static const uint32 kFoodSequenceIds[] = {
+ 0x00060932, 0x00060933, 0x00060934,
+ 0x00060935, 0x00060936, 0x00060937
+ };
+ for (uint i = 0; i < kFoodCount; ++i) {
+ uint32 objectId = _vm->_controls->newTempObjectId();
+ _vm->_controls->placeActor(0x00050119, Common::Point(0, 0), 0x00060931, objectId, 0);
+ Control *control = _vm->_dict->getObjectControl(objectId);
+ control->deactivateObject();
+ control->setPriority(i + 10);
+ control->startSequenceActor(kFoodSequenceIds[(i + 1) % 6], 2, 0);
+ _foodItems[i].objectId = objectId;
+ _foodItems[i].value = 0;
+ }
+ _servedFoodCount = 0;
+ resetFoodControls();
+}
+
+void BbdouFoodCtl::resetFoodControls() {
+ Common::Point pos(-100, 32);
+ for (uint i = 0; i < kFoodCount; ++i) {
+ Control *control = _vm->_dict->getObjectControl(_foodItems[i].objectId);
+ control->setActorPosition(pos);
+ pos.y += 20;
+ }
+}
+
+uint32 BbdouFoodCtl::getFoodSequenceId() {
+ if (_vm->_scriptResource->_properties.get(0x000E014A))
+ return 0x60932;
+ if (_vm->_scriptResource->_properties.get(0x000E014B))
+ return 0x60933;
+ if (_vm->_scriptResource->_properties.get(0x000E014C))
+ return 0x60934;
+ if (_vm->_scriptResource->_properties.get(0x000E014D))
+ return 0x60935;
+ if (_vm->_scriptResource->_properties.get(0x000E014E))
+ return 0x60936;
+ if (_vm->_scriptResource->_properties.get(0x000E014F))
+ return 0x60937;
+ return 0;
+}
+
+uint32 BbdouFoodCtl::getCurrentStudentObjectId() {
+ if (_vm->_scriptResource->_properties.get(0x000E0146))
+ return 0x40077;
+ if (_vm->_scriptResource->_properties.get(0x000E0147))
+ return 0x40255;
+ if (_vm->_scriptResource->_properties.get(0x000E0148))
+ return 0x40256;
+ if (_vm->_scriptResource->_properties.get(0x000E0149))
+ return 0x40257;
+ return 0;
+}
+
+} // End of namespace Illusions
diff --git a/engines/illusions/bbdou/bbdou_foodctl.h b/engines/illusions/bbdou/bbdou_foodctl.h
new file mode 100644
index 0000000000..5a3177765e
--- /dev/null
+++ b/engines/illusions/bbdou/bbdou_foodctl.h
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ILLUSIONS_BBDOU_BBDOU_FOODCTL_H
+#define ILLUSIONS_BBDOU_BBDOU_FOODCTL_H
+
+#include "illusions/specialcode.h"
+#include "illusions/thread.h"
+
+namespace Illusions {
+
+class IllusionsEngine_BBDOU;
+
+// TODO Merge counts?
+const uint kFoodMaxPropertyIdsCount = 15;
+const uint kFoodCount = 16;
+
+struct FoodItem {
+ uint32 objectId;
+ int value;
+};
+
+class BbdouFoodCtl {
+public:
+ BbdouFoodCtl(IllusionsEngine_BBDOU *vm);
+ ~BbdouFoodCtl();
+ void placeFood(uint totalRoundsCount, uint maxRequestedFoodCount);
+ void addFood(uint32 propertyId);
+ void requestFirstFood();
+ void requestNextFood();
+ void nextRound();
+ bool hasReachedRequestedFoodCount();
+ bool hasRoundFinished();
+ void serveFood();
+ void resetFood();
+protected:
+ IllusionsEngine_BBDOU *_vm;
+ uint _totalRoundsCount, _maxRequestedFoodCount;
+ uint32 _foodPropertyIds[kFoodMaxPropertyIdsCount];
+ uint _requestedFoodCount;
+ uint _requestedFoodIndex;
+ FoodItem _foodItems[kFoodCount];
+ uint _servedFoodCount;
+ void placeActors();
+ void resetFoodControls();
+ uint32 getFoodSequenceId();
+ uint32 getCurrentStudentObjectId();
+};
+
+} // End of namespace Illusions
+
+#endif // ILLUSIONS_BBDOU_BBDOU_FOODCTL_H
diff --git a/engines/illusions/bbdou/bbdou_specialcode.cpp b/engines/illusions/bbdou/bbdou_specialcode.cpp
index 8bc09fff01..8839e2f8dd 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.cpp
+++ b/engines/illusions/bbdou/bbdou_specialcode.cpp
@@ -26,6 +26,7 @@
#include "illusions/bbdou/bbdou_inventory.h"
#include "illusions/bbdou/bbdou_credits.h"
#include "illusions/bbdou/bbdou_cursor.h"
+#include "illusions/bbdou/bbdou_foodctl.h"
#include "illusions/actor.h"
#include "illusions/camera.h"
#include "illusions/dictionary.h"
@@ -112,9 +113,11 @@ BbdouSpecialCode::BbdouSpecialCode(IllusionsEngine_BBDOU *vm)
_bubble = new BbdouBubble(_vm, this);
_cursor = new BbdouCursor(_vm, this);
_inventory = new BbdouInventory(_vm, this);
+ _foodCtl = new BbdouFoodCtl(_vm);
}
BbdouSpecialCode::~BbdouSpecialCode() {
+ delete _foodCtl;
delete _inventory;
delete _cursor;
delete _bubble;
@@ -148,6 +151,8 @@ void BbdouSpecialCode::init() {
SPECIAL(0x00160027, spcInitConversation);
SPECIAL(0x00160030, spcResetCursor);
SPECIAL(0x00160032, spcSetCursorField90);
+ SPECIAL(0x00160034, spcFoodCtl);
+ SPECIAL(0x00160035, spcTestFoodCtl);
SPECIAL(0x00160036, spcInitMenu);
SPECIAL(0x00160037, spcIsCursorHoldingObjectId);
SPECIAL(0x00160038, spcInitRadarMicrophone);
@@ -309,6 +314,56 @@ void BbdouSpecialCode::spcSetCursorField90(OpCall &opCall) {
_vm->notifyThreadId(opCall._threadId);
}
+void BbdouSpecialCode::spcFoodCtl(OpCall &opCall) {
+ ARG_UINT32(cmd);
+ switch (cmd) {
+ case 1:
+ {
+ ARG_UINT32(minCount);
+ ARG_UINT32(maxCount);
+ _foodCtl->placeFood(minCount, maxCount);
+ }
+ break;
+ case 2:
+ {
+ ARG_UINT32(propertyId);
+ _foodCtl->addFood(propertyId);
+ }
+ break;
+ case 3:
+ _foodCtl->requestFirstFood();
+ break;
+ case 4:
+ _foodCtl->requestNextFood();
+ break;
+ case 5:
+ _foodCtl->serveFood();
+ break;
+ case 6:
+ _foodCtl->resetFood();
+ break;
+ case 8:
+ _foodCtl->nextRound();
+ break;
+ default:
+ break;
+ }
+}
+
+void BbdouSpecialCode::spcTestFoodCtl(OpCall &opCall) {
+ ARG_UINT32(cmd);
+ switch (cmd) {
+ case 7:
+ _vm->_stack->push(_foodCtl->hasReachedRequestedFoodCount() ? 1 : 0);
+ break;
+ case 9:
+ _vm->_stack->push(_foodCtl->hasRoundFinished() ? 1 : 0);
+ break;
+ default:
+ break;
+ }
+}
+
void BbdouSpecialCode::spcInitMenu(OpCall &opCall) {
// Called but not used in the reimplementation
}
@@ -705,7 +760,7 @@ void BbdouSpecialCode::cursorCrosshairControlRoutine(Control *cursorControl, uin
if (cursorData._flags & 1)
foundOverlapped = false;
- else {
+ else {
foundOverlapped = _vm->_controls->getOverlappedObjectAccurate(cursorControl, cursorPos,
&overlappedControl, cursorData._item10._field58);
}
@@ -818,7 +873,7 @@ void BbdouSpecialCode::cursorCrosshairControlRoutine(Control *cursorControl, uin
}
} else if (_vm->_input->pollEvent(kEventLeftClick)) {
- uint index = (uint)_vm->getRandom(2);
+ uint index = (uint)_vm->getRandom(2);
const ShooterAnim &anim = kShooterAnims[index];
uint32 objectId = anim.objectId;
int gridX = _shooterStatus[index].gridX;
diff --git a/engines/illusions/bbdou/bbdou_specialcode.h b/engines/illusions/bbdou/bbdou_specialcode.h
index 973d4b40f8..f48330784e 100644
--- a/engines/illusions/bbdou/bbdou_specialcode.h
+++ b/engines/illusions/bbdou/bbdou_specialcode.h
@@ -33,6 +33,7 @@ class IllusionsEngine_BBDOU;
class BbdouBubble;
class BbdouCredits;
class BbdouCursor;
+class BbdouFoodCtl;
class BbdouInventory;
struct CursorData;
struct Item10;
@@ -113,6 +114,8 @@ public:
ShooterStatus _shooterStatus[2];
uint _shooterObjectIdIndex;
+ BbdouFoodCtl *_foodCtl;
+
// Special code interface functions
void spcInitCursor(OpCall &opCall);
void spcEnableCursor(OpCall &opCall);
@@ -136,6 +139,8 @@ public:
void spcInitConversation(OpCall &opCall);
void spcResetCursor(OpCall &opCall);
void spcSetCursorField90(OpCall &opCall);
+ void spcFoodCtl(OpCall &opCall);
+ void spcTestFoodCtl(OpCall &opCall);
void spcInitMenu(OpCall &opCall);
void spcIsCursorHoldingObjectId(OpCall &opCall);
void spcInitRadarMicrophone(OpCall &opCall);
diff --git a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
index d887edddb5..e023fb3eee 100644
--- a/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
+++ b/engines/illusions/bbdou/scriptopcodes_bbdou.cpp
@@ -288,7 +288,7 @@ void ScriptOpcodes_BBDOU::opUnloadActiveScenes(ScriptThread *scriptThread, OpCal
//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 = 0x00010016, dthreadId = 0x0002001B;//Dorms ext
//uint32 dsceneId = 0x00010017, dthreadId = 0x0002001C;//Dorms int
//uint32 dsceneId = 0x0001000D, dthreadId = 0x00020012;//Food minigame
//uint32 dsceneId = 0x00010067, dthreadId = 0x0002022A;
@@ -297,6 +297,7 @@ uint32 dsceneId = 0x00010016, dthreadId = 0x0002001B;//Dorms ext
//uint32 dsceneId = 0x0001001A, dthreadId = 0x0002001F;
//uint32 dsceneId = 0x00010047, dthreadId = 0x0002005F;
//uint32 dsceneId = 0x0001007D, dthreadId = 0x000203B9;
+uint32 dsceneId = 0x0001000D, dthreadId = 0x00020012;
void ScriptOpcodes_BBDOU::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
diff --git a/engines/illusions/module.mk b/engines/illusions/module.mk
index 7cbbd7f956..82116960ca 100644
--- a/engines/illusions/module.mk
+++ b/engines/illusions/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS := \
bbdou/bbdou_cursor.o \
bbdou/bbdou_credits.o \
bbdou/bbdou_credits_staticdata.o \
+ bbdou/bbdou_foodctl.o \
bbdou/bbdou_inventory.o \
bbdou/bbdou_specialcode.o \
bbdou/bbdou_triggerfunctions.o \