aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorJoseph-Eugene Winzer2017-07-11 05:33:46 +0200
committerThierry Crozat2018-01-22 23:54:26 +0000
commit30308fbe8d45de40331b10bd7ed6e62c6bff0a4c (patch)
tree129e66e105c49cfec87f261a3000198bd135868b /engines
parent87a0dd970af238e6ec7033288c0a67640a717d6e (diff)
downloadscummvm-rg350-30308fbe8d45de40331b10bd7ed6e62c6bff0a4c.tar.gz
scummvm-rg350-30308fbe8d45de40331b10bd7ed6e62c6bff0a4c.tar.bz2
scummvm-rg350-30308fbe8d45de40331b10bd7ed6e62c6bff0a4c.zip
SUPERNOVA: Implements GUI routines and refactors code
Of course the short description does not adequately describe the changes made with this commit and I assume this won't be the last big restructuring unfortunately. Focus of this commit was to implement/fix the code so the main user interface can be rendered. Bugs in the core routines for rendering Messages and Images were fixed as well.
Diffstat (limited to 'engines')
-rw-r--r--engines/supernova/module.mk3
-rw-r--r--engines/supernova/msn_def.h37
-rw-r--r--engines/supernova/rooms.cpp71
-rw-r--r--engines/supernova/rooms.h8
-rw-r--r--engines/supernova/state.cpp921
-rw-r--r--engines/supernova/state.h153
-rw-r--r--engines/supernova/supernova.cpp767
-rw-r--r--engines/supernova/supernova.h76
8 files changed, 1192 insertions, 844 deletions
diff --git a/engines/supernova/module.mk b/engines/supernova/module.mk
index 7519a3da78..9baf196c7c 100644
--- a/engines/supernova/module.mk
+++ b/engines/supernova/module.mk
@@ -5,7 +5,8 @@ MODULE_OBJS := \
detection.o \
graphics.o \
supernova.o \
- rooms.o
+ rooms.o \
+ state.o
MODULE_DIRS += \
engines/supernova
diff --git a/engines/supernova/msn_def.h b/engines/supernova/msn_def.h
index 8e524043bb..e7a76c84a6 100644
--- a/engines/supernova/msn_def.h
+++ b/engines/supernova/msn_def.h
@@ -422,7 +422,7 @@ enum ObjectID {
TICKETS
};
-static const char *const guiCommands[] = {
+static const char *const guiCommand_DE[] = {
"Gehe",
"Schau",
"Nimm",
@@ -435,6 +435,11 @@ static const char *const guiCommands[] = {
"Gib"
};
+static const char *guiStatusCommand_DE[10] =
+{"Gehe zu ","Schau ","Nimm ","\231ffne ","Schlie\341e ","Dr\201cke ","Ziehe ","Benutze ","Rede mit ","Gib "};
+static const char *guiStatusCommand_EN[10] =
+{"Go to ", "Look at ", "Take ", "Open ", "Close ", "Press ", "Pull ", "Use ", "Talk to ", "Give "};
+
ObjectType operator|(ObjectType a, ObjectType b);
ObjectType operator&(ObjectType a, ObjectType b);
ObjectType operator^(ObjectType a, ObjectType b);
@@ -501,36 +506,6 @@ struct Object {
byte _direction;
};
-struct GameState {
- int32 time;
- int32 timeSleep;
- int32 timeStarting;
- int32 timeAlarm;
- int32 timeAlarmSystem;
- int32 eventTime;
- int32 shipEnergy;
- int32 landingModuleEnergy;
- uint16 greatF;
- int16 timeRobot;
- int16 money;
- char coins;
- char shoes;
- char nameSeen;
- char destination;
- char benOverlay;
- char language;
- bool corridorSearch;
- bool alarmOn;
- bool terminalStripConnected;
- bool terminalStripWire;
- bool cableConnected;
- bool powerOff;
- bool cockpitSeen;
- bool airlockSeen;
- bool holdSeen;
- bool dream;
-};
-
}
#endif // MSN_DEF_H
diff --git a/engines/supernova/rooms.cpp b/engines/supernova/rooms.cpp
index cd7a88bd9f..757fe6c8d6 100644
--- a/engines/supernova/rooms.cpp
+++ b/engines/supernova/rooms.cpp
@@ -23,9 +23,18 @@
#include "common/system.h"
#include "supernova/supernova.h"
+#include "supernova/state.h"
namespace Supernova {
+void StartingItems::onEntrance() {
+ for (int i = 0; i < 3; ++i)
+ _gm->_inventory.add(*getObject(i));
+
+ this->setRoomSeen(true);
+ _gm->changeRoom(CABIN_R3);
+}
+
bool ShipCorridor::interact(Action verb, Object &obj1, Object &obj2) {
if ((verb == ACTION_PRESS) && (obj1._id == BUTTON)) {
if (_objectState[6].hasProperty(OPENED)) {
@@ -165,7 +174,7 @@ bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
_shown[kMaxSection - 1] = false;
} else if (((verb == ACTION_WALK) || (verb == ACTION_USE)) &&
((obj1._id == CABINS) || (obj1._id == CABIN))) {
- r = &_gm->_rooms[AIRLOCK];
+ r = _gm->_rooms[AIRLOCK];
if (!(obj1._id == CABIN) || !(_shown[5])) {
_vm->renderMessage("Es würde wenig bringen,|sich in eine Schlafkammer zu legen,|die nicht eingeschaltet ist.");
} else if (r->getObject(5)->hasProperty(WORN)) {
@@ -174,7 +183,7 @@ bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
_vm->paletteFadeOut();
_vm->renderImage(_gm->_currentRoom->getFileNumber(), _gm->invertSection(5));
_vm->renderImage(_gm->_currentRoom->getFileNumber(), _gm->invertSection(4));
- r = &_gm->_rooms[GENERATOR];
+ r = _gm->_rooms[GENERATOR];
if (r->isSectionVisible(9)) {
energy = &_gm->_state.landingModuleEnergy;
} else {
@@ -186,7 +195,7 @@ bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
if (_gm->_state.timeSleep >= *energy) {
_gm->_state.timeSleep = *energy;
if (r->isSectionVisible(9)) {
- r = &_gm->_rooms[LANDINGMODULE]; // Monitors off
+ r = _gm->_rooms[LANDINGMODULE]; // Monitors off
r->setSectionVisible(2, false);
r->setSectionVisible(7, false);
r->setSectionVisible(8, false);
@@ -196,18 +205,18 @@ bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
}
if (_gm->_state.timeSleep == _gm->_state.time) {
_vm->renderImage(_gm->_currentRoom->getFileNumber(), 3); // landed
- r = &_gm->_rooms[COCKPIT];
+ r = _gm->_rooms[COCKPIT];
r->setSectionVisible(23, true);
- r = &_gm->_rooms[CABIN_R2];
+ r = _gm->_rooms[CABIN_R2];
r->setSectionVisible(5, false);
r->setSectionVisible(6, true);
r->getObject(2)->_click = 10;
- r = &_gm->_rooms[HOLD];
+ r = _gm->_rooms[HOLD];
r->setSectionVisible(0, false);
r->setSectionVisible(1, true);
r->getObject(1)->_click = 255;
r->getObject(3)->_click = 255;
- r = &_gm->_rooms[GENERATOR];
+ r = _gm->_rooms[GENERATOR];
r->setSectionVisible(6, false);
r->setSectionVisible(7, true);
r->getObject(1)->_click = 14;
@@ -226,7 +235,7 @@ bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
_gm->_state.alarmOn = (_gm->_state.timeAlarmSystem > _vm->getDOSTicks());
if (!*energy) {
_gm->turnOff();
- r = &_gm->_rooms[GENERATOR];
+ r = _gm->_rooms[GENERATOR];
r->setSectionVisible(4, r->isSectionVisible(2));
}
if (_gm->_state.time == 0) {
@@ -287,7 +296,7 @@ void ShipSleepCabin::animation() {
}
}
void ShipSleepCabin::onEntrance() {
- if (_gm->_state.dream && (_gm->_rooms[CAVE].getObject(1)->_exitRoom == MEETUP3)) {
+ if (_gm->_state.dream && (_gm->_rooms[CAVE]->getObject(1)->_exitRoom == MEETUP3)) {
_vm->renderMessage("Du wachst mit brummendem Schädel auf|und merkst, daß du nur geträumt hast.");
_gm->mouseWait(_gm->_timer1);
_vm->removeMessage();
@@ -495,7 +504,7 @@ bool ShipCabinL3::interact(Action verb, Object &obj1, Object &obj2) {
} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, WIRE2))
_vm->renderMessage("Schneid doch besser ein|l„ngeres Stck Kabel ab!");
else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, WIRE)) {
- r = &_gm->_rooms[AIRLOCK];
+ r = _gm->_rooms[AIRLOCK];
if (!this->isSectionVisible(10) && !r->getObject(5)->hasProperty(WORN)) {
_vm->renderImage(this->getFileNumber(), 25);
_gm->shock();
@@ -554,10 +563,10 @@ bool ShipCabinR3::interact(Action verb, Object &obj1, Object &obj2) {
}
else if ((verb == ACTION_TAKE) && (obj1._id == DISCMAN) &&
- !_gm->_rooms[0].getObject(3)->hasProperty(CARRIED)) {
+ !_gm->_rooms[0]->getObject(3)->hasProperty(CARRIED)) {
this->getObject(10)->_click = 34; // Locker empty
obj1._click = 255;
- _gm->takeObject(*_gm->_rooms[0].getObject(3));
+ _gm->takeObject(*_gm->_rooms[0]->getObject(3));
_vm->renderImage(this->getFileNumber(), 16);
} else if ((verb == ACTION_TAKE) && (obj1._id == ROPE) &&
obj1.hasProperty(CARRIED)) {
@@ -657,7 +666,7 @@ bool ShipAirlock::interact(Action verb, Object &obj1, Object &obj2) {
this->setSectionVisible(5, false);
_gm->wait2(2);
_vm->renderImage(this->getFileNumber(), _gm->invertSection(4));
- r = &_gm->_rooms[AIRLOCK];
+ r = _gm->_rooms[AIRLOCK];
if (!r->getObject(4)->hasProperty(WORN) ||
!r->getObject(5)->hasProperty(WORN) ||
!r->getObject(6)->hasProperty(WORN)) {
@@ -715,12 +724,12 @@ bool ShipHold::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(this->getFileNumber(), 5);
this->getObject(0)->_name = "langes Kabel mit Stecker";
this->getObject(0)->_click = 10;
- r = &_gm->_rooms[CABIN_L2];
+ r = _gm->_rooms[CABIN_L2];
_gm->_inventory.remove(*this->getObject(9));
}
} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, HOLD_WIRE, GENERATOR_TOP)) {
if (this->isSectionVisible(5)) {
- r = &_gm->_rooms[GENERATOR];
+ r = _gm->_rooms[GENERATOR];
r->getObject(0)->_click = 15;
r->getObject(1)->_click = 13;
r->setSectionVisible(6, false);
@@ -743,7 +752,7 @@ void ShipHold::onEntrance() {
if (!this->hasSeen())
_vm->renderMessage("Was ist denn das fr ein Chaos?|Und auáerdem fehlt das Notraumschiff!|Jetzt wird mir einiges klar.|Die anderen sind geflchtet,|und ich habe es verpennt.");
this->setRoomSeen(true);
- _gm->_rooms[COCKPIT].setRoomSeen(true);
+ _gm->_rooms[COCKPIT]->setRoomSeen(true);
}
bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
@@ -752,7 +761,7 @@ bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderMessage(obj1._description);
else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, PEN, LANDINGMOD_BUTTON)) {
if (_gm->_state.landingModuleEnergy) {
- r = &_gm->_rooms[GENERATOR];
+ r = _gm->_rooms[GENERATOR];
if (this->isSectionVisible(7)) {
_vm->renderImage(this->getFileNumber(), _gm->invertSection(9));
_vm->renderImage(this->getFileNumber(), _gm->invertSection(2));
@@ -770,7 +779,7 @@ bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
// load("MSN_DATA.025");
_gm->roomBrightness();
_vm->paletteBrightness();
- r = &_gm->_rooms[SLEEP];
+ r = _gm->_rooms[SLEEP];
r->setSectionVisible(1, false);
r->setSectionVisible(2, false);
_gm->wait2(2);
@@ -791,7 +800,7 @@ bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
else if ((verb == ACTION_USE) && (obj1._id == KEYBOARD))
_vm->renderMessage("Laá lieber die Finger davon!");
else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, WIRE, LANDINGMOD_SOCKET)) {
- r = &_gm->_rooms[CABIN_L3];
+ r = _gm->_rooms[CABIN_L3];
_gm->_inventory.remove(*r->getObject(8));
this->getObject(4)->_name = r->getObject(8)->_name;
_vm->renderImage(this->getFileNumber(), 4);
@@ -808,7 +817,7 @@ bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LANDINGMOD_WIRE, TERMINALSTRIP)) {
_vm->renderImage(this->getFileNumber(), 11);
this->getObject(4)->_name = "Leitung mit Lsterklemme";
- r = &_gm->_rooms[HOLD];
+ r = _gm->_rooms[HOLD];
_gm->_inventory.remove(*r->getObject(2));
_gm->_state.terminalStripConnected = true;
_gm->_state.terminalStripWire = true;
@@ -819,19 +828,19 @@ bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(this->getFileNumber(), 5);
this->getObject(4)->_name = "langes Kabel mit Stecker";
this->getObject(4)->_click = 6;
- r = &_gm->_rooms[CABIN_L2];
+ r = _gm->_rooms[CABIN_L2];
_gm->_inventory.remove(*r->getObject(9));
}
} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LANDINGMOD_WIRE, LANDINGMOD_HATCH)) {
if (this->getObject(5)->hasProperty(OPENED)) {
- r = &_gm->_rooms[HOLD];
+ r = _gm->_rooms[HOLD];
if (this->isSectionVisible(5)) {
- _gm->_rooms[HOLD].setSectionVisible(5, false);
+ _gm->_rooms[HOLD]->setSectionVisible(5, false);
r->getObject(0)->_click = 10;
} else
r->getObject(0)->_click = 9;
- _gm->_rooms[HOLD].setSectionVisible(4, false);
+ _gm->_rooms[HOLD]->setSectionVisible(4, false);
r->getObject(0)->_name = this->getObject(4)->_name;
_vm->renderImage(this->getFileNumber(), _gm->invertSection(5));
_vm->renderImage(this->getFileNumber(), _gm->invertSection(4));
@@ -866,7 +875,7 @@ bool ShipGenerator::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(this->getFileNumber(), 10);
if (this->isSectionVisible(13))
_vm->renderImage(this->getFileNumber(), 13);
- _gm->_rooms[HOLD].setSectionVisible(3, true);
+ _gm->_rooms[HOLD]->setSectionVisible(3, true);
obj1.setProperty(OPENED);
obj1._click = 2;
_vm->playSound(kAudioDoorOpen);
@@ -881,7 +890,7 @@ bool ShipGenerator::interact(Action verb, Object &obj1, Object &obj2) {
this->setSectionVisible(10, false);
if (this->isSectionVisible(13))
_vm->renderImage(this->getFileNumber(), 13);
- _gm->_rooms[HOLD].setSectionVisible(3, false);
+ _gm->_rooms[HOLD]->setSectionVisible(3, false);
obj1.disableProperty(OPENED);
obj1._click = 1;
_vm->playSound(kAudioDoorClose);
@@ -944,12 +953,12 @@ bool ShipGenerator::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(this->getFileNumber(), 3);
_vm->renderImage(this->getFileNumber(), 9);
this->getObject(0)->_click = 16;
- r = &_gm->_rooms[LANDINGMODULE];
+ r = _gm->_rooms[LANDINGMODULE];
if (_gm->_state.landingModuleEnergy && r->isSectionVisible(7))
_gm->turnOn();
else
_vm->renderImage(this->getFileNumber(), 4);
- _gm->_rooms[HOLD].setSectionVisible(7, true);
+ _gm->_rooms[HOLD]->setSectionVisible(7, true);
_gm->great(3);
} else if ((verb == ACTION_PULL) && (obj1._id == GENERATOR_WIRE) &&
(obj1._click == 16)) {
@@ -960,7 +969,7 @@ bool ShipGenerator::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderImage(this->getFileNumber(), 8);
obj1._click = 15;
_gm->turnOff();
- _gm->_rooms[HOLD].setSectionVisible(7, false);
+ _gm->_rooms[HOLD]->setSectionVisible(7, false);
} else if ((verb == ACTION_USE) &&
(Object::combine(obj1, obj2, WIRE, CLIP) ||
Object::combine(obj1, obj2, SPOOL, CLIP)) &&
@@ -973,7 +982,7 @@ bool ShipGenerator::interact(Action verb, Object &obj1, Object &obj2) {
_vm->renderMessage("Es zeigt volle Spannung an.");
} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LADDER, ROPE)) {
_vm->renderImage(this->getFileNumber(), 13);
- r = &_gm->_rooms[CABIN_R3];
+ r = _gm->_rooms[CABIN_R3];
_gm->_inventory.remove(*r->getObject(9));
this->getObject(3)->_click = 18;
} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, OUTERHATCH, GENERATOR_ROPE)) {
@@ -988,7 +997,7 @@ bool ShipGenerator::interact(Action verb, Object &obj1, Object &obj2) {
} else {
_vm->renderImage(this->getFileNumber(), 12);
}
- r = &_gm->_rooms[OUTSIDE];
+ r = _gm->_rooms[OUTSIDE];
r->setSectionVisible(1, true);
r->getObject(1)->_click = 1;
this->getObject(3)->_click = 17;
diff --git a/engines/supernova/rooms.h b/engines/supernova/rooms.h
index e78f446987..d3d850a83d 100644
--- a/engines/supernova/rooms.h
+++ b/engines/supernova/rooms.h
@@ -36,6 +36,8 @@ class Room {
public:
Room() {
_seen = false;
+ for (int i = 0; i < kMaxSection; ++i)
+ _shown[i] = false;
}
bool hasSeen() {
@@ -101,6 +103,8 @@ public:
Object("Discman", "Es ist eine \"Mad Monkeys\"-CD darin.", DISCMAN,
TAKE | COMBINABLE, 255, 255, 0, NULLROOM, 0);
}
+
+ virtual void onEntrance();
};
// Spaceship
@@ -415,7 +419,7 @@ public:
_objectState[20] = Object("Schrank",Object::defaultDescription,NULLOBJECT,OPEN | CLOSED,1,1,0);
_objectState[21] = Object("Fach",Object::defaultDescription,NULLOBJECT,OPEN | CLOSED,2,2,0);
_objectState[22] = Object("Steckdose",Object::defaultDescription,SOCKET,COMBINABLE,4,4,0);
- _objectState[23] = Object("Toilette",Object::defaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,2);
+ _objectState[23] = Object("Toilette",Object::defaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,22);
}
virtual bool interact(Action verb, Object &obj1, Object &obj2);
@@ -432,7 +436,7 @@ public:
_objectState[0] = Object("Klo","Ein Klo mit Saugmechanismus.",TOILET,NULLTYPE,0,0,0);
_objectState[1] = Object("Dusche",Object::defaultDescription,SHOWER,NULLTYPE,1,1,0);
- _objectState[2] = Object("Ausgang",Object::defaultDescription,BATHROOM_EXIT,EXIT,255,255,0,NULLROOM,2);
+ _objectState[2] = Object("Ausgang",Object::defaultDescription,BATHROOM_EXIT,EXIT,255,255,0,CABIN_R3,2);
}
};
diff --git a/engines/supernova/state.cpp b/engines/supernova/state.cpp
new file mode 100644
index 0000000000..1899daffb4
--- /dev/null
+++ b/engines/supernova/state.cpp
@@ -0,0 +1,921 @@
+
+#include "supernova/supernova.h"
+#include "supernova/state.h"
+
+namespace Supernova {
+
+Inventory::Inventory()
+ : _numObjects(0)
+{}
+
+// TODO: Update Inventory surface for scrolling
+void Inventory::add(Object &obj) {
+ if (_numObjects < kMaxCarry)
+ _inventory[_numObjects++] = &obj;
+
+// if (inventory_amount>8) inventory_scroll = ((inventory_amount+1)/2)*2-8;
+// show_inventory();
+}
+
+// TODO: Update Inventory surface for scrolling
+void Inventory::remove(Object &obj) {
+ for (uint i = 0; i < _numObjects; ++i) {
+ if (_inventory[i] == &obj) {
+ --_numObjects;
+ while (i < _numObjects) {
+ _inventory[i] = _inventory[i + 1];
+ ++i;
+ }
+ obj.disableProperty(CARRIED);
+ }
+ }
+}
+
+Object *Inventory::get(uint index) const {
+ if (index < _numObjects)
+ return _inventory[index];
+
+ return NULL;
+}
+
+Object *Inventory::get(ObjectID id) const {
+ for (uint i = 0; i < _numObjects; ++i) {
+ if (_inventory[i]->_id == id)
+ return _inventory[i];
+ }
+
+ return NULL;
+}
+
+
+static const char *timeToString(int t) {
+ // TODO: Does ScummVM emulate PIT timings for DOS?
+
+ static char s[9];
+ strcpy(s," 0:00:00");
+ s[7] = t % 10 + '0';
+ t /= 10;
+ s[6] = t % 6 + '0';
+ t /= 6;
+ s[4] = t % 10 + '0';
+ t /= 10;
+ s[3] = t % 6 + '0';
+ t /= 6;
+ s[1] = t % 10 + '0';
+ t /= 10;
+ if (t)
+ s[0] = t+48;
+
+ return(s);
+}
+
+GameManager::GameManager(SupernovaEngine *vm) {
+ _rooms[INTRO] = new StartingItems(vm, this);
+ _rooms[CORRIDOR] = new ShipCorridor(vm, this);
+ _rooms[HALL] = new ShipHall(vm, this);
+ _rooms[SLEEP] = new ShipSleepCabin(vm, this);
+ _rooms[COCKPIT] = new ShipCockpit(vm, this);
+ _rooms[AIRLOCK] = new ShipAirlock(vm, this);
+ _rooms[HOLD] = new ShipHold(vm, this);
+ _rooms[LANDINGMODULE] = new ShipLandingModule(vm, this);
+ _rooms[GENERATOR] = new ShipGenerator(vm, this);
+ _rooms[OUTSIDE] = new ShipOuterSpace(vm, this);
+ _rooms[CABIN_R1] = new ShipCabinR1(vm, this);
+ _rooms[CABIN_R2] = new ShipCabinR2(vm, this);
+ _rooms[CABIN_R3] = new ShipCabinR3(vm, this);
+ _rooms[CABIN_L1] = new ShipCabinL1(vm, this);
+ _rooms[CABIN_L2] = new ShipCabinL2(vm, this);
+ _rooms[CABIN_L3] = new ShipCabinL3(vm, this);
+ _rooms[BATHROOM] = new ShipCabinBathroom(vm, this);
+
+// _rooms[ROCKS]
+// _rooms[CAVE]
+// _rooms[MEETUP]
+// _rooms[ENTRANCE]
+// _rooms[REST]
+// _rooms[ROGER]
+// _rooms[GLIDER]
+// _rooms[MEETUP2]
+// _rooms[MEETUP3]
+
+// _rooms[CELL]
+// _rooms[CORRIDOR1]
+// _rooms[CORRIDOR2]
+// _rooms[CORRIDOR3]
+// _rooms[CORRIDOR4]
+// _rooms[CORRIDOR5]
+// _rooms[CORRIDOR6]
+// _rooms[CORRIDOR7]
+// _rooms[CORRIDOR8]
+// _rooms[CORRIDOR9]
+// _rooms[BCORRIDOR]
+// _rooms[GUARD]
+// _rooms[GUARD3]
+// _rooms[OFFICE_L1]
+// _rooms[OFFICE_L2]
+// _rooms[OFFICE_R1]
+// _rooms[OFFICE_R2]
+// _rooms[OFFICE_L]
+// _rooms[ELEVATOR]
+// _rooms[STATION]
+// _rooms[SIGN]
+
+ _currentRoom = _rooms[INTRO];
+ _vm = vm;
+ _inputObject[0] = &_nullObjectInstance;
+ _inputObject[1] = &_nullObjectInstance;
+ _inputVerb = ACTION_WALK;
+ _inputVerb2 = false;
+ _inventoryScroll = 0;
+
+ initGui();
+}
+
+void GameManager::initGui() {
+ // TODO: Initialize GUI dimensions to eliminate the use of magic numbers
+ // especially in the input handling.
+ // Wrapping it in state machine would probably make a lot of it easier
+ // as the current state i.e. when selecting/combining objects would need
+ // to be queried when deciding what to do (flush inputs / render / ... )
+
+ int x = 0;
+ for (int i = 0; i < ARRAYSIZE(_guiCommandDimensions); ++i) {
+ int width;
+ if (i < 9)
+ width = _vm->characterWidth(guiCommand_DE[i]) + 2;
+ else
+ width = 320 - x;
+
+ _guiCommandDimensions[i] = Common::Rect(x, 150, x + width, 159);
+ x += width + 2;
+ }
+}
+
+void GameManager::processInput(Common::KeyState &state) {
+ switch (state.keycode) {
+ case Common::KEYCODE_F1:
+ // help
+ break;
+ case Common::KEYCODE_F2:
+ // show game doc
+ break;
+ case Common::KEYCODE_F3:
+ // show game info
+ break;
+ case Common::KEYCODE_F4:
+ // set text speed
+ break;
+ case Common::KEYCODE_F5:
+ // load/save
+ break;
+ case Common::KEYCODE_x:
+ if (state.flags & Common::KBD_ALT) {
+ // quit game
+ _vm->_gameRunning = false;
+ } else {
+ _key = state.ascii;
+ }
+ break;
+ default:
+ _key = state.ascii;
+ }
+}
+
+void GameManager::processInput(Common::EventType eventType, int x, int y) {
+ _mouseClickType = eventType;
+ _mouseX = x;
+ _mouseY = y;
+ _inputObject[0] = &_nullObjectInstance;
+ _inputObject[1] = &_nullObjectInstance;
+ _inputVerb = ACTION_WALK;
+ _inputVerb2 = false;
+ _mouseField = -1;
+ _objectNumber = 0;
+
+ if (_mouseClickType == Common::EVENT_LBUTTONUP) {
+ // STUB
+
+ } else if (_mouseClickType == Common::EVENT_RBUTTONUP) {
+ ObjectType type;
+ if (((_mouseField >= 0) && (_mouseField < 256)) ||
+ ((_mouseField >= 512) && (_mouseField < 768))) {
+ _inputObject[0] = _inputObject[_objectNumber];
+ _objectNumber = 0;
+ _inputVerb2 = false;
+ type = _inputObject[0]->_type;
+ if (type & OPEN) {
+ if (type & OPENED)
+ _inputVerb = ACTION_CLOSE;
+ else
+ _inputVerb = ACTION_OPEN;
+ } else if (type & PRESS) {
+ _inputVerb = ACTION_PRESS;
+ } else if (type & TALK) {
+ _inputVerb = ACTION_TALK;
+ } else {
+ _inputVerb = ACTION_LOOK;
+ }
+ }
+ } else if (_mouseClickType == Common::EVENT_MOUSEMOVE) {
+ int field;
+ int click;
+ field = -1;
+ /* command row? */
+ if ((y >= _guiCommandDimensions[0].top) && (y <= _guiCommandDimensions[0].bottom)) {
+ field = 9;
+ while (x < _guiCommandDimensions[field].left - 1)
+ field--;
+ field += 256;
+ }
+ /* exit box? */
+ else if ((x >= 283) && (x <= 317) && (y >= 163) && (y <= 197))
+ field = _exitList[(x - 283) / 7 + 5 * ((y - 163) / 7)];
+ /* inventory box */
+ else if ((y >= 161) && (x <= 270)) {
+ field = (x + 1) / 136 + ((y - 161) / 10) * 2;
+ if (field + _inventoryScroll < _inventory.getSize())
+ field += 512;
+ else
+ field = -1;
+ }
+ /* inventory arrows */
+ else if ((y >= 161) && (x >= 271) && (x < 279)) {
+ if (y > 180) field = 769;
+ else field = 768;
+ }
+ /* message window */
+// else if (_vm->_messageDisplayed && (x >= message_columns) && (x < message_columns + message_width) && (y >= message_rows) && (y < message_rows + message_height))
+ else if (_vm->_messageDisplayed)
+ field = -1;
+ /* normal item */
+ else {
+ for (int i = 0; (_currentRoom->getObject(i)->_name != NULL) && (field == -1); i++) {
+ click = _currentRoom->getObject(i)->_click;
+ if (click != 255) {
+ MSNImageDecoder::ClickField *clickField = _vm->_currentImage->_clickField;
+ do {
+ if ((x >= clickField[click].x1) && (x <= clickField[click].x2) &&
+ (y >= clickField[click].y1) && (y <= clickField[click].y2))
+ field = i;
+
+ click = clickField[click].next;
+ } while ((click != 0) && (field == -1));
+ }
+ }
+
+ if ((_objectNumber == 1) && (_currentRoom->getObject(field) == _inputObject[0]))
+ field = -1;
+ }
+ if (_mouseField != field) {
+ if (_mouseField >= 768) {
+ inventory_arrow(_mouseField - 768, 0);
+ } else if (_mouseField >= 512) {
+ inventory_object(_mouseField - 512, 0);
+ _inputObject[_objectNumber] = &_nullObjectInstance;
+ drawStatus();
+ } else if (_mouseField >= 256) {
+ drawCommandBox(_mouseField - 256, 0);
+ } else if (_mouseField != -1) {
+ _inputObject[_objectNumber] = &_nullObjectInstance;
+ drawStatus();
+ }
+ _mouseField = field;
+ if (_mouseField >= 768) {
+ inventory_arrow(_mouseField - 768, 1);
+ } else if (_mouseField >= 512) {
+ inventory_object(_mouseField - 512, 1);
+ _inputObject[_objectNumber] = _inventory.get(_mouseField - 512 + _inventoryScroll);
+ drawStatus();
+ } else if (_mouseField >= 256) {
+ drawCommandBox(_mouseField - 256, 1);
+ } else if (_mouseField != -1) {
+ _inputObject[_objectNumber] = _currentRoom->getObject(_mouseField);
+ drawStatus();
+ }
+ }
+ }
+}
+
+bool GameManager::isHelmetOff() {
+ Object *helmet = _inventory.get(HELMET);
+ if (helmet && helmet->hasProperty(WORN)) {
+ _vm->renderMessage("Irgendwie ist ein Raumhelm|beim Essen unpraktisch.");
+ return false;
+ }
+
+ return true;
+}
+
+void GameManager::great(uint number) {
+ if (number && (_state.greatF & (1 << number)))
+ return;
+
+ _vm->playSound(kAudioUndef7);
+ _state.greatF |= 1 << number;
+}
+
+bool GameManager::airless() {
+ return (
+ ((_currentRoom > _rooms[AIRLOCK]) && (_currentRoom < _rooms[CABIN_R1])) ||
+ ((_currentRoom > _rooms[BATHROOM])&& (_currentRoom < _rooms[ENTRANCE])) ||
+ ((_currentRoom == _rooms[AIRLOCK]) && (_currentRoom->getObject(1)->hasProperty(OPENED))) ||
+ (_currentRoom >= _rooms[MEETUP2])
+ );
+}
+
+void GameManager::turnOff() {
+ if (_state.powerOff)
+ return;
+
+ _state.powerOff = true;
+ roomBrightness();
+
+}
+void GameManager::turnOn() {
+ // STUB
+}
+
+void GameManager::takeObject(Object &obj) {
+ if (obj.hasProperty(CARRIED))
+ return;
+
+ if (obj._section != 0)
+ _vm->renderImage(_currentRoom->getFileNumber(), obj._section);
+ obj.setProperty(CARRIED);
+ obj._click = obj._click2 = 255;
+ _inventory.add(obj);
+}
+
+void GameManager::inventory_object(int num, bool brightness) {
+}
+
+void GameManager::drawCommandBox() {
+ for (int i = 0; i < 10; ++i)
+ drawCommandBox(i, 0);
+}
+
+void GameManager::drawCommandBox(int cmd, bool brightness) {
+ _vm->renderBox(_guiCommandDimensions[cmd].left,
+ _guiCommandDimensions[cmd].top,
+ _guiCommandDimensions[cmd].width(),
+ _guiCommandDimensions[cmd].height(),
+ (brightness) ? HGR_BEF_HELL:HGR_BEF);
+ _vm->renderText(guiCommand_DE[cmd],
+ _guiCommandDimensions[cmd].left + 1,
+ _guiCommandDimensions[cmd].top + 1,
+ (brightness) ? COL_BEF_HELL:COL_BEF);
+}
+
+void GameManager::inventory_arrow(int num, bool brightness) {
+ // STUB
+}
+
+void GameManager::drawInventory() {
+ // TODO: implement scrolling and moveover effects
+ int brightness = 0;
+ for (int i = 0; i < 8; ++i) {
+ int x = 136 * (i % 2);
+ int y = 161 + 10 * (i / 2);
+ _vm->renderBox(x, y, 135, 9, (brightness) ? HGR_INV_HELL : HGR_INV);
+ if (i < _inventory.getSize())
+ _vm->renderText(_inventory.get(i + _inventoryScroll)->_name, x + 1, y + 1, (brightness) ? COL_INV_HELL : COL_INV);
+ }
+ _vm->renderBox(272, 161, 7, 19, HGR_INV);
+ _vm->renderBox(272, 181, 7, 19, HGR_INV);
+}
+
+void GameManager::mouseInput() {
+ // STUB
+}
+
+void GameManager::mouseInput2() {
+ // STUB
+}
+
+void GameManager::mouseInput3() {
+ // STUB
+}
+
+void GameManager::mouseWait(int delay) {
+ // STUB
+}
+
+void GameManager::roomBrightness() {
+ // STUB
+}
+
+void GameManager::loadTime() {
+ // STUB
+}
+
+void GameManager::saveTime() {
+ // STUB
+}
+
+bool GameManager::saveGame(int number) {
+ // STUB
+ return false;
+}
+
+void GameManager::changeRoom(RoomID id) {
+ _currentRoom = _rooms[id];
+}
+
+void GameManager::errorTemp() {
+ // STUB
+}
+
+void GameManager::wait2(int delay) {
+ // STUB
+}
+
+void GameManager::screenShake() {
+ // STUB
+}
+
+void GameManager::palette() {
+ // STUB
+ // Adjust palette to brightness parameters and make it current
+}
+
+void GameManager::shock() {
+ // STUB
+ _vm->playSound(kAudioShock);
+ // die
+}
+
+void GameManager::showMenu() {
+ _vm->renderBox(0, 138, 320, 62, 0);
+ _vm->renderBox(0, 140, 320, 9, HGR_BEF_ANZ);
+ for (int i = 0; i < 10; i++)
+ drawCommandBox(i, 0);
+ _vm->renderBox(281, 161, 39, 39, HGR_AUSG);
+ drawInventory();
+}
+
+void GameManager::drawMapExits() {
+ // TODO: Preload _exitList on room entry instead on every call
+ _vm->renderBox(281, 161, 39, 39, HGR_AUSG);
+
+ for (int i = 0; i < 25; i++)
+ _exitList[i] = -1;
+ for (int i = 0; i < kMaxObject; i++) {
+ if (_currentRoom->getObject(i)->hasProperty(EXIT)) {
+ byte r = _currentRoom->getObject(i)->_direction;
+ _exitList[r] = i;
+ int x = 284 + 7 * (r % 5);
+ int y = 164 + 7 * (r / 5);
+ _vm->renderBox(x, y, 5, 5, COL_AUSG);
+ }
+ }
+}
+
+void GameManager::animationOff() {
+ // STUB
+}
+
+void GameManager::animationOn() {
+ // STUB
+}
+
+void GameManager::edit(char *text, int x, int y, int length) {
+ // STUB
+}
+
+void GameManager::loadOverlayStart() {
+ // STUB
+}
+
+void GameManager::drawStatus() {
+ _vm->renderBox(0, 140, 320, 9, HGR_BEF_ANZ);
+ int index = static_cast<int>(_inputVerb);
+ _vm->renderText(guiStatusCommand_DE[index], 1, 141, COL_BEF_ANZ);
+
+ if (_inputObject[0]->_id != NULLOBJECT) {
+ _vm->renderText(_inputObject[0]->_name);
+ if (_inputVerb2) {
+ if (_inputVerb == ACTION_GIVE) {
+ // to
+ _vm->renderText(" an ");
+ } else {
+ // with
+ _vm->renderText(" mit ");
+ }
+ if (_inputObject[1] != &_nullObjectInstance)
+ _vm->renderText(_inputObject[1]->_name);
+ }
+ }
+}
+
+void GameManager::openLocker(const Room *room, Object *obj, Object *lock, int section) {
+ _vm->renderImage(room->getFileNumber(), section);
+ obj->setProperty(OPENED);
+ lock->_click = 255;
+ int i = obj->_click;
+ obj->_click = obj->_click2;
+ obj->_click2 = i;
+}
+
+void GameManager::closeLocker(const Room *room, Object *obj, Object *lock, int section) {
+ // STUB
+}
+
+int GameManager::invertSection(int section) {
+ if (section < 128)
+ section += 128;
+ else
+ section -= 128;
+
+ return section;
+}
+
+
+bool GameManager::genericInteract(Action verb, Object &obj1, Object &obj2) {
+ Room *r;
+ char t[150];
+
+ if ((verb == ACTION_USE) && (obj1._id == SCHNUCK)) {
+ if (isHelmetOff()) {
+ takeObject(obj1);
+ _vm->renderMessage("Schmeckt ganz gut.");
+ _inventory.remove(obj1);
+ }
+ } else if ((verb == ACTION_USE) && (obj1._id == EGG)) {
+ if (isHelmetOff()) {
+ takeObject(obj1);
+ if (obj1.hasProperty(OPENED))
+ _vm->renderMessage("Schmeckt ganz gut.");
+ else
+ _vm->renderMessage("Da war irgendetwas drin,|aber jetzt hast du es|mit runtergeschluckt.");
+
+ _inventory.remove(obj1);
+ }
+ } else if ((verb == ACTION_OPEN) && (obj1._id == EGG)) {
+ takeObject(obj1);
+ if (obj1.hasProperty(OPENED)) {
+ _vm->renderMessage("Du hast es doch schon ge”ffnet.");
+ } else {
+ takeObject(*_rooms[ENTRANCE]->getObject(8));
+ _vm->renderMessage("In dem Ei ist eine Tablette|in einer Plastikhlle.");
+ obj1.setProperty(OPENED);
+ }
+ } else if ((verb == ACTION_USE) && (obj1._id == PILL)) {
+ if (isHelmetOff()) {
+ _vm->renderMessage("Du iát die Tablette und merkst,|daá sich irgendetwas ver„ndert hat.");
+ great(0);
+ _inventory.remove(obj1);
+ _state.language = 2;
+ takeObject(*_rooms[ENTRANCE]->getObject(17));
+ }
+ } else if ((verb == ACTION_LOOK) && (obj1._id == PILL_HULL) &&
+ (_state.language == 2)) {
+ _vm->renderMessage("Komisch! Auf einmal kannst du die Schrift lesen!|Darauf steht:\"Wenn Sie diese Schrift jetzt|lesen k”nnen, hat die Tablette gewirkt.\"");
+ _state.language = 1;
+ } else if ((verb == ACTION_OPEN) && (obj1._id == WALLET)) {
+ if (!_rooms[ROGER]->getObject(3)->hasProperty(CARRIED)) {
+ _vm->renderMessage("Das muát du erst nehmen.");
+ } else if (_rooms[ROGER]->getObject(7)->hasProperty(CARRIED)) {
+ _vm->renderMessage("Sie ist leer.");
+ } else {
+ _vm->renderMessage("Du findest 10 Buckazoids und eine Keycard.");
+ takeObject(*_rooms[ROGER]->getObject(7));
+ takeObject(*_rooms[ROGER]->getObject(8));
+ }
+ } else if ((verb == ACTION_LOOK) && (obj1._id == NEWSPAPER)) {
+ _vm->renderMessage("Es ist eine Art elektronische Zeitung.");
+ mouseWait(_timer1);
+ _vm->removeMessage();
+ _vm->renderMessage("Halt, hier ist ein interessanter Artikel.");
+ mouseWait(_timer1);
+ _vm->removeMessage();
+ _vm->renderImage(2,0);
+ _vm->setColor63(40);
+ mouseInput2();
+ _vm->renderRoom(*_currentRoom);
+ roomBrightness();
+ palette();
+ showMenu();
+ drawMapExits();
+ _vm->renderMessage("Hmm, irgendwie komme|ich mir verarscht vor.");
+ } else if ((verb == ACTION_LOOK) && (obj1._id == KEYCARD2)) {
+ _vm->renderMessage(obj1._description);
+ obj1._description = "Es ist die Keycard des Commanders.";
+ } else if ((verb == ACTION_LOOK) && (obj1._id == WATCH)) {
+ _vm->renderMessage(Common::String::format(
+ "Es ist eine Uhr mit extra|lautem Wecker. "
+ "Sie hat einen|Knopf zum Verstellen der Alarmzeit.|"
+ "Uhrzeit: %s Alarmzeit: %s",
+ timeToString(_vm->getDOSTicks() - _state.timeStarting),
+ timeToString(_state.timeAlarm)).c_str());
+ } else if ((verb == ACTION_PRESS) && (obj1._id == WATCH)) {
+ char *min;
+ int hours, minutes;
+ bool f;
+ animationOff();
+ _vm->saveScreen(88, 87, 144, 24);
+ _vm->renderBox(88, 87, 144, 24, kColorWhite35);
+ _vm->renderText("Neue Alarmzeit (hh:mm) :", 91, 90, kColorWhite99);
+ do {
+ t[0] = 0;
+ _vm->renderBox(91, 99, 138, 9, kColorDarkBlue);
+ do {
+ edit(t, 91, 100, 5);
+ } while ((_key != Common::ASCII_RETURN) && (_key != Common::ASCII_ESCAPE));
+ f = false;
+ if (t[0] == ':') {
+ t[0] = 0;
+ min = &(t[1]);
+ } else if (t[1] == ':') {
+ t[1] = 0;
+ min = &(t[2]);
+ } else if (t[2] == ':') {
+ t[2] = 0;
+ min = &(t[3]);
+ } else {
+ f = true;
+ }
+
+ for (uint i = 0; i < strlen(t); i++)
+ if ((t[i] < '0') || (t[i] > '9')) f = true;
+ for (uint i = 0; i < strlen(min); i++)
+ if ((min[i] < '0') || (min[i] > '9')) f = true;
+ hours = atoi(t);
+ minutes = atoi(min);
+ if ((hours > 23) || (minutes > 59)) f = true;
+ animationOn();
+ } while (f && (_key != Common::ASCII_ESCAPE));
+ _vm->restoreScreen();
+ if (_key != Common::ASCII_ESCAPE) {
+ _state.timeAlarm = (hours * 60 + minutes) * 1092.3888 + 8;
+ _state.timeAlarmSystem = _state.timeAlarm + _state.timeStarting;
+ _state.alarmOn = (_state.timeAlarmSystem > _vm->getDOSTicks());
+ }
+ } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, TERMINALSTRIP, WIRE)) {
+ r = _rooms[CABIN_L3];
+ if (!r->getObject(8)->hasProperty(CARRIED)) {
+ if (r->isSectionVisible(26))
+ _vm->renderMessage(Object::takeMessage);
+ else
+ return false;
+ } else {
+ r->getObject(8)->_name = "Leitung mit Lsterklemme";
+ r = _rooms[HOLD];
+ _inventory.remove(*r->getObject(2));
+ _state.terminalStripConnected = true;
+ _state.terminalStripWire = true;
+ _vm->renderMessage("Ok.");
+ }
+ } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, TERMINALSTRIP, SPOOL)) {
+ r = _rooms[CABIN_L2];
+ takeObject(*r->getObject(9));
+ r->getObject(9)->_name = "Kabelrolle mit Lsterklemme";
+ r = _rooms[HOLD];
+ _inventory.remove(*r->getObject(2));
+ _state.terminalStripConnected = true;
+ _vm->renderMessage("Ok.");
+ } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, WIRE, SPOOL)) {
+ r = _rooms[CABIN_L3];
+ if (!_state.terminalStripConnected) {
+ if (r->isSectionVisible(26))
+ _vm->renderMessage("Womit denn?");
+ else
+ return false;
+ } else {
+ if (!r->getObject(8)->hasProperty(CARRIED)) {
+ _vm->renderMessage(Object::takeMessage);
+ } else {
+ r = _rooms[CABIN_L2];
+ takeObject(*r->getObject(9));
+ r = _rooms[CABIN_L3];
+ r->getObject(8)->_name = "langes Kabel mit Stecker";
+ r = _rooms[CABIN_L2];
+ _inventory.remove(*r->getObject(9));
+ _state.cableConnected = true;
+ _vm->renderMessage("Ok.");
+ }
+ }
+ } else if ((verb == ACTION_USE) && (obj1._id == SUIT)) {
+ takeObject(obj1);
+ if ((_currentRoom >= _rooms[ENTRANCE]) && (_currentRoom <= _rooms[ROGER])) {
+ if (obj1.hasProperty(WORN)) {
+ _vm->renderMessage("Die Luft hier ist atembar,|du ziehst den Anzug aus.");
+ _rooms[AIRLOCK]->getObject(4)->disableProperty(WORN);
+ _rooms[AIRLOCK]->getObject(5)->disableProperty(WORN);
+ _rooms[AIRLOCK]->getObject(6)->disableProperty(WORN);
+ } else
+ _vm->renderMessage("Hier drinnen brauchtst du deinen Anzug nicht.");
+ } else {
+ if (obj1.hasProperty(WORN)) {
+ r = _rooms[AIRLOCK];
+ if (r->getObject(4)->hasProperty(WORN)) {
+ _vm->renderMessage("Du muát erst den Helm abnehmen.");
+ } else if (r->getObject(6)->hasProperty(WORN)) {
+ _vm->renderMessage("Du muát erst den Versorgungsteil abnehmen.");
+ } else {
+ obj1.disableProperty(WORN);
+ _vm->renderMessage("Du ziehst den Raumanzug aus.");
+ }
+ } else {
+ obj1.setProperty(WORN);
+ _vm->renderMessage("Du ziehst den Raumanzug an.");
+ }
+ }
+ } else if ((verb == ACTION_USE) && (obj1._id == HELMET)) {
+ takeObject(obj1);
+ if ((_currentRoom >= _rooms[ENTRANCE]) && (_currentRoom <= _rooms[ROGER])) {
+ if (obj1.hasProperty(WORN)) {
+ _vm->renderMessage("Die Luft hier ist atembar,|du ziehst den Anzug aus.");
+ _rooms[AIRLOCK]->getObject(4)->disableProperty(WORN);
+ _rooms[AIRLOCK]->getObject(5)->disableProperty(WORN);
+ _rooms[AIRLOCK]->getObject(6)->disableProperty(WORN);
+ } else {
+ _vm->renderMessage("Hier drinnen brauchtst du deinen Anzug nicht.");
+ }
+ } else {
+ if (obj1.hasProperty(WORN)) {
+ if (airless()) {
+ //TODO: Death screen
+// longjmp(dead, "Den Helm h„ttest du|besser angelassen!");
+ }
+ obj1.disableProperty(WORN);
+ _vm->renderMessage("Du ziehst den Helm ab.");
+ } else {
+ r = _rooms[AIRLOCK];
+ if (r->getObject(5)->hasProperty(WORN)) {
+ obj1.setProperty(WORN);
+ _vm->renderMessage("Du ziehst den Helm auf.");
+ } else {
+ _vm->renderMessage("Du muát erst den Anzug anziehen.");
+ }
+ }
+ }
+ } else if ((verb == ACTION_USE) && (obj1._id == LIFESUPPORT)) {
+ takeObject(obj1);
+ if ((_currentRoom >= _rooms[ENTRANCE]) && (_currentRoom <= _rooms[ROGER])) {
+ if (obj1.hasProperty(WORN)) {
+ _vm->renderMessage("Die Luft hier ist atembar,|du ziehst den Anzug aus.");
+ _rooms[AIRLOCK]->getObject(4)->disableProperty(WORN);
+ _rooms[AIRLOCK]->getObject(5)->disableProperty(WORN);
+ _rooms[AIRLOCK]->getObject(6)->disableProperty(WORN);
+ } else
+ _vm->renderMessage("Hier drinnen brauchtst du deinen Anzug nicht.");
+ } else {
+ if (obj1.hasProperty(WORN)) {
+ if (airless()) {
+ //TODO: Death screen
+// longjmp(dead, "Den Versorungsteil h„ttest du|besser nicht abgenommen!");
+ }
+ obj1.disableProperty(WORN);
+ _vm->renderMessage("Du nimmst den Versorgungsteil ab.");
+ } else {
+ r = _rooms[AIRLOCK];
+ if (r->getObject(5)->hasProperty(WORN)) {
+ obj1.setProperty(WORN);
+ _vm->renderMessage("Du ziehst den Versorgungsteil an.");
+ } else {
+ _vm->renderMessage("Du muát erst den Anzug anziehen.");
+ }
+ }
+ }
+ } else if ((verb == ACTION_WALK) && (obj1._id == BATHROOM_DOOR)) {
+// *bathroom = current_room;
+ return false;
+ } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, WIRE, SOCKET))
+ _vm->renderMessage("Die Leitung ist hier unntz.");
+ else if ((verb == ACTION_LOOK) && (obj1._id == BOOK2)) {
+ _vm->renderMessage("Stark, das ist ja die Fortsetzung zum \"Anhalter\":|\"Das Restaurant am Ende des Universums\".");
+ mouseWait(_timer1);
+ _vm->removeMessage();
+ _vm->renderMessage("Moment mal, es ist ein Lesezeichen drin,|auf dem \"Zweiundvierzig\" steht.");
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+void GameManager::executeRoom() {
+ // TODO: clean up. minimize.
+ _vm->renderRoom(*_currentRoom);
+ drawMapExits();
+ drawInventory();
+ drawStatus();
+ drawCommandBox();
+ animationOn();
+ roomBrightness();
+ if (_vm->_brightness == 0)
+ _vm->paletteFadeIn();
+ else
+ _vm->paletteBrightness();
+
+ if (!_currentRoom->hasSeen())
+ _currentRoom->onEntrance();
+
+ bool validCommand = genericInteract(_inputVerb, *_inputObject[0], *_inputObject[1]);
+
+
+#if 0
+ if (!validCommand) {
+ validCommand = _currentRoom->interact(_inputVerb, *_inputObject[0], *_inputObject[1]);
+ if (!validCommand) {
+ switch (_inputVerb) {
+ case ACTION_LOOK:
+ _vm->renderMessage(_inputObject[0]->_description);
+ break;
+
+ case ACTION_WALK:
+ if (_inputObject[0]->hasProperty(CARRIED)) {
+ // You already carry this.
+ _vm->renderMessage("Das tr„gst du doch bei dir.");
+ } else if (!_inputObject[0]->hasProperty(EXIT)) {
+ // You're already there.
+ _vm->renderMessage("Du bist doch schon da.");
+ } else if (_inputObject[0]->hasProperty(OPEN) && !_inputObject[0]->hasProperty(OPENED)) {
+ // This is closed
+ _vm->renderMessage("Das ist geschlossen.");
+ } else {
+ _currentRoom = _rooms[_inputObject[0]->_exitRoom];
+ return;
+ }
+ break;
+
+ case ACTION_TAKE:
+ if (_inputObject[0]->hasProperty(OPENED)) {
+ // You already have that
+ _vm->renderMessage("Das hast du doch schon.");
+ } else if (_inputObject[0]->hasProperty(UNNECESSARY)) {
+ // You do not need that.
+ _vm->renderMessage("Das brauchst du nicht.");
+ } else if (!_inputObject[0]->hasProperty(TAKE)) {
+ // You can't take that.
+ _vm->renderMessage("Das kannst du nicht nehmen.");
+ } else {
+ takeObject(*_inputObject[0]);
+ }
+ break;
+
+ case ACTION_OPEN:
+ if (!_inputObject[0]->hasProperty(OPEN)) {
+ // This can't be opened
+ _vm->renderMessage("Das l„át sich nicht ”ffnen.");
+ } else if (_inputObject[0]->hasProperty(OPENED)) {
+ // This is already opened.
+ _vm->renderMessage("Das ist schon offen.");
+ } else if (_inputObject[0]->hasProperty(CLOSED)) {
+ // This is locked.
+ _vm->renderMessage("Das ist verschlossen.");
+ } else {
+ _vm->renderImage(_currentRoom->getFileNumber(), _inputObject[0]->_section);
+ _inputObject[0]->setProperty(OPENED);
+ byte i = _inputObject[0]->_click;
+ _inputObject[0]->_click = _inputObject[0]->_click2;
+ _inputObject[0]->_click2 = i;
+ _vm->playSound(kAudioDoorOpen);
+ }
+ break;
+
+ case ACTION_CLOSE:
+ if (!_inputObject[0]->hasProperty(OPEN) ||
+ (_inputObject[0]->hasProperty(CLOSED) &&
+ _inputObject[0]->hasProperty(OPENED))) {
+ // This can't be closed.
+ _vm->renderMessage("Das l„át sich nicht schlieáen.");
+ } else if (!_inputObject[0]->hasProperty(OPENED)) {
+ // This is already closed.
+ _vm->renderMessage("Das ist schon geschlossen.");
+ } else {
+ _vm->renderImage(_currentRoom->getFileNumber(), invertSection(_inputObject[0]->_section));
+ _inputObject[0]->disableProperty(OPENED);
+ byte i = _inputObject[0]->_click;
+ _inputObject[0]->_click = _inputObject[0]->_click2;
+ _inputObject[0]->_click2 = i;
+ _vm->playSound(kAudioDoorClose);
+ }
+ break;
+
+ case ACTION_GIVE:
+ if (_inputObject[0]->hasProperty(CARRIED)) {
+ // Better keep it!
+ _vm->renderMessage("Behalt es lieber!");
+ }
+ break;
+
+ default:
+ // This is not possible.
+ _vm->renderMessage("Das geht nicht.");
+ }
+
+ if (_newOverlay) {
+ loadOverlayStart();
+ _newOverlay = false;
+ }
+ if (_newRoom) {
+ _newRoom = false;
+ return;
+ }
+ }
+ }
+#endif
+}
+
+}
diff --git a/engines/supernova/state.h b/engines/supernova/state.h
new file mode 100644
index 0000000000..08e5591af1
--- /dev/null
+++ b/engines/supernova/state.h
@@ -0,0 +1,153 @@
+/* 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 STATE_H
+#define STATE_H
+
+#include "common/rect.h"
+#include "supernova/rooms.h"
+
+namespace Supernova {
+
+struct GameState {
+ int32 time;
+ int32 timeSleep;
+ int32 timeStarting;
+ int32 timeAlarm;
+ int32 timeAlarmSystem;
+ int32 eventTime;
+ int32 shipEnergy;
+ int32 landingModuleEnergy;
+ uint16 greatF;
+ int16 timeRobot;
+ int16 money;
+ char coins;
+ char shoes;
+ char nameSeen;
+ char destination;
+ char benOverlay;
+ char language;
+ bool corridorSearch;
+ bool alarmOn;
+ bool terminalStripConnected;
+ bool terminalStripWire;
+ bool cableConnected;
+ bool powerOff;
+ bool cockpitSeen;
+ bool airlockSeen;
+ bool holdSeen;
+ bool dream;
+};
+
+class Inventory {
+public:
+ Inventory();
+
+ void add(Object &obj);
+ void remove(Object &obj);
+ Object *get(uint index) const;
+ Object *get(ObjectID id) const;
+ uint getSize() const { return _numObjects; }
+
+private:
+ Object *_inventory[kMaxCarry];
+ uint _numObjects;
+};
+
+class GameManager {
+public:
+ GameManager(SupernovaEngine *vm);
+
+ void processInput(Common::KeyState &state);
+ void processInput(Common::EventType eventType, int x, int y);
+ void executeRoom();
+
+ SupernovaEngine *_vm;
+ uint16 _key;
+ Common::EventType _mouseClickType;
+ int _mouseX;
+ int _mouseY;
+ int _mouseField;
+ Room *_currentRoom;
+ Room *_rooms[kRoomsNum];
+ Inventory _inventory;
+ GameState _state;
+ int _status;
+ Action _inputVerb;
+ bool _inputVerb2;
+ Object _nullObjectInstance;
+ Object *_inputObject[2];
+ int _objectNumber;
+ bool _waitEvent;
+ bool _newRoom;
+ bool _newOverlay;
+ int _timer1;
+ int _timer2;
+ int _inventoryScroll;
+ int _exitList[25];
+ Common::Rect _guiCommandDimensions[10];
+ // 0 PC Speaker | 1 SoundBlaster | 2 No Sound
+ int _soundDevice;
+
+ void takeObject(Object &obj);
+
+ void initGui();
+ bool genericInteract(Action verb, Object &obj1, Object &obj2);
+ bool isHelmetOff();
+ void great(uint number);
+ bool airless();
+ void shock();
+ void mouseInput();
+ void mouseInput2();
+ void mouseInput3();
+ void mouseWait(int delay);
+ void wait2(int delay);
+ void turnOff();
+ void turnOn();
+ void screenShake();
+ void loadTime();
+ void saveTime();
+ bool saveGame(int number);
+ void errorTemp();
+ void roomBrightness();
+ void palette();
+ void showMenu();
+ void animationOff();
+ void animationOn();
+ void loadOverlayStart();
+ void openLocker(const Room *room, Object *obj, Object *lock, int section);
+ void closeLocker(const Room *room, Object *obj, Object *lock, int section);
+ void edit(char *text, int x, int y, int length);
+ int invertSection(int section);
+ void drawMapExits();
+ void drawStatus();
+ void drawCommandBox(int cmd, bool brightness);
+ void drawCommandBox();
+ void inventory_arrow(int num, bool brightness);
+ void inventory_object(int num, bool brightness);
+ void drawInventory();
+ void changeRoom(RoomID id);
+};
+
+}
+
+#endif // STATE_H
diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp
index 6774ac7c2f..b11c66a831 100644
--- a/engines/supernova/supernova.cpp
+++ b/engines/supernova/supernova.cpp
@@ -39,6 +39,7 @@
#include "common/endian.h"
#include "supernova/supernova.h"
+#include "supernova/state.h"
namespace Supernova {
@@ -126,20 +127,18 @@ SupernovaEngine::~SupernovaEngine() {
}
Common::Error SupernovaEngine::run() {
- GameManager gm(this, &_event);
initGraphics(_screenWidth, _screenHeight);
+ GameManager gm(this);
_console = new Console(this, &gm);
initData();
initPalette();
- paletteFadeIn();
- CursorMan.replaceCursor(_mouseWait, 16, 16, 0, 0, kColorCursorTransparent);
+ CursorMan.replaceCursor(_mouseNormal, 16, 16, 0, 0, kColorCursorTransparent);
CursorMan.replaceCursorPalette(initVGAPalette, 0, 16);
CursorMan.showMouse(true);
while (_gameRunning) {
-
while (g_system->getEventManager()->pollEvent(_event)) {
switch (_event.type) {
case Common::EVENT_QUIT:
@@ -148,29 +147,29 @@ Common::Error SupernovaEngine::run() {
break;
case Common::EVENT_KEYDOWN:
- if (_event.kbd.keycode == Common::KEYCODE_d && _event.kbd.hasFlags(Common::KBD_CTRL)) {
+ if (_event.kbd.keycode == Common::KEYCODE_d &&
+ (_event.kbd.flags & Common::KBD_CTRL)) {
_console->attach();
}
+
+ gm.processInput(_event.kbd);
break;
case Common::EVENT_LBUTTONUP:
- break;
+ // fallthrough
case Common::EVENT_RBUTTONUP:
- // TODO: Determines verb depending on object properties
- break;
+ // fallthrough
case Common::EVENT_MOUSEMOVE:
- // TODO: Update status if mouse enters/leaves object
+ gm.processInput(_event.type, _event.mouse.x, _event.mouse.y);
break;
default:
break;
}
-// gm.processInput();
}
+ gm.executeRoom();
_console->onFrame();
- renderText(Common::String::format("%3d | %3d", _imageIndex, _sectionIndex).c_str(),
- 10, 190, kColorLightGreen);
_system->updateScreen();
_system->delayMillis(_delay);
}
@@ -312,7 +311,7 @@ void SupernovaEngine::renderImage(MSNImageDecoder &image, int section, bool full
uint offset = image._section[section].y1 * image._pitch + image._section[section].x1;
_system->copyRectToScreen(static_cast<const byte *>(image._sectionSurfaces[section]->getPixels()) + offset,
image._pitch,
- sectionRect.top, sectionRect.left,
+ sectionRect.left, sectionRect.top,
sectionRect.width(), sectionRect.height());
}
}
@@ -333,13 +332,17 @@ void SupernovaEngine::restoreScreen() {
}
void SupernovaEngine::renderRoom(Room &room) {
- for (int i = 0; i < kMaxSection; ++i) {
- if (room.isSectionVisible(i))
- renderImage(room.getFileNumber(), i);
+ if (room.getFileNumber() == -1) {
+ _system->fillScreen(kColorBlack);
+ } else {
+ for (int i = 0; i < kMaxSection; ++i) {
+ if (room.isSectionVisible(i))
+ renderImage(room.getFileNumber(), i);
+ }
}
}
-static int characterWidth(const char *text) {
+int SupernovaEngine::characterWidth(const char *text) {
int charWidth = 0;
while (*text != '\0') {
byte c = *text++;
@@ -422,6 +425,7 @@ void SupernovaEngine::renderMessage(const char *text, MessagePosition position)
int message_rows = y - 3;
int message_width = rowWidthMax + 6;
int message_height = numRows * 9 + 5;
+ saveScreen(message_columns, message_rows, message_width, message_height);
renderBox(message_columns, message_rows, message_width, message_height, HGR_MELD);
for (uint i = 0; i < numRows; ++i) {
renderText(row[i], x, y, textColor);
@@ -543,694 +547,6 @@ void SupernovaEngine::setColor63(byte value) {
_system->getPaletteManager()->setPalette(color, 63, 1);
}
-
-Inventory::Inventory()
- : _numObjects(0)
-{}
-
-// TODO: Update Inventory surface for scrolling
-void Inventory::add(Object &obj) {
- if (_numObjects < kMaxCarry)
- _inventory[_numObjects] = &obj;
-
-// if (inventory_amount>8) inventory_scroll = ((inventory_amount+1)/2)*2-8;
-// show_inventory();
-}
-
-// TODO: Update Inventory surface for scrolling
-void Inventory::remove(Object &obj) {
- for (uint i = 0; i < _numObjects; ++i) {
- if (_inventory[i] == &obj) {
- --_numObjects;
- while (i < _numObjects) {
- _inventory[i] = _inventory[i + 1];
- ++i;
- }
- obj.disableProperty(CARRIED);
- }
- }
-}
-
-Object *Inventory::get(uint index) const {
- if (index < _numObjects)
- return _inventory[index];
-
- return NULL;
-}
-
-Object *Inventory::get(ObjectID id) const {
- for (uint i = 0; i < _numObjects; ++i) {
- if (_inventory[i]->_id == id)
- return _inventory[i];
- }
-
- return NULL;
-}
-
-ScreenBufferStack::ScreenBufferStack()
- : _last(_buffer) {
-}
-
-void ScreenBufferStack::push(int x, int y, int width, int height, int pitch) {
- if (_last == ARRAYEND(_buffer))
- return;
-
- _last->_pixels = new byte[width * height];
- byte *pixels = _last->_pixels;
- const byte *screen = static_cast<const byte *>(g_system->lockScreen()->getBasePtr(x, y));
- for (int i = 0; i < height; ++i) {
- Common::copy(screen, screen + width, pixels);
- screen += pitch;
- pixels += width;
- }
- g_system->unlockScreen();
-
- _last->_x = x;
- _last->_y = y;
- _last->_width = width;
- _last->_height = height;
- _last->_pitch = pitch;
-
- ++_last;
-}
-
-void ScreenBufferStack::restore() {
- if (_last == _buffer)
- return;
-
- --_last;
- g_system->lockScreen()->copyRectToSurface(
- _last->_pixels, _last->_width, _last->_x, _last->_y,
- _last->_width, _last->_height);
- g_system->unlockScreen();
-
- delete[] _last->_pixels;
-}
-
-
-static const char *timeToString(int t) {
- // TODO: Does ScummVM emulate PIT timings for DOS?
-
- static char s[9];
- strcpy(s," 0:00:00");
- s[7] = t % 10 + '0';
- t /= 10;
- s[6] = t % 6 + '0';
- t /= 6;
- s[4] = t % 10 + '0';
- t /= 10;
- s[3] = t % 6 + '0';
- t /= 6;
- s[1] = t % 10 + '0';
- t /= 10;
- if (t)
- s[0] = t+48;
-
- return(s);
-}
-
-GameManager::GameManager(SupernovaEngine *vm, Common::Event *event) {
- _rooms[INTRO] = StartingItems(vm, this);
- _rooms[CORRIDOR] = ShipCorridor(vm, this);
- _rooms[HALL] = ShipHall(vm, this);
- _rooms[SLEEP] = ShipSleepCabin(vm, this);
- _rooms[COCKPIT] = ShipCockpit(vm, this);
- _rooms[AIRLOCK] = ShipAirlock(vm, this);
- _rooms[HOLD] = ShipHold(vm, this);
- _rooms[LANDINGMODULE] = ShipLandingModule(vm, this);
- _rooms[GENERATOR] = ShipGenerator(vm, this);
- _rooms[OUTSIDE] = ShipOuterSpace(vm, this);
- _rooms[CABIN_R1] = ShipCabinR1(vm, this);
- _rooms[CABIN_R2] = ShipCabinR2(vm, this);
- _rooms[CABIN_R3] = ShipCabinR3(vm, this);
- _rooms[CABIN_L1] = ShipCabinL1(vm, this);
- _rooms[CABIN_L2] = ShipCabinL2(vm, this);
- _rooms[CABIN_L3] = ShipCabinL3(vm, this);
- _rooms[BATHROOM] = ShipCabinBathroom(vm, this);
-
-// _rooms[ROCKS]
-// _rooms[CAVE]
-// _rooms[MEETUP]
-// _rooms[ENTRANCE]
-// _rooms[REST]
-// _rooms[ROGER]
-// _rooms[GLIDER]
-// _rooms[MEETUP2]
-// _rooms[MEETUP3]
-
-// _rooms[CELL]
-// _rooms[CORRIDOR1]
-// _rooms[CORRIDOR2]
-// _rooms[CORRIDOR3]
-// _rooms[CORRIDOR4]
-// _rooms[CORRIDOR5]
-// _rooms[CORRIDOR6]
-// _rooms[CORRIDOR7]
-// _rooms[CORRIDOR8]
-// _rooms[CORRIDOR9]
-// _rooms[BCORRIDOR]
-// _rooms[GUARD]
-// _rooms[GUARD3]
-// _rooms[OFFICE_L1]
-// _rooms[OFFICE_L2]
-// _rooms[OFFICE_R1]
-// _rooms[OFFICE_R2]
-// _rooms[OFFICE_L]
-// _rooms[ELEVATOR]
-// _rooms[STATION]
-// _rooms[SIGN]
-
- _currentRoom = &_rooms[0];
- _vm = vm;
- _event = event;
-}
-
-bool GameManager::isHelmetOff() {
- Object *helmet = _inventory.get(HELMET);
- if (helmet && helmet->hasProperty(WORN)) {
- _vm->renderMessage("Irgendwie ist ein Raumhelm|beim Essen unpraktisch.");
- return false;
- }
-
- return true;
-}
-
-void GameManager::great(uint number) {
- if (number && (_state.greatF & (1 << number)))
- return;
-
- _vm->playSound(kAudioUndef7);
- _state.greatF |= 1 << number;
-}
-
-bool GameManager::airless() {
- return (
- ((_currentRoom > &_rooms[AIRLOCK]) && (_currentRoom < &_rooms[CABIN_R1])) ||
- ((_currentRoom > &_rooms[BATHROOM])&& (_currentRoom < &_rooms[ENTRANCE])) ||
- ((_currentRoom == &_rooms[AIRLOCK]) && (_currentRoom->getObject(1)->hasProperty(OPENED))) ||
- (_currentRoom >= &_rooms[MEETUP2])
- );
-}
-
-void GameManager::processInput() {
- // STUB
-}
-
-void GameManager::turnOff() {
- if (_state.powerOff)
- return;
-
- _state.powerOff = true;
- roomBrightness();
-
-}
-void GameManager::turnOn() {
- // STUB
-}
-
-void GameManager::takeObject(Object &obj) {
- if (obj.hasProperty(CARRIED))
- return;
-
- if (obj._section != 0)
- _vm->renderImage(_currentRoom->getFileNumber(), obj._section);
- obj.setProperty(CARRIED);
- obj._click = obj._click2 = 255;
- _inventory.add(obj);
-}
-
-void GameManager::mouseInput() {
- // STUB
-}
-
-void GameManager::mouseInput2() {
- // STUB
-}
-
-void GameManager::mouseInput3() {
- // STUB
-}
-
-void GameManager::mouseWait(int delay) {
- // STUB
-}
-
-void GameManager::roomBrightness() {
- // STUB
-}
-
-void GameManager::loadTime() {
- // STUB
-}
-
-void GameManager::saveTime() {
- // STUB
-}
-
-bool GameManager::saveGame(int number) {
- // STUB
- return false;
-}
-
-void GameManager::errorTemp() {
- // STUB
-}
-
-void GameManager::wait2(int delay) {
- // STUB
-}
-
-void GameManager::screenShake() {
- // STUB
-}
-
-void GameManager::palette() {
- // STUB
- // Adjust palette to brightness parameters and make it current
-}
-
-void GameManager::shock() {
- // STUB
- _vm->playSound(kAudioShock);
- // die
-}
-
-void GameManager::showMenu() {
- // STUB
-}
-
-void GameManager::drawMapExits() {
- // STUB
-}
-
-void GameManager::animationOff() {
- // STUB
-}
-
-void GameManager::animationOn() {
- // STUB
-}
-
-void GameManager::edit(char *text, int x, int y, int length) {
- // STUB
-}
-
-void GameManager::loadOverlayStart() {
- // STUB
-}
-
-void GameManager::openLocker(const Room *room, Object *obj, Object *lock, int section) {
- _vm->renderImage(room->getFileNumber(), section);
- obj->setProperty(OPENED);
- lock->_click = 255;
- int i = obj->_click;
- obj->_click = obj->_click2;
- obj->_click2 = i;
-}
-
-void GameManager::closeLocker(const Room *room, Object *obj, Object *lock, int section) {
- // STUB
-}
-
-int GameManager::invertSection(int section) {
- if (section < 128)
- section += 128;
- else
- section -= 128;
-
- return section;
-}
-
-
-bool GameManager::genericInteract(Action verb, Object &obj1, Object &obj2) {
- Room *r;
- char t[150];
-
- if ((verb == ACTION_USE) && (obj1._id == SCHNUCK)) {
- if (isHelmetOff()) {
- takeObject(obj1);
- _vm->renderMessage("Schmeckt ganz gut.");
- _inventory.remove(obj1);
- }
- } else if ((verb == ACTION_USE) && (obj1._id == EGG)) {
- if (isHelmetOff()) {
- takeObject(obj1);
- if (obj1.hasProperty(OPENED))
- _vm->renderMessage("Schmeckt ganz gut.");
- else
- _vm->renderMessage("Da war irgendetwas drin,|aber jetzt hast du es|mit runtergeschluckt.");
-
- _inventory.remove(obj1);
- }
- } else if ((verb == ACTION_OPEN) && (obj1._id == EGG)) {
- takeObject(obj1);
- if (obj1.hasProperty(OPENED)) {
- _vm->renderMessage("Du hast es doch schon ge”ffnet.");
- } else {
- takeObject(*_rooms[ENTRANCE].getObject(8));
- _vm->renderMessage("In dem Ei ist eine Tablette|in einer Plastikhlle.");
- obj1.setProperty(OPENED);
- }
- } else if ((verb == ACTION_USE) && (obj1._id == PILL)) {
- if (isHelmetOff()) {
- _vm->renderMessage("Du iát die Tablette und merkst,|daá sich irgendetwas ver„ndert hat.");
- great(0);
- _inventory.remove(obj1);
- _state.language = 2;
- takeObject(*_rooms[ENTRANCE].getObject(17));
- }
- } else if ((verb == ACTION_LOOK) && (obj1._id == PILL_HULL) &&
- (_state.language == 2)) {
- _vm->renderMessage("Komisch! Auf einmal kannst du die Schrift lesen!|Darauf steht:\"Wenn Sie diese Schrift jetzt|lesen k”nnen, hat die Tablette gewirkt.\"");
- _state.language = 1;
- } else if ((verb == ACTION_OPEN) && (obj1._id == WALLET)) {
- if (!_rooms[ROGER].getObject(3)->hasProperty(CARRIED)) {
- _vm->renderMessage("Das muát du erst nehmen.");
- } else if (_rooms[ROGER].getObject(7)->hasProperty(CARRIED)) {
- _vm->renderMessage("Sie ist leer.");
- } else {
- _vm->renderMessage("Du findest 10 Buckazoids und eine Keycard.");
- takeObject(*_rooms[ROGER].getObject(7));
- takeObject(*_rooms[ROGER].getObject(8));
- }
- } else if ((verb == ACTION_LOOK) && (obj1._id == NEWSPAPER)) {
- _vm->renderMessage("Es ist eine Art elektronische Zeitung.");
- mouseWait(_timer1);
- _vm->removeMessage();
- _vm->renderMessage("Halt, hier ist ein interessanter Artikel.");
- mouseWait(_timer1);
- _vm->removeMessage();
- _vm->renderImage(2,0);
- _vm->setColor63(40);
- mouseInput2();
- _vm->renderRoom(*_currentRoom);
- roomBrightness();
- palette();
- showMenu();
- drawMapExits();
- _vm->renderMessage("Hmm, irgendwie komme|ich mir verarscht vor.");
- } else if ((verb == ACTION_LOOK) && (obj1._id == KEYCARD2)) {
- _vm->renderMessage(obj1._description);
- obj1._description = "Es ist die Keycard des Commanders.";
- } else if ((verb == ACTION_LOOK) && (obj1._id == WATCH)) {
- _vm->renderMessage(Common::String::format(
- "Es ist eine Uhr mit extra|lautem Wecker. "
- "Sie hat einen|Knopf zum Verstellen der Alarmzeit.|"
- "Uhrzeit: %s Alarmzeit: %s",
- timeToString(_vm->getDOSTicks() - _state.timeStarting),
- timeToString(_state.timeAlarm)).c_str());
- } else if ((verb == ACTION_PRESS) && (obj1._id == WATCH)) {
- char *min;
- int hours, minutes;
- bool f;
- animationOff();
- _vm->saveScreen(88, 87, 144, 24);
- _vm->renderBox(88, 87, 144, 24, kColorWhite35);
- _vm->renderText("Neue Alarmzeit (hh:mm) :", 91, 90, kColorWhite99);
- do {
- t[0] = 0;
- _vm->renderBox(91, 99, 138, 9, kColorDarkBlue);
- do {
- edit(t, 91, 100, 5);
- } while ((_key != Common::ASCII_RETURN) && (_key != Common::ASCII_ESCAPE));
- f = false;
- if (t[0] == ':') {
- t[0] = 0;
- min = &(t[1]);
- } else if (t[1] == ':') {
- t[1] = 0;
- min = &(t[2]);
- } else if (t[2] == ':') {
- t[2] = 0;
- min = &(t[3]);
- } else {
- f = true;
- }
-
- for (uint i = 0; i < strlen(t); i++)
- if ((t[i] < '0') || (t[i] > '9')) f = true;
- for (uint i = 0; i < strlen(min); i++)
- if ((min[i] < '0') || (min[i] > '9')) f = true;
- hours = atoi(t);
- minutes = atoi(min);
- if ((hours > 23) || (minutes > 59)) f = true;
- animationOn();
- } while (f && (_key != Common::ASCII_ESCAPE));
- _vm->restoreScreen();
- if (_key != Common::ASCII_ESCAPE) {
- _state.timeAlarm = (hours * 60 + minutes) * 1092.3888 + 8;
- _state.timeAlarmSystem = _state.timeAlarm + _state.timeStarting;
- _state.alarmOn = (_state.timeAlarmSystem > _vm->getDOSTicks());
- }
- } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, TERMINALSTRIP, WIRE)) {
- r = &_rooms[CABIN_L3];
- if (!r->getObject(8)->hasProperty(CARRIED)) {
- if (r->isSectionVisible(26))
- _vm->renderMessage(Object::takeMessage);
- else
- return false;
- } else {
- r->getObject(8)->_name = "Leitung mit Lsterklemme";
- r = &_rooms[HOLD];
- _inventory.remove(*r->getObject(2));
- _state.terminalStripConnected = true;
- _state.terminalStripWire = true;
- _vm->renderMessage("Ok.");
- }
- } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, TERMINALSTRIP, SPOOL)) {
- r = &_rooms[CABIN_L2];
- takeObject(*r->getObject(9));
- r->getObject(9)->_name = "Kabelrolle mit Lsterklemme";
- r = &_rooms[HOLD];
- _inventory.remove(*r->getObject(2));
- _state.terminalStripConnected = true;
- _vm->renderMessage("Ok.");
- } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, WIRE, SPOOL)) {
- r = &_rooms[CABIN_L3];
- if (!_state.terminalStripConnected) {
- if (r->isSectionVisible(26))
- _vm->renderMessage("Womit denn?");
- else
- return false;
- } else {
- if (!r->getObject(8)->hasProperty(CARRIED)) {
- _vm->renderMessage(Object::takeMessage);
- } else {
- r = &_rooms[CABIN_L2];
- takeObject(*r->getObject(9));
- r = &_rooms[CABIN_L3];
- r->getObject(8)->_name = "langes Kabel mit Stecker";
- r = &_rooms[CABIN_L2];
- _inventory.remove(*r->getObject(9));
- _state.cableConnected = true;
- _vm->renderMessage("Ok.");
- }
- }
- } else if ((verb == ACTION_USE) && (obj1._id == SUIT)) {
- takeObject(obj1);
- if ((_currentRoom >= &_rooms[ENTRANCE]) && (_currentRoom <= &_rooms[ROGER])) {
- if (obj1.hasProperty(WORN)) {
- _vm->renderMessage("Die Luft hier ist atembar,|du ziehst den Anzug aus.");
- _rooms[AIRLOCK].getObject(4)->disableProperty(WORN);
- _rooms[AIRLOCK].getObject(5)->disableProperty(WORN);
- _rooms[AIRLOCK].getObject(6)->disableProperty(WORN);
- } else
- _vm->renderMessage("Hier drinnen brauchtst du deinen Anzug nicht.");
- } else {
- if (obj1.hasProperty(WORN)) {
- r = &_rooms[AIRLOCK];
- if (r->getObject(4)->hasProperty(WORN)) {
- _vm->renderMessage("Du muát erst den Helm abnehmen.");
- } else if (r->getObject(6)->hasProperty(WORN)) {
- _vm->renderMessage("Du muát erst den Versorgungsteil abnehmen.");
- } else {
- obj1.disableProperty(WORN);
- _vm->renderMessage("Du ziehst den Raumanzug aus.");
- }
- } else {
- obj1.setProperty(WORN);
- _vm->renderMessage("Du ziehst den Raumanzug an.");
- }
- }
- } else if ((verb == ACTION_USE) && (obj1._id == HELMET)) {
- takeObject(obj1);
- if ((_currentRoom >= &_rooms[ENTRANCE]) && (_currentRoom <= &_rooms[ROGER])) {
- if (obj1.hasProperty(WORN)) {
- _vm->renderMessage("Die Luft hier ist atembar,|du ziehst den Anzug aus.");
- _rooms[AIRLOCK].getObject(4)->disableProperty(WORN);
- _rooms[AIRLOCK].getObject(5)->disableProperty(WORN);
- _rooms[AIRLOCK].getObject(6)->disableProperty(WORN);
- } else {
- _vm->renderMessage("Hier drinnen brauchtst du deinen Anzug nicht.");
- }
- } else {
- if (obj1.hasProperty(WORN)) {
- if (airless()) {
- //TODO: Death screen
-// longjmp(dead, "Den Helm h„ttest du|besser angelassen!");
- }
- obj1.disableProperty(WORN);
- _vm->renderMessage("Du ziehst den Helm ab.");
- } else {
- r = &_rooms[AIRLOCK];
- if (r->getObject(5)->hasProperty(WORN)) {
- obj1.setProperty(WORN);
- _vm->renderMessage("Du ziehst den Helm auf.");
- } else {
- _vm->renderMessage("Du muát erst den Anzug anziehen.");
- }
- }
- }
- } else if ((verb == ACTION_USE) && (obj1._id == LIFESUPPORT)) {
- takeObject(obj1);
- if ((_currentRoom >= &_rooms[ENTRANCE]) && (_currentRoom <= &_rooms[ROGER])) {
- if (obj1.hasProperty(WORN)) {
- _vm->renderMessage("Die Luft hier ist atembar,|du ziehst den Anzug aus.");
- _rooms[AIRLOCK].getObject(4)->disableProperty(WORN);
- _rooms[AIRLOCK].getObject(5)->disableProperty(WORN);
- _rooms[AIRLOCK].getObject(6)->disableProperty(WORN);
- } else
- _vm->renderMessage("Hier drinnen brauchtst du deinen Anzug nicht.");
- } else {
- if (obj1.hasProperty(WORN)) {
- if (airless()) {
- //TODO: Death screen
-// longjmp(dead, "Den Versorungsteil h„ttest du|besser nicht abgenommen!");
- }
- obj1.disableProperty(WORN);
- _vm->renderMessage("Du nimmst den Versorgungsteil ab.");
- } else {
- r = &_rooms[AIRLOCK];
- if (r->getObject(5)->hasProperty(WORN)) {
- obj1.setProperty(WORN);
- _vm->renderMessage("Du ziehst den Versorgungsteil an.");
- } else {
- _vm->renderMessage("Du muát erst den Anzug anziehen.");
- }
- }
- }
- } else if ((verb == ACTION_WALK) && (obj1._id == BATHROOM_DOOR)) {
-// *bathroom = current_room;
- return false;
- } else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, WIRE, SOCKET))
- _vm->renderMessage("Die Leitung ist hier unntz.");
- else if ((verb == ACTION_LOOK) && (obj1._id == BOOK2)) {
- _vm->renderMessage("Stark, das ist ja die Fortsetzung zum \"Anhalter\":|\"Das Restaurant am Ende des Universums\".");
- mouseWait(_timer1);
- _vm->removeMessage();
- _vm->renderMessage("Moment mal, es ist ein Lesezeichen drin,|auf dem \"Zweiundvierzig\" steht.");
- } else {
- return false;
- }
-
- return true;
-}
-
-void GameManager::executeRoom() {
- bool validCommand = genericInteract(_inputVerb, _inputObject[0], _inputObject[1]);
-
- if (!validCommand) {
- validCommand = _currentRoom->interact(_inputVerb, _inputObject[0], _inputObject[1]);
- if (!validCommand) {
- switch (_inputVerb) {
- case ACTION_LOOK:
- _vm->renderMessage(_inputObject[0]._description);
- break;
-
- case ACTION_WALK:
- if (_inputObject[0].hasProperty(CARRIED)) {
- // You already carry this.
- _vm->renderMessage("Das tr„gst du doch bei dir.");
- } else if (!_inputObject[0].hasProperty(EXIT)) {
- // You're already there.
- _vm->renderMessage("Du bist doch schon da.");
- } else if (_inputObject[0].hasProperty(OPEN) && !_inputObject[0].hasProperty(OPENED)) {
- // This is closed
- _vm->renderMessage("Das ist geschlossen.");
- } else {
- _currentRoom = &_rooms[_inputObject[0]._exitRoom];
- return;
- }
- break;
-
- case ACTION_TAKE:
- if (_inputObject[0].hasProperty(OPENED)) {
- // You already have that
- _vm->renderMessage("Das hast du doch schon.");
- } else if (_inputObject[0].hasProperty(UNNECESSARY)) {
- // You do not need that.
- _vm->renderMessage("Das brauchst du nicht.");
- } else if (!_inputObject[0].hasProperty(TAKE)) {
- // You can't take that.
- _vm->renderMessage("Das kannst du nicht nehmen.");
- } else {
- takeObject(_inputObject[0]);
- }
- break;
-
- case ACTION_OPEN:
- if (!_inputObject[0].hasProperty(OPEN)) {
- // This can't be opened
- _vm->renderMessage("Das l„át sich nicht ”ffnen.");
- } else if (_inputObject[0].hasProperty(OPENED)) {
- // This is already opened.
- _vm->renderMessage("Das ist schon offen.");
- } else if (_inputObject[0].hasProperty(CLOSED)) {
- // This is locked.
- _vm->renderMessage("Das ist verschlossen.");
- } else {
- _vm->renderImage(_currentRoom->getFileNumber(), _inputObject[0]._section);
- _inputObject[0].setProperty(OPENED);
- byte i = _inputObject[0]._click;
- _inputObject[0]._click = _inputObject[0]._click2;
- _inputObject[0]._click2 = i;
- _vm->playSound(kAudioDoorOpen);
- }
- break;
-
- case ACTION_CLOSE:
- if (!_inputObject[0].hasProperty(OPEN) ||
- (_inputObject[0].hasProperty(CLOSED) &&
- _inputObject[0].hasProperty(OPENED))) {
- // This can't be closed.
- _vm->renderMessage("Das l„át sich nicht schlieáen.");
- } else if (!_inputObject[0].hasProperty(OPENED)) {
- // This is already closed.
- _vm->renderMessage("Das ist schon geschlossen.");
- } else {
- _vm->renderImage(_currentRoom->getFileNumber(), invertSection(_inputObject[0]._section));
- _inputObject[0].disableProperty(OPENED);
- byte i = _inputObject[0]._click;
- _inputObject[0]._click = _inputObject[0]._click2;
- _inputObject[0]._click2 = i;
- _vm->playSound(kAudioDoorClose);
- }
- break;
-
- case ACTION_GIVE:
- if (_inputObject[0].hasProperty(CARRIED)) {
- // Better keep it!
- _vm->renderMessage("Behalt es lieber!");
- }
- break;
-
- default:
- // This is not possible.
- _vm->renderMessage("Das geht nicht.");
- }
-
- if (_newOverlay) {
- loadOverlayStart();
- _newOverlay = false;
- }
- if (_newRoom) {
- _newRoom = false;
- return;
- }
- }
- }
-}
-
Common::MemoryReadStream *SupernovaEngine::convertToMod(const char *filename, int version) {
// MSN format
struct {
@@ -1417,4 +733,45 @@ Common::MemoryReadStream *SupernovaEngine::convertToMod(const char *filename, in
return new Common::MemoryReadStream(buffer.getData(), buffer.size());
}
+
+ScreenBufferStack::ScreenBufferStack()
+ : _last(_buffer) {
+}
+
+void ScreenBufferStack::push(int x, int y, int width, int height, int pitch) {
+ if (_last == ARRAYEND(_buffer))
+ return;
+
+ _last->_pixels = new byte[width * height];
+ byte *pixels = _last->_pixels;
+ const byte *screen = static_cast<const byte *>(g_system->lockScreen()->getBasePtr(x, y));
+ for (int i = 0; i < height; ++i) {
+ Common::copy(screen, screen + width, pixels);
+ screen += pitch;
+ pixels += width;
+ }
+ g_system->unlockScreen();
+
+ _last->_x = x;
+ _last->_y = y;
+ _last->_width = width;
+ _last->_height = height;
+ _last->_pitch = pitch;
+
+ ++_last;
+}
+
+void ScreenBufferStack::restore() {
+ if (_last == _buffer)
+ return;
+
+ --_last;
+ g_system->lockScreen()->copyRectToSurface(
+ _last->_pixels, _last->_width, _last->_x, _last->_y,
+ _last->_width, _last->_height);
+ g_system->unlockScreen();
+
+ delete[] _last->_pixels;
+}
+
}
diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h
index 78e9f72142..1d3b17cd36 100644
--- a/engines/supernova/supernova.h
+++ b/engines/supernova/supernova.h
@@ -107,6 +107,7 @@ public:
int _textColor;
int getDOSTicks();
+ int characterWidth(const char *text);
void initData();
void initPalette();
void paletteFadeIn();
@@ -127,84 +128,11 @@ public:
void renderText(const char *text);
void renderBox(int x, int y, int width, int height, byte color);
void setColor63(byte value);
+ void command_print();
Common::MemoryReadStream *convertToMod(const char *filename, int version = 1);
};
-
-class Inventory {
-public:
- Inventory();
-
- void add(Object &obj);
- void remove(Object &obj);
- Object *get(uint index) const;
- Object *get(ObjectID id) const;
-
-private:
- Object *_inventory[kMaxCarry];
- uint _numObjects;
-};
-
-class GameManager {
-public:
- GameManager(SupernovaEngine *vm, Common::Event *event);
-
- void processInput();
- void executeRoom();
-
- SupernovaEngine *_vm;
- Common::Event *_event;
- uint16 _key;
- Room *_currentRoom;
- Room _rooms[kRoomsNum];
- Inventory _inventory;
- GameState _state;
- int _status;
- Action _inputVerb;
- Object _inputObject[2];
- bool _waitEvent;
- bool _newRoom;
- bool _newOverlay;
- int _timer1;
- int _timer2;
- // 0 PC Speaker | 1 SoundBlaster | 2 No Sound
- int _soundDevice;
-
- void takeObject(Object &obj);
-
- bool genericInteract(Action verb, Object &obj1, Object &obj2);
- bool isHelmetOff();
- void great(uint number);
- bool airless();
- void shock();
- void mouseInput();
- void mouseInput2();
- void mouseInput3();
- void mouseWait(int delay);
- void wait2(int delay);
- void turnOff();
- void turnOn();
- void screenShake();
- void loadTime();
- void saveTime();
- bool saveGame(int number);
- void errorTemp();
- void roomBrightness();
- void palette();
- void showMenu();
- void drawMapExits();
- void animationOff();
- void animationOn();
- void loadOverlayStart();
- void openLocker(const Room *room, Object *obj, Object *lock, int section);
- void closeLocker(const Room *room, Object *obj, Object *lock, int section);
- void edit(char *text, int x, int y, int length);
- int invertSection(int section);
- void command_print();
-};
-
-
}
#endif