aboutsummaryrefslogtreecommitdiff
path: root/engines/tsage/ringworld2/ringworld2_logic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/tsage/ringworld2/ringworld2_logic.cpp')
-rw-r--r--engines/tsage/ringworld2/ringworld2_logic.cpp661
1 files changed, 598 insertions, 63 deletions
diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp
index ebb09a7e08..c0fc2eb766 100644
--- a/engines/tsage/ringworld2/ringworld2_logic.cpp
+++ b/engines/tsage/ringworld2/ringworld2_logic.cpp
@@ -88,8 +88,10 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Walking in hall
return new Scene525();
case 600:
+ // Drive Room
return new Scene600();
case 700:
+ // Lander Bay 2
return new Scene700();
case 800:
// Sick bay
@@ -101,11 +103,13 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Deck #5 - By Lift
return new Scene850();
case 900:
+ // Lander Bay 2 - Crane Controls
return new Scene900();
/* Scene group #1 */
//
case 1000:
- error("Missing scene %d from group 1", sceneNumber);
+ // Cutscene scene
+ return new Scene1000();
case 1010:
// Cutscene - trip in space
return new Scene1010();
@@ -129,6 +133,7 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Cutscene - Elevator
return new Scene1530();
case 1550:
+ // Spaceport
return new Scene1550();
case 1575:
return new Scene1575();
@@ -139,10 +144,13 @@ Scene *Ringworld2Game::createScene(int sceneNumber) {
// Miranda being questioned
return new Scene1625();
case 1700:
+ // Rim
return new Scene1700();
case 1750:
+ // Rim Transport Vechile
return new Scene1750();
case 1800:
+ // Rim Lift Exterior
return new Scene1800();
case 1850:
return new Scene1850();
@@ -314,11 +322,23 @@ SceneExt::SceneExt(): Scene() {
for (int i = 0; i < 256; i++)
_field312[i] = 0;
- _field372 = _field37A = 0;
+
_savedPlayerEnabled = false;
_savedUiEnabled = false;
_savedCanWalk = false;
- _focusObject = NULL;
+
+ // WORKAROUND: In the original, playing animations don't reset the global _animationCtr
+ // counter as scene changes unless the playing animation explicitly finishes. For now,
+ // to make inter-scene debugging easier, I'm explicitly resetting the _animationCtr
+ // on scene start, since scene objects aren't drawn while it's non-zero
+ R2_GLOBALS._animationCtr = 0;
+}
+
+void SceneExt::synchronize(Serializer &s) {
+ Scene::synchronize(s);
+
+ s.syncBytes(&_field312[0], 256);
+ _sceneAreas.synchronize(s);
}
void SceneExt::postInit(SceneObjectList *OwnerList) {
@@ -327,7 +347,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
// Exclude the bottom area of the screen to allow room for the UI
T2_GLOBALS._interfaceY = UI_INTERFACE_Y;
- // Initialise fields
+ // Initialize fields
_action = NULL;
_field12 = 0;
_sceneMode = 0;
@@ -336,8 +356,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50))
|| (sceneNumber == 50)
- || ((prevScene == 205) && (sceneNumber == 100))
- || ((prevScene == 180) && (sceneNumber == 100))) {
+ || ((sceneNumber == 100) && (prevScene == 0 || prevScene == 180 || prevScene == 205))) {
static_cast<SceneHandlerExt *>(R2_GLOBALS._sceneHandler)->setupPaletteMaps();
R2_GLOBALS._uiElements._active = true;
R2_GLOBALS._uiElements.show();
@@ -349,6 +368,7 @@ void SceneExt::postInit(SceneObjectList *OwnerList) {
void SceneExt::remove() {
_sceneAreas.clear();
Scene::remove();
+ R2_GLOBALS._uiElements._active = true;
}
void SceneExt::process(Event &event) {
@@ -373,27 +393,6 @@ void SceneExt::dispatch() {
Scene::dispatch();
}
-void SceneExt::loadScene(int sceneNum) {
- Scene::loadScene(sceneNum);
-
- _v51C34.top = 0;
- _v51C34.bottom = 300;
-
- int prevScene = R2_GLOBALS._sceneManager._previousScene;
- int sceneNumber = R2_GLOBALS._sceneManager._sceneNumber;
-
- if (((prevScene == -1) && (sceneNumber != 180) && (sceneNumber != 205) && (sceneNumber != 50)) ||
- (sceneNumber == 50) || ((prevScene == 205) && (sceneNumber == 100)) ||
- ((prevScene == 180) && (sceneNumber == 100))) {
- // TODO: sub_17875
- R2_GLOBALS._uiElements._active = true;
- R2_GLOBALS._uiElements.show();
- } else {
- // Update the user interface
- R2_GLOBALS._uiElements.updateInventory();
- }
-}
-
bool SceneExt::display(CursorType action, Event &event) {
switch (action) {
case CURSOR_CROSSHAIRS:
@@ -415,17 +414,19 @@ bool SceneExt::display(CursorType action, Event &event) {
SceneItem::display2(5, 0);
break;
case R2_SONIC_STUNNER:
- if ((R2_GLOBALS._v565F1[1] == 2) || ((R2_GLOBALS._v565F1[1] == 1) &&
- (R2_GLOBALS._v565F1[2] == 2) && (R2_GLOBALS._sceneManager._previousScene == 300))) {
+ if ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 2)
+ || ((R2_GLOBALS._scannerFrequencies[R2_QUINN] == 1) &&
+ (R2_GLOBALS._scannerFrequencies[R2_SEEKER] == 2) &&
+ (R2_GLOBALS._sceneManager._previousScene == 300))) {
R2_GLOBALS._sound4.stop();
R2_GLOBALS._sound3.play(46);
SceneItem::display2(5, 15);
+
+ R2_GLOBALS._sound4.play(45);
} else {
R2_GLOBALS._sound3.play(43, 0);
- SceneItem::display2(2, 0);
+ SceneItem::display2(2, R2_SONIC_STUNNER);
}
-
- R2_GLOBALS._sound4.play(45);
break;
case R2_COM_SCANNER:
case R2_COM_SCANNER_2:
@@ -453,7 +454,6 @@ void SceneExt::fadeOut() {
void SceneExt::startStrip() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
- scene->_field372 = 1;
scene->_savedPlayerEnabled = R2_GLOBALS._player._enabled;
if (scene->_savedPlayerEnabled) {
@@ -469,7 +469,6 @@ void SceneExt::startStrip() {
void SceneExt::endStrip() {
SceneExt *scene = (SceneExt *)R2_GLOBALS._sceneManager._scene;
- scene->_field372 = 0;
if (scene->_savedPlayerEnabled) {
R2_GLOBALS._player.enableControl();
@@ -517,7 +516,7 @@ void SceneExt::refreshBackground(int xAmount, int yAmount) {
assert(screenSize == (s.w * s.h));
// Copy the data
- byte *destP = (byte *)s.getBasePtr(0, 0);
+ byte *destP = (byte *)s.getPixels();
Common::copy(dataP, dataP + (s.w * s.h), destP);
_backSurface.unlockSurface();
@@ -565,6 +564,13 @@ void SceneExt::scalePalette(int RFactor, int GFactor, int BFactor) {
}
}
+void SceneExt::loadBlankScene() {
+ _backSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT * 3 / 2);
+ _backSurface.fillRect(_backSurface.getBounds(), 0);
+
+ R2_GLOBALS._screenSurface.fillRect(R2_GLOBALS._screenSurface.getBounds(), 0);
+}
+
/*--------------------------------------------------------------------------*/
void SceneHandlerExt::postInit(SceneObjectList *OwnerList) {
@@ -581,7 +587,7 @@ void SceneHandlerExt::process(Event &event) {
SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene);
if (scene && R2_GLOBALS._player._uiEnabled) {
// Handle any scene areas that have been registered
- SynchronizedList<SceneArea *>::iterator saIter;
+ SynchronizedList<EventHandler *>::iterator saIter;
for (saIter = scene->_sceneAreas.begin(); saIter != scene->_sceneAreas.end() && !event.handled; ++saIter) {
(*saIter)->process(event);
}
@@ -591,11 +597,32 @@ void SceneHandlerExt::process(Event &event) {
SceneHandler::process(event);
}
+void SceneHandlerExt::postLoad(int priorSceneBeforeLoad, int currentSceneBeforeLoad) {
+ if (priorSceneBeforeLoad == -1 || priorSceneBeforeLoad == 50
+ || priorSceneBeforeLoad == 180 || priorSceneBeforeLoad == 205)
+ setupPaletteMaps();
+
+ if (currentSceneBeforeLoad == 2900) {
+ R2_GLOBALS._gfxFontNumber = 50;
+ R2_GLOBALS._gfxColors.background = 0;
+ R2_GLOBALS._gfxColors.foreground = 59;
+ R2_GLOBALS._fontColors.background = 4;
+ R2_GLOBALS._fontColors.foreground = 15;
+ R2_GLOBALS._frameEdgeColor = 2;
+
+ R2_GLOBALS._scenePalette.loadPalette(0);
+ R2_GLOBALS._scenePalette.setEntry(255, 0xff, 0xff, 0xff);
+ R2_GLOBALS._fadePaletteFlag = false;
+ setupPaletteMaps();
+ }
+}
+
void SceneHandlerExt::setupPaletteMaps() {
byte *palP = &R2_GLOBALS._scenePalette._palette[0];
- if (!R2_GLOBALS._v1000Flag) {
- R2_GLOBALS._v1000Flag = true;
+ // Set up the mapping table for giving faded versions of pixels at different fade percentages
+ if (!R2_GLOBALS._fadePaletteFlag) {
+ R2_GLOBALS._fadePaletteFlag = true;
for (int idx = 0; idx < 10; ++idx) {
for (int palIndex = 0; palIndex < 224; ++palIndex) {
@@ -625,7 +652,7 @@ void SceneHandlerExt::setupPaletteMaps() {
break;
}
- // Scan for the palette index with the closest matching colour
+ // Scan for the palette index with the closest matching color
int threshold = 769;
int foundIndex = -1;
for (int pIndex2 = 223; pIndex2 >= 0; --pIndex2) {
@@ -645,18 +672,19 @@ void SceneHandlerExt::setupPaletteMaps() {
foundIndex = pIndex2;
}
- R2_GLOBALS._palIndexList[idx][palIndex] = foundIndex;
+ R2_GLOBALS._fadePaletteMap[idx][palIndex] = foundIndex;
}
}
}
for (int palIndex = 0; palIndex < 224; ++palIndex) {
- int r = palP[palIndex * 3] >> 2;
- int g = palP[palIndex * 3 + 1] >> 2;
- int b = palP[palIndex * 3 + 2] >> 2;
+ int r = palP[palIndex * 3] >> 4;
+ int g = palP[palIndex * 3 + 1] >> 4;
+ int b = palP[palIndex * 3 + 2] >> 4;
- int idx = (((r << 4) | g) << 4) | b;
- R2_GLOBALS._v1000[idx] = palIndex;
+ int v = (r << 8) | (g << 4) | b;
+ assert(v < 0x1000);
+ R2_GLOBALS._paletteMap[v] = palIndex;
}
int vdx = 0;
@@ -664,9 +692,9 @@ void SceneHandlerExt::setupPaletteMaps() {
int palIndex = 224;
for (int vIndex = 0; vIndex < 4096; ++vIndex) {
- int v = R2_GLOBALS._v1000[vIndex];
+ int v = R2_GLOBALS._paletteMap[vIndex];
if (!v) {
- R2_GLOBALS._v1000[vIndex] = idx;
+ R2_GLOBALS._paletteMap[vIndex] = idx;
} else {
idx = v;
}
@@ -850,6 +878,7 @@ Ringworld2InvObjectList::Ringworld2InvObjectList():
_itemList.push_back(&_inv52);
_selectedItem = NULL;
+
}
void Ringworld2InvObjectList::reset() {
@@ -912,6 +941,9 @@ void Ringworld2InvObjectList::reset() {
setObjectScene(R2_ALCOHOL_LAMP_3, 2435);
setObjectScene(R2_BROKEN_DISPLAY, 1580);
setObjectScene(R2_TOOLBOX, 3260);
+
+ // Set up the select item handler method
+ T2_GLOBALS._onSelectItem = SelectItem;
}
void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) {
@@ -926,7 +958,129 @@ void Ringworld2InvObjectList::setObjectScene(int objectNum, int sceneNumber) {
R2_GLOBALS._events.setCursor(CURSOR_USE);
// Update the user interface if necessary
- T2_GLOBALS._uiElements.updateInventory();
+ T2_GLOBALS._uiElements.updateInventory(
+ (sceneNumber == R2_GLOBALS._player._characterIndex) ? objectNum : 0);
+}
+
+/**
+ * When an inventory item is selected, in Return to Ringworld two objects can be combined
+ */
+bool Ringworld2InvObjectList::SelectItem(int objectNumber) {
+ // If no existing item selected, don't go any further
+ int currentItem = R2_GLOBALS._events.getCursor();
+ if (currentItem >= 256)
+ return false;
+
+ switch (objectNumber) {
+ case R2_NEGATOR_GUN:
+ switch (currentItem) {
+ case R2_SENSOR_PROBE:
+ if (R2_GLOBALS.getFlag(1))
+ SceneItem::display2(5, 1);
+ else if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) != 100)
+ SceneItem::display2(5, 3);
+ else {
+ R2_GLOBALS._sound3.play(48);
+ SceneItem::display2(5, 2);
+ R2_INVENTORY.setObjectScene(R2_SPENT_POWER_CAPSULE, 1);
+ }
+ break;
+ case R2_COM_SCANNER:
+ R2_GLOBALS._sound3.play(44);
+ if (R2_GLOBALS.getFlag(1))
+ SceneItem::display2(5, 9);
+ else if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) == 100)
+ SceneItem::display2(5, 8);
+ else
+ SceneItem::display2(5, 10);
+
+ R2_GLOBALS._sound3.stop();
+ break;
+ case R2_CHARGED_POWER_CAPSULE:
+ if (R2_INVENTORY.getObjectScene(R2_SPENT_POWER_CAPSULE) == 1) {
+ R2_GLOBALS._sound3.play(49);
+ R2_INVENTORY.setObjectScene(R2_CHARGED_POWER_CAPSULE, 100);
+ R2_GLOBALS.setFlag(1);
+ SceneItem::display2(5, 4);
+ } else {
+ SceneItem::display2(5, 5);
+ }
+ break;
+ default:
+ selectDefault(objectNumber);
+ break;
+ }
+ break;
+ case R2_STEPPING_DISKS:
+ switch (currentItem) {
+ case R2_SENSOR_PROBE:
+ if (R2_INVENTORY.getObjectScene(R2_CHARGED_POWER_CAPSULE) == 400) {
+ R2_GLOBALS._sound3.play(48);
+ SceneItem::display2(5, 6);
+ R2_INVENTORY.setObjectScene(R2_CHARGED_POWER_CAPSULE, 1);
+ } else {
+ SceneItem::display2(5, 7);
+ }
+ break;
+ case R2_COM_SCANNER:
+ R2_GLOBALS._sound3.play(44);
+ if (R2_INVENTORY.getObjectScene(R2_CHARGED_POWER_CAPSULE) == 400)
+ SceneItem::display2(5, 16);
+ else
+ SceneItem::display2(5, 17);
+ R2_GLOBALS._sound3.stop();
+ break;
+ default:
+ selectDefault(objectNumber);
+ break;
+ }
+ break;
+ case R2_ATTRACTOR_UNIT:
+ case R2_CABLE_HARNESS:
+ if (currentItem == R2_CABLE_HARNESS ||
+ currentItem == R2_ATTRACTOR_UNIT) {
+ R2_INVENTORY.setObjectScene(R2_CABLE_HARNESS, 0);
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_UNIT, 0);
+ R2_INVENTORY.setObjectScene(R2_ATTRACTOR_CABLE_HARNESS, 1);
+ } else {
+ selectDefault(objectNumber);
+ }
+ break;
+ case R2_TANNER_MASK:
+ case R2_PURE_GRAIN_ALCOHOL:
+ if (currentItem == R2_TANNER_MASK ||
+ currentItem == R2_PURE_GRAIN_ALCOHOL) {
+ R2_INVENTORY.setObjectScene(R2_TANNER_MASK, 0);
+ R2_INVENTORY.setObjectScene(R2_PURE_GRAIN_ALCOHOL, 0);
+ R2_INVENTORY.setObjectScene(R2_SOAKED_FACEMASK, 1);
+ } else {
+ selectDefault(objectNumber);
+ }
+ break;
+ default:
+ // Standard item selection
+ return false;
+ }
+
+ return true;
+}
+
+void Ringworld2InvObjectList::selectDefault(int objectNumber) {
+ Common::String msg1 = g_resourceManager->getMessage(4, 53);
+ Common::String msg2 = g_resourceManager->getMessage(4, R2_GLOBALS._events.getCursor());
+ Common::String msg3 = g_resourceManager->getMessage(4, 54);
+ Common::String msg4 = g_resourceManager->getMessage(4, objectNumber);
+ Common::String line = Common::String::format("%.5s%.5s%.5s%.5s%s %s %s %s.",
+ msg1.c_str(), msg2.c_str(), msg3.c_str(), msg4.c_str(),
+ msg1.c_str() + 5, msg2.c_str() + 5, msg3.c_str() + 5, msg4.c_str() + 5);
+
+ SceneItem::display(-1, -1, line.c_str(),
+ SET_WIDTH, 280,
+ SET_X, 160,
+ SET_Y, 20,
+ SET_POS_MODE, 1,
+ SET_EXT_BGCOLOR, 7,
+ LIST_END);
}
/*--------------------------------------------------------------------------*/
@@ -1091,6 +1245,14 @@ void SceneActor::postInit(SceneObjectList *OwnerList) {
SceneObject::postInit();
}
+void SceneActor::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
+ _field9C = NULL;
+ _linkedActor = NULL;
+
+ SceneObject::remove();
+}
+
bool SceneActor::startAction(CursorType action, Event &event) {
bool handled = true;
@@ -1123,9 +1285,35 @@ bool SceneActor::startAction(CursorType action, Event &event) {
return handled;
}
+GfxSurface SceneActor::getFrame() {
+ GfxSurface frame = SceneObject::getFrame();
+
+ // TODO: Proper effects handling
+ switch (_effect) {
+ case 0:
+ case 5:
+ // TODO: Figure out purpose of setting image flags to 64, and getting
+ // scene priorities -1 or _shade
+ break;
+ case 1:
+ // TODO: Transposing using R2_GLOBALS._pixelArrayMap
+ break;
+ case 2:
+ // No effect
+ break;
+ case 4:
+ break;
+ default:
+ // TODO: Default effect
+ break;
+ }
+
+ return frame;
+}
+
/*--------------------------------------------------------------------------*/
-SceneArea::SceneArea(): EventHandler() {
+SceneArea::SceneArea(): SceneItem() {
_enabled = true;
_insideArea = false;
_savedCursorNum = CURSOR_NONE;
@@ -1138,8 +1326,8 @@ void SceneArea::synchronize(Serializer &s) {
_bounds.synchronize(s);
s.syncAsSint16LE(_enabled);
s.syncAsSint16LE(_insideArea);
- s.syncAsSint16LE(_cursorNum);
- s.syncAsSint16LE(_savedCursorNum);
+ s.syncAsSint32LE(_cursorNum);
+ s.syncAsSint32LE(_savedCursorNum);
s.syncAsSint16LE(_cursorState);
}
@@ -1229,6 +1417,7 @@ void SceneExit::process(Event &event) {
/*--------------------------------------------------------------------------*/
void SceneAreaObject::remove() {
+ R2_GLOBALS._sceneItems.remove(this);
_object1.remove();
SceneArea::remove();
--R2_GLOBALS._insetUp;
@@ -1238,19 +1427,22 @@ void SceneAreaObject::process(Event &event) {
if (_insetCount == R2_GLOBALS._insetUp) {
CursorType cursor = R2_GLOBALS._events.getCursor();
- if (_bounds.contains(event.mousePos)) {
+ if (_object1._bounds.contains(event.mousePos)) {
// Cursor moving in bounded area
if (cursor == _cursorNum) {
R2_GLOBALS._events.setCursor(_savedCursorNum);
}
} else if (event.mousePos.y < 168) {
- if (_cursorNum != cursor)
+ if (_cursorNum != cursor) {
// Cursor moved outside bounded area
- R2_GLOBALS._events.setCursor(_savedCursorNum);
-
+ _savedCursorNum = R2_GLOBALS._events.getCursor();
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+
if (event.eventType == EVENT_BUTTON_DOWN) {
- R2_GLOBALS._events.setCursor(_savedCursorNum);
event.handled = true;
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ remove();
}
}
}
@@ -1270,7 +1462,7 @@ void SceneAreaObject::setDetails(int visage, int strip, int frameNumber, const C
}
void SceneAreaObject::setDetails(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
- ((SceneHotspot *)(this))->setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
+ _object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum,
2, (SceneItem *)NULL);
}
@@ -1341,7 +1533,7 @@ void MazeUI::clear() {
if (_mapData)
DEALLOCATE(_mapData);
_mapData = NULL;
-
+
_mapImage.clear();
}
@@ -1387,7 +1579,7 @@ void MazeUI::draw() {
// Loop to handle the cell rows of the visible display area one at a time
for (int yCtr = 0; yCtr < _cellsVisible.y; ++yCtr, yPos += ySize) {
int cellY = _mapOffset.y / _cellSize.y + yCtr;
-
+
// Loop to iterate through the horizontal visible cells to build up
// an entire cell high horizontal slice of the map
for (int xCtr = 0; xCtr < _cellsVisible.x; ++xCtr) {
@@ -1398,7 +1590,7 @@ void MazeUI::draw() {
if (cell >= 0) {
int frameNum = (cell % _frameCount) + 1;
int rlbNum = (cell % _resCount) / _frameCount + 1;
- int resNum = _cellsResNum + (cell / _resCount);
+ int resNum = _cellsResNum + (cell / _resCount);
visage.setVisage(resNum, rlbNum);
GfxSurface frame = visage.getFrame(frameNum);
@@ -1416,7 +1608,7 @@ void MazeUI::draw() {
// First line of the map to be displayed - only the bottom portion of that
// first cell row may be visible
yPos = _bounds.top;
- ySize = _cellSize.y - (_mapOffset.y % _cellSize.y);
+ ySize = _cellSize.y - (_mapOffset.y % _cellSize.y);
Rect srcBounds(_mapOffset.x % _cellSize.x, _mapOffset.y % _cellSize.y,
(_mapOffset.x % _cellSize.x) + _bounds.width(), _cellSize.y);
@@ -1564,7 +1756,7 @@ AnimationPlayer::~AnimationPlayer() {
void AnimationPlayer::synchronize(Serializer &s) {
EventHandler::synchronize(s);
- warning("TODO AnimationPlayer::load");
+ warning("TODO AnimationPlayer::synchronize");
}
void AnimationPlayer::remove() {
@@ -1682,7 +1874,7 @@ bool AnimationPlayer::load(int animId, Action *endAction) {
default:
// ANIMPALMODE_CURR_PALETTE
- // Use the closest matching colours in the currently active palette to those specified in the animation
+ // Use the closest matching colors in the currently active palette to those specified in the animation
for (int idx = _subData._palStart; idx < (_subData._palStart + _subData._palSize); ++idx) {
byte r = _subData._palData[idx * 3];
byte g = _subData._palData[idx * 3 + 1];
@@ -1928,6 +2120,349 @@ void AnimationPlayerExt::synchronize(Serializer &s) {
s.syncAsSint16LE(_v);
}
+/*--------------------------------------------------------------------------*/
+
+ModalWindow::ModalWindow() {
+ _field20 = 0;
+}
+
+void ModalWindow::remove() {
+ R2_GLOBALS._sceneItems.remove(&_object1);
+ _object1.remove();
+
+ SceneArea::remove();
+
+ --R2_GLOBALS._insetUp;
+}
+
+void ModalWindow::synchronize(Serializer &s) {
+ SceneArea::synchronize(s);
+
+ s.syncAsByte(_field20);
+}
+
+void ModalWindow::process(Event &event) {
+ if (_field20 != R2_GLOBALS._insetUp)
+ return;
+
+ CursorType cursor = R2_GLOBALS._events.getCursor();
+
+ if (_object1._bounds.contains(event.mousePos.x + g_globals->gfxManager()._bounds.left , event.mousePos.y)) {
+ if (cursor == _cursorNum) {
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ }
+ } else if (event.mousePos.y < 168) {
+ if (cursor != _cursorNum) {
+ _savedCursorNum = cursor;
+ R2_GLOBALS._events.setCursor(CURSOR_INVALID);
+ }
+ if (event.eventType == EVENT_BUTTON_DOWN) {
+ event.handled = true;
+ R2_GLOBALS._events.setCursor(_savedCursorNum);
+ remove();
+ }
+ }
+}
+
+void ModalWindow::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ Scene1200 *scene = (Scene1200 *)R2_GLOBALS._sceneManager._scene;
+
+ _object1.postInit();
+ _object1.setup(visage, stripFrameNum, frameNum);
+ _object1.setPosition(Common::Point(posX, posY));
+ _object1.fixPriority(250);
+ _cursorNum = CURSOR_INVALID;
+ scene->_sceneAreas.push_front(this);
+ ++R2_GLOBALS._insetUp;
+ _field20 = R2_GLOBALS._insetUp;
+}
+
+void ModalWindow::proc13(int resNum, int lookLineNum, int talkLineNum, int useLineNum) {
+ _object1.setDetails(resNum, lookLineNum, talkLineNum, useLineNum, 2, (SceneItem *) NULL);
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScannerDialog::Button::Button() {
+ _buttonId = 0;
+ _buttonDown = false;
+}
+
+void ScannerDialog::Button::setup(int buttonId) {
+ _buttonId = buttonId;
+ _buttonDown = false;
+ SceneActor::postInit();
+
+ SceneObject::setup(4, 2, 2);
+ fixPriority(255);
+
+ if (_buttonId == 1)
+ setPosition(Common::Point(141, 99));
+ else if (_buttonId == 2)
+ setPosition(Common::Point(141, 108));
+
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this);
+}
+
+void ScannerDialog::Button::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+ s.syncAsSint16LE(_buttonId);
+}
+
+void ScannerDialog::Button::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN && R2_GLOBALS._events.getCursor() == CURSOR_USE
+ && _bounds.contains(event.mousePos) && !_buttonDown) {
+ setFrame(3);
+ _buttonDown = true;
+ event.handled = true;
+ }
+
+ if (event.eventType == EVENT_BUTTON_UP && _buttonDown) {
+ setFrame(2);
+ _buttonDown = false;
+ event.handled = true;
+
+ reset();
+ }
+}
+
+bool ScannerDialog::Button::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+
+ return startAction(action, event);
+}
+
+void ScannerDialog::Button::reset() {
+ Scene *scene = R2_GLOBALS._sceneManager._scene;
+ ScannerDialog &scanner = *R2_GLOBALS._scannerDialog;
+
+ switch (_buttonId) {
+ case 1:
+ // Talk button
+ switch (R2_GLOBALS._sceneManager._sceneNumber) {
+ case 1550:
+ scene->_sceneMode = 80;
+ scene->signal();
+ break;
+ case 1700:
+ scene->_sceneMode = 30;
+ scene->signal();
+ remove();
+ break;
+ default:
+ break;
+ }
+ break;
+ case 2:
+ // Scan button
+ switch (R2_GLOBALS._sceneManager._sceneNumber) {
+ case 1550:
+ scanner._obj4.setup(4, 3, 1);
+
+ scanner._obj5.postInit();
+ scanner._obj5.setup(4, 4, 1);
+ scanner._obj5.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_QUINN].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_QUINN].y + 59));
+ scanner._obj5.fixPriority(257);
+
+ scanner._obj6.postInit();
+ scanner._obj6.setup(4, 4, 2);
+ scanner._obj6.setPosition(Common::Point(R2_GLOBALS._s1550PlayerArea[R2_SEEKER].x + 145,
+ R2_GLOBALS._s1550PlayerArea[R2_SEEKER].y + 59));
+ scanner._obj6.fixPriority(257);
+ break;
+ case 1700:
+ case 1800:
+ if (R2_GLOBALS._rimLocation < 1201)
+ scanner._obj4.setup(4, 3, 3);
+ else if (R2_GLOBALS._rimLocation < 1201)
+ scanner._obj4.setup(4, 3, 4);
+ else
+ scanner._obj4.setup(4, 3, 5);
+ break;
+ case 3800:
+ case 3900:
+ if ((R2_GLOBALS._v56A93 + 1) == 0 && R2_GLOBALS._v566A9 == 0) {
+ do {
+ R2_GLOBALS._v566A9 = R2_GLOBALS._randomSource.getRandomNumber(3);
+ } while (R2_GLOBALS._v566A9 == R2_GLOBALS._v566AA);
+ }
+
+ scanner._obj4.setup(4, 7, R2_GLOBALS._v566A9);
+ if (!R2_GLOBALS.getFlag(46))
+ R2_GLOBALS.setFlag(46);
+ break;
+ default:
+ scanner._obj4.setup(4, 3, 2);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScannerDialog::Slider::Slider() {
+ _initial = _xStart = _yp = 0;
+ _width = _xInc = 0;
+ _sliderDown = false;
+}
+
+void ScannerDialog::Slider::synchronize(Serializer &s) {
+ SceneActor::synchronize(s);
+
+ s.syncAsSint16LE(_initial);
+ s.syncAsSint16LE(_xStart);
+ s.syncAsSint16LE(_yp);
+ s.syncAsSint16LE(_width);
+ s.syncAsSint16LE(_xInc);
+}
+
+void ScannerDialog::Slider::remove() {
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.remove(this);
+ SceneActor::remove();
+}
+
+void ScannerDialog::Slider::process(Event &event) {
+ if (event.eventType == EVENT_BUTTON_DOWN && R2_GLOBALS._events.getCursor() == CURSOR_USE
+ && _bounds.contains(event.mousePos)) {
+ _sliderDown = true;
+ }
+
+ if (event.eventType == EVENT_BUTTON_UP && _sliderDown) {
+ _sliderDown = false;
+ event.handled = true;
+ update();
+ }
+
+ if (_sliderDown) {
+ event.handled = true;
+ if (event.mousePos.x < _xStart) {
+ setPosition(Common::Point(_xStart, _yp));
+ } else if (event.mousePos.x >= (_xStart + _width)) {
+ setPosition(Common::Point(_xStart + _width, _yp));
+ } else {
+ setPosition(Common::Point(event.mousePos.x, _yp));
+ }
+ }
+}
+
+bool ScannerDialog::Slider::startAction(CursorType action, Event &event) {
+ if (action == CURSOR_USE)
+ return false;
+
+ return startAction(action, event);
+}
+
+void ScannerDialog::Slider::update() {
+ int incHalf = (_width / (_xInc - 1)) / 2;
+ int newFrequency = ((_position.x - _xStart + incHalf) * _xInc) / (_width + incHalf * 2);
+ setPosition(Common::Point(_xStart + ((_width * newFrequency) / (_xInc - 1)), _yp));
+
+ R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex] = newFrequency + 1;
+
+ switch (newFrequency) {
+ case 0:
+ R2_GLOBALS._sound4.stop();
+ break;
+ case 1:
+ R2_GLOBALS._sound4.play(45);
+ break;
+ case 2:
+ R2_GLOBALS._sound4.play(4);
+ break;
+ case 3:
+ R2_GLOBALS._sound4.play(5);
+ break;
+ case 4:
+ R2_GLOBALS._sound4.play(6);
+ break;
+ default:
+ break;
+ }
+}
+
+void ScannerDialog::Slider::setup(int initial, int xStart, int yp, int width, int xInc) {
+ _initial = initial;
+ _xStart = xStart;
+ _yp = yp;
+ _width = width;
+ _xInc = xInc;
+ _sliderDown = false;
+ SceneActor::postInit();
+ SceneObject::setup(4, 2, 1);
+ fixPriority(255);
+ setPosition(Common::Point(_width * (_initial - 1) / (_xInc - 1) + _xStart, yp));
+
+ static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene)->_sceneAreas.push_front(this);
+}
+
+/*--------------------------------------------------------------------------*/
+
+ScannerDialog::ScannerDialog() {
+}
+
+void ScannerDialog::remove() {
+ switch (R2_GLOBALS._sceneManager._sceneNumber) {
+ case 1550:
+ case 1700:
+ R2_GLOBALS._events.setCursor(R2_GLOBALS._player._canWalk ? CURSOR_WALK : CURSOR_USE);
+ break;
+ case 3800:
+ case 3900: {
+ Scene *scene = R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 3806;
+ scene->signal();
+ break;
+ }
+ default:
+ break;
+ }
+
+ SceneExt *scene = static_cast<SceneExt *>(R2_GLOBALS._sceneManager._scene);
+ scene->_sceneAreas.remove(&_talkButton);
+ scene->_sceneAreas.remove(&_scanButton);
+ _talkButton.remove();
+ _scanButton.remove();
+ _slider.remove();
+ _obj4.remove();
+ _obj5.remove();
+ _obj6.remove();
+ _obj7.remove();
+
+ ModalWindow::remove();
+}
+
+void ScannerDialog::proc12(int visage, int stripFrameNum, int frameNum, int posX, int posY) {
+ // Stop player moving if currently doing so
+ if (R2_GLOBALS._player._mover)
+ R2_GLOBALS._player.addMover(NULL);
+
+ R2_GLOBALS._events.setCursor(CURSOR_USE);
+ ModalWindow::proc12(visage, stripFrameNum, frameNum, posX, posY);
+
+ proc13(100, -1, -1, -1);
+ _talkButton.setup(1);
+ _scanButton.setup(2);
+ _slider.setup(R2_GLOBALS._scannerFrequencies[R2_GLOBALS._player._characterIndex], 142, 124, 35, 5);
+
+ _obj4.postInit();
+ _obj4.setup(4, 3, 2);
+ _obj4.setPosition(Common::Point(160, 83));
+ _obj4.fixPriority(256);
+
+ if (R2_GLOBALS._sceneManager._sceneNumber == 3800 || R2_GLOBALS._sceneManager._sceneNumber == 3900) {
+ Scene *scene = R2_GLOBALS._sceneManager._scene;
+ scene->_sceneMode = 3805;
+ scene->signal();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
} // End of namespace Ringworld2
} // End of namespace TsAGE