aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPeter Kohaut2017-03-20 00:30:41 +0100
committerPeter Kohaut2017-03-20 00:30:41 +0100
commit02185fbcf52a406fb6a381ccfdfdd46077c24127 (patch)
treec29431a4344664c27862d43967d1c9e9f3627ea6 /engines
parent25e5143f99dab91d53eb52de703ef1b4c9ee2656 (diff)
parent89d5eeaa5819c10266160fd1bf12f88f6e073a12 (diff)
downloadscummvm-rg350-02185fbcf52a406fb6a381ccfdfdd46077c24127.tar.gz
scummvm-rg350-02185fbcf52a406fb6a381ccfdfdd46077c24127.tar.bz2
scummvm-rg350-02185fbcf52a406fb6a381ccfdfdd46077c24127.zip
Merge branch 'master' of https://github.com/scummvm/scummvm
Diffstat (limited to 'engines')
-rw-r--r--engines/chewy/console.cpp23
-rw-r--r--engines/chewy/console.h3
-rw-r--r--engines/chewy/cursor.cpp29
-rw-r--r--engines/chewy/cursor.h9
-rw-r--r--engines/chewy/events.cpp2
-rw-r--r--engines/chewy/graphics.cpp47
-rw-r--r--engines/chewy/graphics.h7
-rw-r--r--engines/chewy/scene.cpp207
-rw-r--r--engines/chewy/scene.h1
-rw-r--r--engines/chewy/text.cpp10
-rw-r--r--engines/director/cast.h21
-rw-r--r--engines/director/director.cpp27
-rw-r--r--engines/director/director.h13
-rw-r--r--engines/director/events.cpp71
-rw-r--r--engines/director/frame.cpp150
-rw-r--r--engines/director/frame.h3
-rw-r--r--engines/director/graphics.cpp233
-rw-r--r--engines/director/lingo/lingo-builtins.cpp34
-rw-r--r--engines/director/lingo/lingo-code.cpp12
-rw-r--r--engines/director/lingo/lingo-the.cpp50
-rw-r--r--engines/director/lingo/lingo.cpp15
-rw-r--r--engines/director/resource.cpp42
-rw-r--r--engines/director/score.cpp258
-rw-r--r--engines/director/score.h25
-rw-r--r--engines/director/sprite.cpp21
-rw-r--r--engines/director/sprite.h9
-rw-r--r--engines/director/util.cpp2
-rw-r--r--engines/mohawk/detection_tables.h18
-rw-r--r--engines/mohawk/myst_scripts.cpp21
-rw-r--r--engines/mohawk/myst_stacks/channelwood.cpp2
-rw-r--r--engines/mohawk/myst_stacks/myst.cpp2
-rw-r--r--engines/sci/engine/script_patches.cpp256
-rw-r--r--engines/sci/engine/script_patches.h36
-rw-r--r--engines/titanic/module.mk3
-rw-r--r--engines/titanic/star_control/base_star.cpp26
-rw-r--r--engines/titanic/star_control/base_star.h30
-rw-r--r--engines/titanic/star_control/dmatrix.cpp64
-rw-r--r--engines/titanic/star_control/dmatrix.h15
-rw-r--r--engines/titanic/star_control/dvector.cpp27
-rw-r--r--engines/titanic/star_control/dvector.h18
-rw-r--r--engines/titanic/star_control/fmatrix.cpp78
-rw-r--r--engines/titanic/star_control/fmatrix.h22
-rw-r--r--engines/titanic/star_control/frange.cpp (renamed from engines/titanic/star_control/star_control_sub4.cpp)8
-rw-r--r--engines/titanic/star_control/frange.h (renamed from engines/titanic/star_control/star_control_sub4.h)20
-rw-r--r--engines/titanic/star_control/fvector.cpp21
-rw-r--r--engines/titanic/star_control/fvector.h22
-rw-r--r--engines/titanic/star_control/star_control_sub12.cpp125
-rw-r--r--engines/titanic/star_control/star_control_sub12.h14
-rw-r--r--engines/titanic/star_control/star_control_sub13.cpp187
-rw-r--r--engines/titanic/star_control/star_control_sub13.h35
-rw-r--r--engines/titanic/star_control/star_control_sub2.cpp27
-rw-r--r--engines/titanic/star_control/star_control_sub2.h2
-rw-r--r--engines/titanic/star_control/star_control_sub20.cpp32
-rw-r--r--engines/titanic/star_control/star_control_sub20.h8
-rw-r--r--engines/titanic/star_control/star_control_sub21.cpp42
-rw-r--r--engines/titanic/star_control/star_control_sub21.h7
-rw-r--r--engines/titanic/star_control/star_control_sub22.cpp15
-rw-r--r--engines/titanic/star_control/star_control_sub22.h6
-rw-r--r--engines/titanic/star_control/star_control_sub23.cpp85
-rw-r--r--engines/titanic/star_control/star_control_sub23.h36
-rw-r--r--engines/titanic/star_control/star_control_sub24.cpp14
-rw-r--r--engines/titanic/star_control/star_control_sub24.h6
-rw-r--r--engines/titanic/star_control/star_control_sub25.cpp6
-rw-r--r--engines/titanic/star_control/star_control_sub25.h2
-rw-r--r--engines/titanic/star_control/star_control_sub26.cpp11
-rw-r--r--engines/titanic/star_control/star_control_sub26.h11
-rw-r--r--engines/titanic/star_control/star_control_sub27.cpp32
-rw-r--r--engines/titanic/star_control/star_control_sub27.h5
-rw-r--r--engines/titanic/star_control/star_control_sub5.cpp480
-rw-r--r--engines/titanic/star_control/star_control_sub5.h27
-rw-r--r--engines/titanic/star_control/star_control_sub6.cpp171
-rw-r--r--engines/titanic/star_control/star_control_sub6.h21
-rw-r--r--engines/titanic/star_control/star_control_sub7.cpp48
-rw-r--r--engines/titanic/star_control/star_control_sub8.cpp190
-rw-r--r--engines/titanic/star_control/star_control_sub8.h41
-rw-r--r--engines/titanic/star_control/star_field.cpp4
-rw-r--r--engines/titanic/star_control/star_points1.cpp2
-rw-r--r--engines/titanic/star_control/star_points2.cpp4
-rw-r--r--engines/titanic/star_control/star_ref.cpp63
-rw-r--r--engines/titanic/star_control/star_ref.h84
-rw-r--r--engines/titanic/star_control/star_view.cpp18
-rw-r--r--engines/titanic/star_control/surface_area.cpp5
-rw-r--r--engines/titanic/titanic.h2
83 files changed, 2920 insertions, 961 deletions
diff --git a/engines/chewy/console.cpp b/engines/chewy/console.cpp
index 6fbd99278f..65c4a681d6 100644
--- a/engines/chewy/console.cpp
+++ b/engines/chewy/console.cpp
@@ -35,7 +35,8 @@ namespace Chewy {
Console::Console(ChewyEngine *vm) : GUI::Debugger(), _vm(vm) {
registerCmd("dump", WRAP_METHOD(Console, Cmd_Dump));
registerCmd("dump_bg", WRAP_METHOD(Console, Cmd_DumpBg));
- registerCmd("draw", WRAP_METHOD(Console, Cmd_Draw));
+ registerCmd("draw_image", WRAP_METHOD(Console, Cmd_DrawImage));
+ registerCmd("draw_sprite", WRAP_METHOD(Console, Cmd_DrawSprite));
registerCmd("play_sound", WRAP_METHOD(Console, Cmd_PlaySound));
registerCmd("play_speech", WRAP_METHOD(Console, Cmd_PlaySpeech));
registerCmd("play_music", WRAP_METHOD(Console, Cmd_PlayMusic));
@@ -104,9 +105,9 @@ bool Console::Cmd_DumpBg(int argc, const char **argv) {
}
-bool Console::Cmd_Draw(int argc, const char **argv) {
+bool Console::Cmd_DrawImage(int argc, const char **argv) {
if (argc < 3) {
- debugPrintf("Usage: draw <file> <resource number>\n");
+ debugPrintf("Usage: draw_image <file> <resource number>\n");
return true;
}
@@ -118,6 +119,22 @@ bool Console::Cmd_Draw(int argc, const char **argv) {
return false;
}
+bool Console::Cmd_DrawSprite(int argc, const char **argv) {
+ if (argc < 3) {
+ debugPrintf("Usage: draw_sprite <file> <resource number> [x] [y]\n");
+ return true;
+ }
+
+ Common::String filename = argv[1];
+ int spriteNum = atoi(argv[2]);
+ int x = (argc < 4) ? 0 : atoi(argv[3]);
+ int y = (argc < 5) ? 0 : atoi(argv[4]);
+
+ _vm->_graphics->drawSprite(filename, spriteNum, x, y);
+
+ return false;
+}
+
bool Console::Cmd_PlaySound(int argc, const char **argv) {
if (argc < 2) {
debugPrintf("Usage: play_sound <number>\n");
diff --git a/engines/chewy/console.h b/engines/chewy/console.h
index ae2be15f30..2ceb1df4e6 100644
--- a/engines/chewy/console.h
+++ b/engines/chewy/console.h
@@ -39,7 +39,8 @@ private:
bool Cmd_Dump(int argc, const char **argv);
bool Cmd_DumpBg(int argc, const char **argv);
- bool Cmd_Draw(int argc, const char **argv);
+ bool Cmd_DrawImage(int argc, const char **argv);
+ bool Cmd_DrawSprite(int argc, const char **argv);
bool Cmd_PlaySound(int argc, const char **argv);
bool Cmd_PlaySpeech(int argc, const char **argv);
bool Cmd_PlayMusic(int argc, const char **argv);
diff --git a/engines/chewy/cursor.cpp b/engines/chewy/cursor.cpp
index 4795221e44..54496ef848 100644
--- a/engines/chewy/cursor.cpp
+++ b/engines/chewy/cursor.cpp
@@ -63,6 +63,35 @@ Cursor::~Cursor() {
delete _cursorSprites;
}
+// TODO: This may need to be refactored, since in the original the user
+// selects the cursor to use from a pop-up menu
+CurrentCursor Cursor::getCurrentCursor() const {
+ switch (_curCursor) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ return kWalk;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ return kUse;
+ case 13:
+ case 14:
+ case 15:
+ case 16:
+ return kLook;
+ case 17:
+ case 18:
+ case 19:
+ case 20:
+ return kTalk;
+ default:
+ return kOther;
+ }
+}
+
void Cursor::setCursor(uint num, bool newCursor) {
TAFChunk *cursor = _cursorSprites->getSprite(num);
if (newCursor)
diff --git a/engines/chewy/cursor.h b/engines/chewy/cursor.h
index de5a707ca6..bb39abb463 100644
--- a/engines/chewy/cursor.h
+++ b/engines/chewy/cursor.h
@@ -30,6 +30,14 @@ namespace Chewy {
class SpriteResource;
class Font;
+enum CurrentCursor {
+ kWalk,
+ kLook,
+ kUse,
+ kTalk,
+ kOther
+};
+
class Cursor {
public:
Cursor();
@@ -40,6 +48,7 @@ public:
void hideCursor();
void animateCursor();
void nextCursor();
+ CurrentCursor getCurrentCursor() const;
private:
uint _curCursor;
diff --git a/engines/chewy/events.cpp b/engines/chewy/events.cpp
index 3da9da2803..532b1acce7 100644
--- a/engines/chewy/events.cpp
+++ b/engines/chewy/events.cpp
@@ -55,6 +55,8 @@ void Events::processEvents() {
default:
break;
}
+ } else if (_event.type == Common::EVENT_LBUTTONUP) {
+ _vm->_scene->mouseClick(_event.mouse);
} else if (_event.type == Common::EVENT_RBUTTONUP) {
_vm->_cursor->nextCursor();
} else if (_event.type == Common::EVENT_MOUSEMOVE) {
diff --git a/engines/chewy/graphics.cpp b/engines/chewy/graphics.cpp
index 54a731fd3a..2f7c28ad6c 100644
--- a/engines/chewy/graphics.cpp
+++ b/engines/chewy/graphics.cpp
@@ -34,12 +34,17 @@
namespace Chewy {
+#define DESC_WIDTH 80
+#define DESC_HEIGHT 8
+
Graphics::Graphics(ChewyEngine *vm) : _vm(vm) {
_font = nullptr;
+ _descSurface.create(DESC_WIDTH, DESC_HEIGHT, ::Graphics::PixelFormat::createFormatCLUT8());
}
Graphics::~Graphics() {
delete _font;
+ _descSurface.free();
}
void Graphics::drawSprite(Common::String filename, int spriteNum, uint x, uint y) {
@@ -67,6 +72,15 @@ void Graphics::drawImage(Common::String filename, int imageNum) {
delete res;
}
+void Graphics::drawRect(Common::Rect r, byte color) {
+ ::Graphics::Surface *screen = g_system->lockScreen();
+ screen->drawLine(r.left, r.top, r.right, r.top, color);
+ screen->drawLine(r.right, r.top, r.right, r.bottom, color);
+ screen->drawLine(r.left, r.bottom, r.right, r.bottom, color);
+ screen->drawLine(r.left, r.top, r.left, r.bottom, color);
+ g_system->unlockScreen();
+}
+
void Graphics::loadFont(Common::String filename) {
_font = new Font(filename);
}
@@ -75,10 +89,12 @@ void Graphics::drawTransparent(uint16 x, uint16 y, byte *data, uint16 width, uin
::Graphics::Surface *screen = g_system->lockScreen();
for (uint curX = 0; curX < width; curX++) {
for (uint curY = 0; curY < height; curY++) {
- byte *src = data + (curY * width) + curX;
- byte *dst = (byte *)screen->getBasePtr(curX + x, curY + y);
- if (*src != transparentColor)
- *dst = *src;
+ if (curX + x < 320 && curY + y < 200) {
+ byte *src = data + (curY * width) + curX;
+ byte *dst = (byte *)screen->getBasePtr(curX + x, curY + y);
+ if (*src != transparentColor)
+ *dst = *src;
+ }
}
}
g_system->unlockScreen();
@@ -145,4 +161,27 @@ void Graphics::playVideo(uint num) {
delete cfoDecoder;
}
+void Graphics::setDescSurface(Common::Point pos) {
+ _descPos = pos;
+
+ if (pos.x < 0)
+ return;
+
+ ::Graphics::Surface *s = g_system->lockScreen();
+ Common::Rect r = Common::Rect(pos.x, pos.y, pos.x + _descSurface.w, pos.y + _descSurface.h);
+ r.clip(Common::Rect(0, 0, 320, 200));
+ _descSurface.copyRectToSurface(*s, 0, 0, r);
+ g_system->unlockScreen();
+}
+
+void Graphics::restoreDescSurface() {
+ if (_descPos.x < 0)
+ return;
+
+ Common::Rect r = Common::Rect(_descPos.x, _descPos.y, _descPos.x + _descSurface.w, _descPos.y + _descSurface.h);
+ r.clip(Common::Rect(0, 0, 320, 200));
+ g_system->copyRectToScreen(_descSurface.getPixels(), _descSurface.pitch, _descPos.x, _descPos.y, r.width(), r.height());
+ _descPos = Common::Point(-1, -1);
+}
+
} // End of namespace Chewy
diff --git a/engines/chewy/graphics.h b/engines/chewy/graphics.h
index a260311df5..09865711df 100644
--- a/engines/chewy/graphics.h
+++ b/engines/chewy/graphics.h
@@ -24,6 +24,8 @@
#define CHEWY_GRAPHICS_H
#include "chewy/chewy.h"
+#include "common/rect.h"
+#include "graphics/surface.h"
namespace Chewy {
@@ -37,15 +39,20 @@ public:
void drawImage(Common::String filename, int imageNum);
void drawSprite(Common::String filename, int spriteNum, uint x, uint y);
+ void drawRect(Common::Rect r, byte color);
void playVideo(uint num);
void loadFont(Common::String filename);
void drawText(Common::String text, uint x, uint y);
+ void setDescSurface(Common::Point pos);
+ void restoreDescSurface();
private:
void drawTransparent(uint16 x, uint16 y, byte *data, uint16 width, uint16 height, byte transparentColor);
ChewyEngine *_vm;
Font *_font;
+ Common::Point _descPos;
+ ::Graphics::Surface _descSurface;
};
} // End of namespace Chewy
diff --git a/engines/chewy/scene.cpp b/engines/chewy/scene.cpp
index 0f12219078..df8dd66148 100644
--- a/engines/chewy/scene.cpp
+++ b/engines/chewy/scene.cpp
@@ -30,6 +30,7 @@
#include "chewy/graphics.h"
#include "chewy/scene.h"
#include "chewy/resource.h"
+#include "chewy/sound.h"
#include "chewy/text.h"
#include "chewy/video/cfo_decoder.h"
@@ -37,12 +38,28 @@ namespace Chewy {
#define MAX_DETAILS 32
#define MAX_HOTSPOTS 50
+#define MAX_AUTOMOVE 20
+#define MAX_SOUNDS 3
// Animated details - scene animations
struct AnimatedDetails {
- uint16 x;
- uint16 y;
- // 66 bytes animated details - TODO
+ int16 x;
+ int16 y;
+ byte startFlag; // 0: no animation
+ byte repeat;
+ int16 startSprite;
+ int16 endSprite;
+ int16 spriteCount;
+ uint16 delay;
+ uint16 delayCount;
+ uint16 reverse; // 0: play normally, 1: play in reverse
+ uint16 timerStart; // seconds until detail is started (0: no timer)
+ uint16 zIndex;
+ byte loadFlag; // 0: load animation in memory immediately, 1: load animation in memory when it is played
+ byte zoom;
+ // 2 * 3 * 7 = 42 bytes sound data - TODO
+ byte showOneFrame; // show a sprite, 0: none, 1: before animation, 2: after animation
+ byte currentFrame;
};
// Static details - scene sprites and props
@@ -50,20 +67,18 @@ struct StaticDetails {
int16 x;
int16 y;
int16 spriteNum;
- uint16 z;
+ uint16 zIndex;
byte hide;
// 1 byte dummy
};
-struct SceneInfo {
- uint16 staticDetailsCount;
- uint16 animatedDetailsCount;
- uint32 spritePtr;
- AnimatedDetails animatedDetails[MAX_DETAILS];
- StaticDetails staticDetails[MAX_DETAILS];
- Common::Rect hotspot[MAX_HOTSPOTS];
- uint16 hotspotDescRes[MAX_HOTSPOTS];
- Common::String hotspotDesc[MAX_HOTSPOTS];
+struct Hotspot {
+ Common::Rect rect;
+ uint16 resource;
+ Common::String desc;
+};
+
+struct RoomInfo {
byte roomNum;
byte picNum;
byte autoMoveCount;
@@ -71,13 +86,37 @@ struct SceneInfo {
Common::String tafName; // 14 bytes
byte zoomFactor;
// 1 byte dummy
- // 6 * 20 = 120 bytes automove coordinates - TODO
- // MAX_DETAILS * 3 * 2 = 192 bytes voc - TODO
- // MAX_DETAILS * 3 = 96 bytes samples - TODO
+};
+
+struct AutoMove {
+ int16 x;
+ int16 y;
+ byte spriteNum; // sprite number to draw when the end point is reached
+ // 1 byte dummy
+};
+
+struct HotspotSpeech {
+ int16 look;
+ int16 use;
+ int16 talk;
+};
+
+struct SceneInfo {
+ uint16 staticDetailsCount;
+ uint16 animatedDetailsCount;
+ uint32 spritePtr;
+ AnimatedDetails animatedDetails[MAX_DETAILS];
+ StaticDetails staticDetails[MAX_DETAILS];
+ Hotspot hotspot[MAX_HOTSPOTS];
+ RoomInfo roomInfo;
+ AutoMove autoMove[MAX_AUTOMOVE];
+ HotspotSpeech hotspotSpeech[MAX_DETAILS];
+ byte hotspotSound[MAX_DETAILS][MAX_SOUNDS];
};
Scene::Scene(ChewyEngine *vm) : _vm(vm) {
_sceneInfo = new SceneInfo();
+ _vm->_graphics->setDescSurface(Common::Point(-1, -1));
}
Scene::~Scene() {
@@ -97,8 +136,8 @@ void Scene::draw() {
// Background
_vm->_graphics->drawImage("episode1.tgp", _curScene);
- // Static details
- for (uint16 i = 0; i < MAX_HOTSPOTS; i++) {
+ for (uint16 i = 0; i < MAX_DETAILS; i++) {
+ // Static details
StaticDetails s = _sceneInfo->staticDetails[i];
if (s.spriteNum >= 0 && s.x >= 0 && s.y >= 0 && !s.hide)
_vm->_graphics->drawSprite(Common::String::format("det%d.taf", _curScene), s.spriteNum, s.x, s.y);
@@ -107,23 +146,54 @@ void Scene::draw() {
// TODO: These are all hardcoded for now
_vm->_graphics->drawSprite("det1.taf", 0, 200, 100);
_vm->_graphics->loadFont("6x8.tff");
- _vm->_graphics->drawText("This is a test", 200, 80);
+ //_vm->_graphics->drawText("This is a test", 200, 80);
+
+ _vm->_graphics->setDescSurface(Common::Point(-1, -1));
}
void Scene::updateMouse(Common::Point coords) {
- // Animated details
- // TODO: handle these
+ _vm->_graphics->restoreDescSurface();
// Static details
for (uint16 i = 0; i < MAX_HOTSPOTS; i++) {
- if (_sceneInfo->hotspot[i].contains(coords)) {
- // TODO: Draw hotspot description on screen
- debug("Coords %d, %d: '%s'", coords.x, coords.y, _sceneInfo->hotspotDesc[i].c_str());
+ //_vm->_graphics->drawRect(_sceneInfo->hotspot[i].rect, 0); // debug
+ if (_sceneInfo->hotspot[i].rect.contains(coords) && _sceneInfo->hotspot[i].resource < kATSTextMax) {
+ if (coords.y >= 8) {
+ _vm->_graphics->setDescSurface(Common::Point(coords.x, coords.y - 8));
+ _vm->_graphics->drawText(_sceneInfo->hotspot[i].desc, coords.x, coords.y - 8);
+ }
break;
}
}
}
+void Scene::mouseClick(Common::Point coords) {
+ // Static details
+ for (uint16 i = 0; i < MAX_HOTSPOTS; i++) {
+ //_vm->_graphics->drawRect(_sceneInfo->hotspot[i].rect, 0); // debug
+ if (_sceneInfo->hotspot[i].rect.contains(coords)) {
+ int sample = -1;
+
+ switch (_vm->_cursor->getCurrentCursor()) {
+ case kLook:
+ sample = _sceneInfo->hotspotSpeech[i].look;
+ break;
+ case kUse:
+ sample = _sceneInfo->hotspotSpeech[i].use;
+ break;
+ case kTalk:
+ sample = _sceneInfo->hotspotSpeech[i].talk;
+ break;
+ default:
+ break;
+ }
+
+ if (sample >= 0)
+ _vm->_sound->playSpeech(sample);
+ }
+ }
+}
+
void Scene::loadSceneInfo() {
const uint32 sceneInfoSize = 3784;
const uint32 headerRDI = MKTAG('R', 'D', 'I', '\0');
@@ -148,9 +218,23 @@ void Scene::loadSceneInfo() {
// Animated details
for (int i = 0; i < MAX_DETAILS; i++) {
- _sceneInfo->animatedDetails[i].x = indexFile.readUint16LE();
- _sceneInfo->animatedDetails[i].y = indexFile.readUint16LE();
- indexFile.skip(66); // animated details info - TODO: read these
+ _sceneInfo->animatedDetails[i].x = indexFile.readSint16LE();
+ _sceneInfo->animatedDetails[i].y = indexFile.readSint16LE();
+ _sceneInfo->animatedDetails[i].startFlag = indexFile.readByte();
+ _sceneInfo->animatedDetails[i].repeat = indexFile.readByte();
+ _sceneInfo->animatedDetails[i].startSprite = indexFile.readSint16LE();
+ _sceneInfo->animatedDetails[i].endSprite = indexFile.readSint16LE();
+ _sceneInfo->animatedDetails[i].spriteCount = indexFile.readSint16LE();
+ _sceneInfo->animatedDetails[i].delay = indexFile.readUint16LE();
+ _sceneInfo->animatedDetails[i].delayCount = indexFile.readUint16LE();
+ _sceneInfo->animatedDetails[i].reverse = indexFile.readUint16LE();
+ _sceneInfo->animatedDetails[i].timerStart = indexFile.readUint16LE();
+ _sceneInfo->animatedDetails[i].zIndex = indexFile.readUint16LE();
+ _sceneInfo->animatedDetails[i].loadFlag = indexFile.readByte();
+ _sceneInfo->animatedDetails[i].zoom = indexFile.readByte();
+ indexFile.skip(42); // 2 * 3 * 7 = 42 bytes sound data - TODO
+ _sceneInfo->animatedDetails[i].showOneFrame = indexFile.readUint16LE();
+ _sceneInfo->animatedDetails[i].currentFrame = indexFile.readUint16LE();
}
// Static details
@@ -158,49 +242,70 @@ void Scene::loadSceneInfo() {
_sceneInfo->staticDetails[i].x = indexFile.readSint16LE();
_sceneInfo->staticDetails[i].y = indexFile.readSint16LE();
_sceneInfo->staticDetails[i].spriteNum = indexFile.readSint16LE();
- _sceneInfo->staticDetails[i].z = indexFile.readUint16LE();
+ _sceneInfo->staticDetails[i].zIndex = indexFile.readUint16LE();
_sceneInfo->staticDetails[i].hide = indexFile.readByte();
indexFile.readByte(); // padding
}
// Hotspots
for (int i = 0; i < MAX_HOTSPOTS; i++) {
- _sceneInfo->hotspot[i].left = indexFile.readUint16LE();
- _sceneInfo->hotspot[i].top = indexFile.readUint16LE();
- _sceneInfo->hotspot[i].right = indexFile.readUint16LE();
- _sceneInfo->hotspot[i].bottom = indexFile.readUint16LE();
- if (!_sceneInfo->hotspot[i].isValidRect())
+ _sceneInfo->hotspot[i].rect.left = indexFile.readUint16LE();
+ _sceneInfo->hotspot[i].rect.top = indexFile.readUint16LE();
+ _sceneInfo->hotspot[i].rect.right = indexFile.readUint16LE();
+ _sceneInfo->hotspot[i].rect.bottom = indexFile.readUint16LE();
+ if (!_sceneInfo->hotspot[i].rect.isValidRect())
warning("Hotspot %d has an invalid rect", i);
}
// Hotspot descriptions
for (int i = 0; i < MAX_HOTSPOTS; i++) {
- _sceneInfo->hotspotDescRes[i] = indexFile.readUint16LE();
-
- if (_sceneInfo->hotspotDescRes[i] < 12) {
- // TODO: Hotspot description IDs are off... investigate why
- _sceneInfo->hotspotDesc[i] = text->getText(_curScene + kADSTextMax, _sceneInfo->hotspotDescRes[i])->text;
- } else {
- // TODO: Handle these types of hotspot descriptions
- warning("Hotspot %d has an invalid description resource (%d)", i, _sceneInfo->hotspotDescRes[i]);
- _sceneInfo->hotspotDesc[i] = Common::String::format("Hotspot %d", _sceneInfo->hotspotDescRes[i]);
+ _sceneInfo->hotspot[i].resource = indexFile.readUint16LE() + 4;
+ _sceneInfo->hotspot[i].desc = "";
+
+ if (_sceneInfo->hotspot[i].resource < kATSTextMax) {
+ TextEntry *entry = text->getText(_curScene + kADSTextMax, _sceneInfo->hotspot[i].resource);
+ if (entry)
+ _sceneInfo->hotspot[i].desc = entry->text;
}
}
- _sceneInfo->roomNum = indexFile.readByte();
- _sceneInfo->picNum = indexFile.readByte();
- _sceneInfo->autoMoveCount = indexFile.readByte();
- _sceneInfo->loadTaf = indexFile.readByte();
+ // Room info
+ _sceneInfo->roomInfo.roomNum = indexFile.readByte();
+ _sceneInfo->roomInfo.picNum = indexFile.readByte();
+ _sceneInfo->roomInfo.autoMoveCount = indexFile.readByte();
+ _sceneInfo->roomInfo.loadTaf = indexFile.readByte();
+ _sceneInfo->roomInfo.tafName = "";
for (int i = 0; i < 14; i++)
- _sceneInfo->tafName += indexFile.readByte();
+ _sceneInfo->roomInfo.tafName += indexFile.readByte();
- _sceneInfo->zoomFactor = indexFile.readByte();
+ _sceneInfo->roomInfo.zoomFactor = indexFile.readByte();
indexFile.readByte(); // padding
- // 6 * 20 = 120 bytes automove coordinates - TODO: read these
- // MAX_DETAILS * 3 * 2 = 192 bytes voc - TODO: read these
- // MAX_DETAILS * 3 = 96 bytes samples - TODO: read these
+ for (int i = 0; i < MAX_AUTOMOVE; i++) {
+ _sceneInfo->autoMove[i].x = indexFile.readSint16LE();
+ _sceneInfo->autoMove[i].y = indexFile.readSint16LE();
+ _sceneInfo->autoMove[i].spriteNum = indexFile.readByte();
+ indexFile.readByte(); // padding
+ if (i > _sceneInfo->roomInfo.autoMoveCount && !(_sceneInfo->autoMove[i].x <= 0 || _sceneInfo->autoMove[i].y <= 0))
+ warning("Auto move %d should be unused, but it isn't (max auto move items are %d)", i, _sceneInfo->roomInfo.autoMoveCount);
+ }
+
+ for (int i = 0; i < MAX_DETAILS; i++) {
+ // FIXME: These are all wrong... investigate why
+ _sceneInfo->hotspotSpeech[i].look = indexFile.readSint16LE();
+ _sceneInfo->hotspotSpeech[i].use = indexFile.readSint16LE();
+ _sceneInfo->hotspotSpeech[i].talk = indexFile.readSint16LE();
+ }
+
+ for (int i = 0; i < MAX_DETAILS; i++) {
+ _sceneInfo->hotspotSound[i][0] = indexFile.readSint16LE();
+ _sceneInfo->hotspotSound[i][1] = indexFile.readSint16LE();
+ _sceneInfo->hotspotSound[i][2] = indexFile.readSint16LE();
+ }
+
+ // TODO: We seem to be missing a chunk of data (186 bytes) from the end of
+ // the room info structure
delete text;
indexFile.close();
diff --git a/engines/chewy/scene.h b/engines/chewy/scene.h
index c5b87ac7ae..bcbbf6761e 100644
--- a/engines/chewy/scene.h
+++ b/engines/chewy/scene.h
@@ -37,6 +37,7 @@ public:
void change(uint scene);
void draw();
void updateMouse(Common::Point coords);
+ void mouseClick(Common::Point coords);
uint getCurScene() const {
return _curScene;
}
diff --git a/engines/chewy/text.cpp b/engines/chewy/text.cpp
index cf0fb041a7..095b74b290 100644
--- a/engines/chewy/text.cpp
+++ b/engines/chewy/text.cpp
@@ -112,8 +112,14 @@ TextEntry *Text::getText(uint dialogNum, uint entryNum) {
}
} while (*ptr);
- if (*(ptr + 1) != kEndText || *(ptr + 2) != kEndChunk)
- error("Invalid text resource - %d, %d", dialogNum, entryNum);
+ if (*(ptr + 1) != kEndText || *(ptr + 2) != kEndChunk) {
+ warning("Invalid text resource - %d, %d", dialogNum, entryNum);
+
+ delete[] data;
+ delete d;
+
+ return nullptr;
+ }
if (!isText)
ptr += 3; // 0, kEndText, kEndChunk
diff --git a/engines/director/cast.h b/engines/director/cast.h
index 953c94c4c6..f304456e12 100644
--- a/engines/director/cast.h
+++ b/engines/director/cast.h
@@ -26,6 +26,7 @@
#include "common/rect.h"
#include "common/substream.h"
#include "director/archive.h"
+#include "graphics/surface.h"
namespace Director {
@@ -44,16 +45,20 @@ enum CastType {
kCastLingoScript = 11
};
-struct Cast {
+class Cast {
+public:
CastType type;
Common::Rect initialRect;
Common::Rect boundingRect;
Common::Array<Resource> children;
+ const Graphics::Surface *surface;
+
byte modified;
};
-struct BitmapCast : Cast {
+class BitmapCast : public Cast {
+public:
BitmapCast(Common::ReadStreamEndian &stream, uint16 version = 2);
uint16 regX;
@@ -72,7 +77,8 @@ enum ShapeType {
kShapeLine
};
-struct ShapeCast : Cast {
+class ShapeCast : public Cast {
+public:
ShapeCast(Common::ReadStreamEndian &stream, uint16 version = 2);
ShapeType shapeType;
@@ -111,7 +117,8 @@ enum SizeType {
kSizeLargest
};
-struct TextCast : Cast {
+class TextCast : public Cast {
+public:
TextCast(Common::ReadStreamEndian &stream, uint16 version = 2);
SizeType borderSize;
@@ -135,13 +142,15 @@ enum ButtonType {
kTypeRadio
};
-struct ButtonCast : TextCast {
+class ButtonCast : public TextCast {
+public:
ButtonCast(Common::ReadStreamEndian &stream, uint16 version = 2);
ButtonType buttonType;
};
-struct ScriptCast : Cast {
+class ScriptCast : public Cast {
+public:
ScriptCast(Common::ReadStreamEndian &stream, uint16 version = 2);
uint32 id;
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index edea7ea591..70d5cf3c62 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -92,7 +92,10 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
_keyCode = 0;
_machineType = 9; // Macintosh IIci
_playbackPaused = false;
- g_director->_skipFrameAdvance = false;
+ _skipFrameAdvance = false;
+
+ _draggingSprite = false;
+ _draggingSpriteId = 0;
}
DirectorEngine::~DirectorEngine() {
@@ -141,6 +144,8 @@ Common::Error DirectorEngine::run() {
//_mainArchive = new RIFFArchive();
//_mainArchive->openFile("bookshelf_example.mmm");
+ _currentScore = new Score(this);
+
if (getVersion() < 4) {
if (getPlatform() == Common::kPlatformWindows) {
_sharedCastFile = "SHARDCST.MMM";
@@ -155,7 +160,7 @@ Common::Error DirectorEngine::run() {
loadInitialMovie(getEXEName());
- _currentScore = new Score(this, _mainArchive);
+ _currentScore->setArchive(_mainArchive);
debug(0, "Score name %s", _currentScore->getMacName().c_str());
bool loop = true;
@@ -176,8 +181,12 @@ Common::Error DirectorEngine::run() {
_nextMovie.frameI = -1;
}
+ debugC(1, kDebugEvents, "Starting playback of score '%s'", _currentScore->getMacName().c_str());
+
_currentScore->startLoop();
+ debugC(1, kDebugEvents, "Finished playback of score '%s'", _currentScore->getMacName().c_str());
+
// If a loop was requested, do it
if (!_nextMovie.movie.empty()) {
_lingo->restartLingo();
@@ -192,8 +201,9 @@ Common::Error DirectorEngine::run() {
return Common::kNoError;
}
- _currentScore = new Score(this, mov);
- debug(0, "Score name %s", _currentScore->getMacName().c_str());
+ _currentScore = new Score(this);
+ _currentScore->setArchive(mov);
+ debug(0, "Switching to score '%s'", _currentScore->getMacName().c_str());
_nextMovie.movie.clear();
loop = true;
@@ -233,7 +243,8 @@ Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Commo
warning("name: %s", i->getName().c_str());
arc->openFile(i->getName());
- Score *sc = new Score(this, arc);
+ Score *sc = new Score(this);
+ sc->setArchive(arc);
nameMap->setVal(sc->getMacName(), sc);
debugC(2, kDebugLoading, "Movie name: \"%s\"", sc->getMacName().c_str());
@@ -243,11 +254,11 @@ Common::HashMap<Common::String, Score *> *DirectorEngine::scanMovies(const Commo
return nameMap;
}
-Common::HashMap<int, Cast *> *DirectorEngine::getSharedCasts() {
+Common::HashMap<int, CastType> *DirectorEngine::getSharedCastTypes() {
if (_sharedScore)
- return &_sharedScore->_casts;
+ return &_sharedScore->_castTypes;
- return &_dummyCast;
+ return &_dummyCastType;
}
} // End of namespace Director
diff --git a/engines/director/director.h b/engines/director/director.h
index 2f0b65288f..3c3e2e947a 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -28,6 +28,7 @@
#include "common/hashmap.h"
#include "engines/engine.h"
+#include "director/cast.h"
namespace Common {
class MacResManager;
@@ -50,7 +51,7 @@ struct DirectorGameDescription;
class DirectorSound;
class Lingo;
class Score;
-struct Cast;
+class Cast;
enum {
kDebugLingoExec = 1 << 0,
@@ -89,6 +90,7 @@ public:
Archive *getMainArchive() const { return _mainArchive; }
Lingo *getLingo() const { return _lingo; }
Score *getCurrentScore() const { return _currentScore; }
+ Score *getSharedScore() const { return _sharedScore; }
void setPalette(byte *palette, uint16 count);
bool hasFeature(EngineFeature f) const;
const byte *getPalette() const { return _currentPalette; }
@@ -103,11 +105,12 @@ public:
void cleanupMainArchive();
void processEvents(); // evetns.cpp
+ void setDraggedSprite(uint16 id); // events.cpp
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedDIB() const { return _sharedDIB; }
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedBMP() const { return _sharedBMP; }
Common::HashMap<int, Common::SeekableSubReadStreamEndian *> *getSharedSTXT() const { return _sharedSTXT; }
- Common::HashMap<int, Cast *> *getSharedCasts();
+ Common::HashMap<int, CastType> *getSharedCastTypes();
Common::HashMap<Common::String, Score *> *_movies;
@@ -159,7 +162,11 @@ private:
Graphics::MacPatterns _director3QuickDrawPatterns;
Common::String _sharedCastFile;
- Common::HashMap<int, Cast *> _dummyCast;
+ Common::HashMap<int, CastType> _dummyCastType;
+
+ bool _draggingSprite;
+ uint16 _draggingSpriteId;
+ Common::Point _draggingSpritePos;
private:
void testFontScaling();
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 613e83c352..e60af2244b 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -46,51 +46,62 @@ void DirectorEngine::processEvents() {
uint endTime = g_system->getMillis() + 200;
Score *sc = getCurrentScore();
- int currentFrame = sc->getCurrentFrame();
+ Frame *currentFrame = sc->_frames[sc->getCurrentFrame()];
uint16 spriteId = 0;
- // TODO: re-instate when we know which script to run.
- //if (currentFrame > 0)
- // _lingo->processEvent(kEventIdle, currentFrame - 1);
+ Common::Point pos;
while (g_system->getMillis() < endTime) {
while (g_system->getEventManager()->pollEvent(event)) {
- if (event.type == Common::EVENT_QUIT)
+ switch (event.type) {
+ case Common::EVENT_QUIT:
sc->_stopPlay = true;
+ break;
- if (event.type == Common::EVENT_LBUTTONDOWN) {
- Common::Point pos = g_system->getEventManager()->getMousePos();
+ case Common::EVENT_LBUTTONDOWN:
+ pos = g_system->getEventManager()->getMousePos();
// D3 doesn't have both mouse up and down.
// But we still want to know if the mouse is down for press effects.
- spriteId = sc->_frames[currentFrame]->getSpriteIDFromPos(pos);
+ spriteId = currentFrame->getSpriteIDFromPos(pos);
sc->_currentMouseDownSpriteId = spriteId;
+ debugC(3, kDebugEvents, "event: Button Down @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
+
if (getVersion() > 3) {
// TODO: check that this is the order of script execution!
- _lingo->processEvent(kEventMouseDown, kCastScript, sc->_frames[currentFrame]->_sprites[spriteId]->_castId);
- _lingo->processEvent(kEventMouseDown, kSpriteScript, sc->_frames[currentFrame]->_sprites[spriteId]->_scriptId);
+ _lingo->processEvent(kEventMouseDown, kCastScript, currentFrame->_sprites[spriteId]->_castId);
+ _lingo->processEvent(kEventMouseDown, kSpriteScript, currentFrame->_sprites[spriteId]->_scriptId);
}
- }
- if (event.type == Common::EVENT_LBUTTONUP) {
- Common::Point pos = g_system->getEventManager()->getMousePos();
+ if (currentFrame->_sprites[spriteId]->_moveable) {
+ warning("Moveable");
+ }
+ break;
+
+ case Common::EVENT_LBUTTONUP:
+ pos = g_system->getEventManager()->getMousePos();
+
+ spriteId = currentFrame->getSpriteIDFromPos(pos);
+
+ debugC(3, kDebugEvents, "event: Button Up @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
- spriteId = sc->_frames[currentFrame]->getSpriteIDFromPos(pos);
if (getVersion() > 3) {
// TODO: check that this is the order of script execution!
- _lingo->processEvent(kEventMouseUp, kCastScript, sc->_frames[currentFrame]->_sprites[spriteId]->_castId);
- _lingo->processEvent(kEventMouseUp, kSpriteScript, sc->_frames[currentFrame]->_sprites[spriteId]->_scriptId);
+ _lingo->processEvent(kEventMouseUp, kCastScript, currentFrame->_sprites[spriteId]->_castId);
+ _lingo->processEvent(kEventMouseUp, kSpriteScript, currentFrame->_sprites[spriteId]->_scriptId);
} else {
// Frame script overrides sprite script
- if (!sc->_frames[currentFrame]->_sprites[spriteId]->_scriptId)
- _lingo->processEvent(kEventMouseUp, kSpriteScript, sc->_frames[currentFrame]->_sprites[spriteId]->_castId + 1024);
+ if (!currentFrame->_sprites[spriteId]->_scriptId)
+ _lingo->processEvent(kEventMouseUp, kSpriteScript, currentFrame->_sprites[spriteId]->_castId + 1024);
else
- _lingo->processEvent(kEventMouseUp, kFrameScript, sc->_frames[currentFrame]->_sprites[spriteId]->_scriptId);
+ _lingo->processEvent(kEventMouseUp, kFrameScript, currentFrame->_sprites[spriteId]->_scriptId);
}
- }
- if (event.type == Common::EVENT_KEYDOWN) {
+ sc->_currentMouseDownSpriteId = 0;
+ break;
+
+ case Common::EVENT_KEYDOWN:
_keyCode = event.kbd.keycode;
_key = (unsigned char)(event.kbd.ascii & 0xff);
@@ -111,14 +122,28 @@ void DirectorEngine::processEvents() {
warning("Keycode: %d", _keyCode);
}
- // TODO: is movie script correct? Can this be elsewhere?
- _lingo->processEvent(kEventKeyDown, kMovieScript, 0);
+ _lingo->processEvent(kEventKeyDown, kGlobalScript, 0);
+ break;
+
+ default:
+ break;
}
}
g_system->updateScreen();
g_system->delayMillis(10);
+
+ if (sc->getCurrentFrame() > 0)
+ _lingo->processEvent(kEventIdle, kFrameScript, sc->getCurrentFrame());
}
}
+void DirectorEngine::setDraggedSprite(uint16 id) {
+ _draggingSprite = true;
+ _draggingSpriteId = id;
+ _draggingSpritePos = g_system->getEventManager()->getMousePos();
+
+ warning("STUB: DirectorEngine::setDraggedSprite(%d)", id);
+}
+
} // End of namespace Director
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 7690a47893..92aa851d06 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -36,6 +36,7 @@
#include "director/score.h"
#include "director/sprite.h"
#include "director/util.h"
+#include "director/lingo/lingo.h"
namespace Director {
@@ -221,10 +222,14 @@ void Frame::readChannels(Common::ReadStreamEndian *stream) {
sprite._unk3 = stream->readUint32();
}
- debugC(kDebugLoading, 8, "%03d(%d)[%x,%x,%04x,%d/%d/%d/%d/%d] script:%d",
- sprite._castId, sprite._enabled, sprite._x1, sprite._x2, sprite._flags,
- sprite._startPoint.x, sprite._startPoint.y, sprite._width, sprite._height,
- sprite._lineSize, sprite._scriptId);
+ if (sprite._castId) {
+ debugC(kDebugLoading, 4, "CH: %-3d castId: %03d(%s) (e:%d) [%x,%x, flags:%04x, %dx%d@%d,%d linesize: %d] script: %d",
+ i + 1, sprite._castId, numToCastNum(sprite._castId), sprite._enabled, sprite._x1, sprite._x2, sprite._flags,
+ sprite._width, sprite._height, sprite._startPoint.x, sprite._startPoint.y,
+ sprite._lineSize, sprite._scriptId);
+ } else {
+ debugC(kDebugLoading, 4, "CH: %-3d castId: 000", i + 1);
+ }
}
}
@@ -539,6 +544,14 @@ void Frame::playTransition(Score *score) {
}
}
+void Frame::executeImmediateScripts() {
+ for (uint16 i = 0; i < CHANNEL_COUNT; i++) {
+ if (_vm->getCurrentScore()->_immediateActions.contains(_sprites[i]->_scriptId)) {
+ g_lingo->processEvent(kEventMouseUp, kFrameScript, _sprites[i]->_scriptId);
+ }
+ }
+}
+
void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
for (uint16 i = 0; i < CHANNEL_COUNT; i++) {
if (_sprites[i]->_enabled) {
@@ -563,18 +576,17 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
break;
}
} else {
- if (!_vm->getCurrentScore()->_casts.contains(_sprites[i]->_castId)) {
- if (!_vm->getSharedCasts()->contains(_sprites[i]->_castId)) {
+ if (!_vm->getCurrentScore()->_castTypes.contains(_sprites[i]->_castId)) {
+ if (!_vm->getSharedCastTypes()->contains(_sprites[i]->_castId)) {
warning("Cast id %d not found", _sprites[i]->_castId);
continue;
} else {
warning("Getting cast id %d from shared cast", _sprites[i]->_castId);
- cast = _vm->getSharedCasts()->getVal(_sprites[i]->_castId);
+ castType = _vm->getSharedCastTypes()->getVal(_sprites[i]->_castId);
}
} else {
- cast = _vm->getCurrentScore()->_casts[_sprites[i]->_castId];
+ castType = _vm->getCurrentScore()->_castTypes[_sprites[i]->_castId];
}
- castType = cast->type;
}
// this needs precedence to be hit first... D3 does something really tricky with cast IDs for shapes.
@@ -586,34 +598,15 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
} else if (castType == kCastButton) {
renderButton(surface, i, _vm->getVersion() < 4 ? _sprites[i]->_castId + 1024 : cast->children[0].index);
} else {
- Image::ImageDecoder *img = getImageFrom(_sprites[i]->_castId);
-
- if (!img) {
- warning("Image with id %d (%s) not found", _sprites[i]->_castId, numToCastNum(_sprites[i]->_castId));
- continue;
- }
-
- if (!img->getSurface()) {
- warning("Frame::renderSprites: Could not load image %d (%s)", _sprites[i]->_castId, numToCastNum(_sprites[i]->_castId));
- continue;
- }
-
- if (!_sprites[i]->_cast) {
+ if (!_sprites[i]->_bitmapCast) {
warning("No cast ID for sprite %d", i);
continue;
}
- BitmapCast *bitmapCast = static_cast<BitmapCast *>(_sprites[i]->_cast);
- // TODO: might want a quicker way to determine if cast is from Shared Cast.
- if (_vm->getSharedBMP() != NULL && _vm->getSharedBMP()->contains(_sprites[i]->_castId + 1024)) {
- debugC(2, kDebugImages, "Shared cast sprite BMP: id: %d", _sprites[i]->_castId + 1024);
- bitmapCast = static_cast<BitmapCast *>(_vm->getSharedCasts()->getVal(_sprites[i]->_castId));
- }
-
- uint32 regX = bitmapCast->regX;
- uint32 regY = bitmapCast->regY;
- uint32 rectLeft = bitmapCast->initialRect.left;
- uint32 rectTop = bitmapCast->initialRect.top;
+ uint32 regX = _sprites[i]->_bitmapCast->regX;
+ uint32 regY = _sprites[i]->_bitmapCast->regY;
+ uint32 rectLeft = _sprites[i]->_bitmapCast->initialRect.left;
+ uint32 rectTop = _sprites[i]->_bitmapCast->initialRect.top;
int x = _sprites[i]->_startPoint.x - regX + rectLeft;
int y = _sprites[i]->_startPoint.y - regY + rectTop;
@@ -621,9 +614,8 @@ void Frame::renderSprites(Graphics::ManagedSurface &surface, bool renderTrail) {
int width = _sprites[i]->_width;
Common::Rect drawRect(x, y, x + width, y + height);
-
addDrawRect(i, drawRect);
- inkBasedBlit(surface, *img->getSurface(), i, drawRect);
+ inkBasedBlit(surface, *(_sprites[i]->_bitmapCast->surface), i, drawRect);
}
}
}
@@ -667,15 +659,15 @@ void Frame::renderShape(Graphics::ManagedSurface &surface, uint16 spriteId) {
void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId, uint16 textId) {
uint16 castId = _sprites[spriteId]->_castId;
- ButtonCast *button = static_cast<ButtonCast *>(_vm->getCurrentScore()->_casts[castId]);
+ ButtonCast *button = _vm->getCurrentScore()->_loadedButtons->getVal(castId);
uint32 rectLeft = button->initialRect.left;
uint32 rectTop = button->initialRect.top;
int x = _sprites[spriteId]->_startPoint.x + rectLeft;
int y = _sprites[spriteId]->_startPoint.y + rectTop;
- int height = button->initialRect.height(); // _sprites[spriteId]->_height;
- int width = button->initialRect.width() + 3; // _sprites[spriteId]->_width;
+ int height = button->initialRect.height();
+ int width = button->initialRect.width() + 3;
Common::Rect textRect(0, 0, width, height);
// pass the rect of the button into the label.
@@ -706,73 +698,6 @@ void Frame::renderButton(Graphics::ManagedSurface &surface, uint16 spriteId, uin
}
}
-Image::ImageDecoder *Frame::getImageFrom(uint16 spriteId) {
- uint16 imgId = spriteId + 1024;
-
- if (_vm->getVersion() >= 4 && _vm->getCurrentScore()->_casts[spriteId]->children.size() > 0)
- imgId = _vm->getCurrentScore()->_casts[spriteId]->children[0].index;
-
- Image::ImageDecoder *img = NULL;
-
- if (_vm->getCurrentScore()->getArchive()->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) {
- img = new DIBDecoder();
- img->loadStream(*_vm->getCurrentScore()->getArchive()->getResource(MKTAG('D', 'I', 'B', ' '), imgId));
- return img;
- }
-
- if (_vm->getSharedDIB() != NULL && _vm->getSharedDIB()->contains(imgId)) {
- img = new DIBDecoder();
- img->loadStream(*_vm->getSharedDIB()->getVal(imgId));
- return img;
- }
-
- Common::SeekableReadStream *pic = NULL;
- BitmapCast *bc = NULL;
-
- if (_vm->getSharedBMP() != NULL && _vm->getSharedBMP()->contains(imgId)) {
- debugC(4, kDebugImages, "Shared cast BMP: id: %d", imgId);
- pic = _vm->getSharedBMP()->getVal(imgId);
- pic->seek(0); // TODO: this actually gets re-read every loop... we need to rewind it!
- bc = static_cast<BitmapCast *>(_vm->getSharedCasts()->getVal(spriteId));
- } else if (_vm->getCurrentScore()->getArchive()->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
- pic = _vm->getCurrentScore()->getArchive()->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
- bc = static_cast<BitmapCast *>(_vm->getCurrentScore()->_casts[spriteId]);
- }
-
- if (pic != NULL && bc != NULL) {
- if (_vm->getVersion() < 4) {
- int w = bc->initialRect.width(), h = bc->initialRect.height();
-
- debugC(4, kDebugImages, "id: %d, w: %d, h: %d, flags: %x, some: %x, unk1: %d, unk2: %d",
- imgId, w, h, bc->flags, bc->someFlaggyThing, bc->unk1, bc->unk2);
- img = new BITDDecoder(w, h);
- } else if (_vm->getVersion() < 6) {
- bc = static_cast<BitmapCast *>(_vm->getCurrentScore()->_casts[spriteId]);
- int w = bc->initialRect.width(), h = bc->initialRect.height();
-
- debugC(4, kDebugImages, "id: %d, w: %d, h: %d, flags: %x, some: %x, unk1: %d, unk2: %d",
- imgId, w, h, bc->flags, bc->someFlaggyThing, bc->unk1, bc->unk2);
- img = new BITDDecoderV4(w, h, bc->bitsPerPixel);
- } else {
- img = new Image::BitmapDecoder();
- }
-
- if (debugChannelSet(8, kDebugLoading)) {
- Common::SeekableReadStream *s = pic;
- byte buf[1024];
- int n = s->read(buf, 1024);
- Common::hexdump(buf, n);
- s->seek(0);
- }
-
- img->loadStream(*pic);
- return img;
- }
-
- warning("Image %d not found", spriteId);
- return img;
-}
-
void Frame::inkBasedBlit(Graphics::ManagedSurface &targetSurface, const Graphics::Surface &spriteSurface, uint16 spriteId, Common::Rect drawRect) {
switch (_sprites[spriteId]->_ink) {
case kInkTypeCopy:
@@ -818,7 +743,7 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteId, Commo
return;
uint16 castId = _sprites[spriteId]->_castId;
- TextCast *textCast = static_cast<TextCast *>(_vm->getCurrentScore()->_casts[castId]);
+ TextCast *textCast = _vm->getCurrentScore()->_loadedText->getVal(castId);
uint32 unk1 = textStream->readUint32();
uint32 strLen = textStream->readUint32();
@@ -906,8 +831,8 @@ void Frame::renderText(Graphics::ManagedSurface &surface, uint16 spriteId, Commo
int x = _sprites[spriteId]->_startPoint.x; // +rectLeft;
int y = _sprites[spriteId]->_startPoint.y; // +rectTop;
- int height = _sprites[spriteId]->_cast->initialRect.height(); //_sprites[spriteId]->_height;
- int width = _sprites[spriteId]->_cast->initialRect.width(); //_sprites[spriteId]->_width;
+ int height = textCast->initialRect.height(); //_sprites[spriteId]->_height;
+ int width = textCast->initialRect.width(); //_sprites[spriteId]->_width;
if (_vm->getVersion() >= 4 && textSize != NULL)
width = textCast->initialRect.right;
@@ -1143,4 +1068,13 @@ uint16 Frame::getSpriteIDFromPos(Common::Point pos) {
return 0;
}
+bool Frame::checkSpriteIntersection(uint16 spriteId, Common::Point pos) {
+ // Find first from front to back
+ for (int dr = _drawRects.size() - 1; dr >= 0; dr--)
+ if (_drawRects[dr]->spriteId == spriteId && _drawRects[dr]->rect.contains(pos))
+ return true;
+
+ return false;
+}
+
} // End of namespace Director
diff --git a/engines/director/frame.h b/engines/director/frame.h
index 704319ba0d..e2a4a1f37b 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -119,6 +119,9 @@ public:
void readChannel(Common::SeekableSubReadStreamEndian &stream, uint16 offset, uint16 size);
void prepareFrame(Score *score);
uint16 getSpriteIDFromPos(Common::Point pos);
+ bool checkSpriteIntersection(uint16 spriteId, Common::Point pos);
+
+ void executeImmediateScripts();
private:
void playTransition(Score *score);
diff --git a/engines/director/graphics.cpp b/engines/director/graphics.cpp
index 5322abcedf..46dab0f763 100644
--- a/engines/director/graphics.cpp
+++ b/engines/director/graphics.cpp
@@ -82,123 +82,126 @@ byte defaultPalette[768] = {
102, 255, 102, 153, 255, 102, 204, 255, 102, 255, 255, 153, 0, 255, 153, 51,
255, 153, 102, 255, 153, 153, 255, 153, 204, 255, 153, 255, 255, 204, 0, 255,
204, 51, 255, 204, 102, 255, 204, 153, 255, 204, 204, 255, 204, 255, 255, 255,
- 0, 255, 255, 51, 255, 255, 102, 255, 255, 153, 255, 255, 204, 255, 255, 255 };
-
-
-static byte director3Patterns[][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
- { 0xFF, 0xFF, 0x77, 0xFF, 0xFF, 0xFF, 0x77, 0xFF },
- { 0x77, 0xFF, 0xDD, 0xFF, 0x77, 0xFF, 0xDD, 0xFF },
- { 0xFF, 0xDD, 0xFF, 0x55, 0xFF, 0xDD, 0xFF, 0x55 },
- { 0xFF, 0xD5, 0xFF, 0x55, 0xFF, 0x5D, 0xFF, 0x55 },
- { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA },
- { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
- { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
- { 0xAA, 0x44, 0xAA, 0x00, 0xAA, 0x44, 0xAA, 0x00 },
- { 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00 },
- { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 },
- { 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00 },
- { 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 },
- { 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
- { 0x21, 0x42, 0x84, 0x09, 0x12, 0x24, 0x48, 0x90 },
- { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
- { 0xEE, 0xDD, 0xBB, 0x77, 0xEE, 0xDD, 0xBB, 0x77 },
- { 0xF6, 0xED, 0xDB, 0xB7, 0x6F, 0xDE, 0xBD, 0x7B },
- { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F },
- { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF },
- { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF },
- { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF },
- { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF },
- { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 },
- { 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00 },
- { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
- { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
- { 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82 },
- { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
- { 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94 },
- { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA },
- { 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD },
- { 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB },
- { 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7 },
- { 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF },
- { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00 },
- { 0x7F, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x00 },
- { 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00 },
- { 0x88, 0x88, 0x88, 0xFF, 0x88, 0x88, 0x88, 0xFF },
- { 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF },
- { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF },
- { 0x01, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82 },
- { 0x11, 0x82, 0x45, 0xAB, 0xD7, 0xAB, 0x45, 0x82 },
- { 0xF7, 0x7F, 0xBE, 0x5D, 0x2A, 0x5D, 0xBE, 0x7F },
- { 0xFE, 0x7D, 0xBB, 0xD7, 0xEF, 0xD7, 0xBB, 0x7D },
- { 0xFE, 0x7F, 0xBF, 0xDF, 0xEF, 0xDF, 0xBF, 0x7F },
- { 0xEE, 0x77, 0xBB, 0xDD, 0xEE, 0xDD, 0xBB, 0x77 },
- { 0x11, 0x88, 0x44, 0x22, 0x11, 0x22, 0x44, 0x88 },
- { 0x01, 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80 },
- { 0x22, 0x00, 0x01, 0x22, 0x54, 0x88, 0x01, 0x00 },
- { 0xBF, 0xAF, 0xAB, 0xAA, 0xEA, 0xFA, 0xFE, 0xFF },
- { 0xFF, 0xFF, 0xBE, 0x9C, 0xAA, 0xB6, 0xBE, 0xFF }
+ 0, 255, 255, 51, 255, 255, 102, 255, 255, 153, 255, 255, 204, 255, 255, 255
};
-static byte director3QuickDrawPatterns[][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
- { 0xDD, 0xFF, 0x77, 0xFF, 0xDD, 0xFF, 0x77, 0xFF },
- { 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77 },
- { 0xEE, 0xDD, 0xBB, 0x77, 0xEE, 0xDD, 0xBB, 0x77 },
- { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA },
- { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
- { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 },
- { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
- { 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00 },
- { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
- { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 },
- { 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08 },
- { 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 },
- { 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
- { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
- { 0x58, 0xDF, 0x00, 0xDF, 0xDF, 0x58, 0x58, 0x58 },
- { 0xB1, 0x36, 0x06, 0x60, 0x63, 0x1B, 0x18, 0x81 },
- { 0x08, 0xFF, 0x01, 0x01, 0x01, 0xFF, 0x08, 0x08 },
- { 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00 },
- { 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0x80 },
- { 0x80, 0x10, 0x02, 0x40, 0x04, 0x20, 0x09, 0x00 },
- { 0x80, 0x01, 0x82, 0x44, 0x38, 0x10, 0x20, 0x40 },
- { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 },
- { 0x22, 0xFF, 0x22, 0x22, 0x22, 0xFF, 0x22, 0x22 },
- { 0x00, 0x08, 0x14, 0x2A, 0x55, 0x2A, 0x14, 0x08 },
- { 0x81, 0xAA, 0x14, 0x08, 0x08, 0xAA, 0x41, 0x80 },
- { 0x3E, 0x1D, 0x88, 0xD1, 0xE3, 0xC5, 0x88, 0x5C },
- { 0xAA, 0x00, 0x80, 0x00, 0x88, 0x00, 0x80, 0x00 },
- { 0x00, 0x11, 0x82, 0x44, 0x28, 0x11, 0x00, 0x55 },
- { 0x7C, 0x10, 0x10, 0x28, 0xC7, 0x01, 0x01, 0x82 },
- { 0xEE, 0x31, 0xF1, 0xF1, 0xEE, 0x13, 0x1F, 0x1F },
- { 0x00, 0x40, 0x20, 0x10, 0x00, 0x01, 0x02, 0x04 },
- { 0x00, 0x00, 0x40, 0xA0, 0x00, 0x04, 0x0A, 0x00 },
- { 0x20, 0x60, 0x90, 0x09, 0x06, 0x81, 0x40, 0x20 },
- { 0x00, 0x7F, 0x43, 0x5F, 0x5F, 0x5F, 0x7F, 0x7F },
- { 0x01, 0x02, 0x45, 0xAA, 0xFF, 0x20, 0x40, 0x80 },
- { 0x00, 0x44, 0x0A, 0x11, 0x11, 0x11, 0x51, 0x24 },
- { 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0 },
- { 0xF8, 0xFC, 0xFA, 0xFC, 0xFA, 0x54, 0x2A, 0x00 },
- { 0x42, 0xC3, 0x3C, 0x3C, 0x3C, 0x3C, 0xC3, 0x42 },
- { 0x10, 0x38, 0x7C, 0xFE, 0x7D, 0x3A, 0x14, 0x08 },
- { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF },
- { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
- { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
- { 0xBB, 0xDD, 0xAE, 0x77, 0xEE, 0xDD, 0xAB, 0x77 },
- { 0x80, 0x40, 0x40, 0x20, 0x20, 0x18, 0x06, 0x01 },
- { 0x01, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82 },
- { 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF },
- { 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF },
- { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00 },
- { 0xC3, 0x87, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE1 },
- { 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0 },
- { 0xFF, 0xFF, 0xE7, 0xC3, 0x81, 0x18, 0x3C, 0x7E },
- { 0x1F, 0x8F, 0xC7, 0xE3, 0xC7, 0x8F, 0x1F, 0x3E },
- { 0xFF, 0x2A, 0xFF, 0xC8, 0xFF, 0x65, 0xFF, 0x9D }
+
+static byte director3Patterns[][8] = {
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+ { 0xFF, 0xFF, 0x77, 0xFF, 0xFF, 0xFF, 0x77, 0xFF },
+ { 0x77, 0xFF, 0xDD, 0xFF, 0x77, 0xFF, 0xDD, 0xFF },
+ { 0xFF, 0xDD, 0xFF, 0x55, 0xFF, 0xDD, 0xFF, 0x55 },
+ { 0xFF, 0xD5, 0xFF, 0x55, 0xFF, 0x5D, 0xFF, 0x55 },
+ { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA },
+ { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA },
+ { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
+ { 0xAA, 0x44, 0xAA, 0x00, 0xAA, 0x44, 0xAA, 0x00 },
+ { 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00 },
+ { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 },
+ { 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00 },
+ { 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 },
+ { 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 },
+ { 0x21, 0x42, 0x84, 0x09, 0x12, 0x24, 0x48, 0x90 },
+ { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
+ { 0xEE, 0xDD, 0xBB, 0x77, 0xEE, 0xDD, 0xBB, 0x77 },
+ { 0xF6, 0xED, 0xDB, 0xB7, 0x6F, 0xDE, 0xBD, 0x7B },
+ { 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F },
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF },
+ { 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF },
+ { 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF },
+ { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF },
+ { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 },
+ { 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00 },
+ { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
+ { 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
+ { 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82 },
+ { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
+ { 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94 },
+ { 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA },
+ { 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD, 0xAD },
+ { 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB },
+ { 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7, 0xB7 },
+ { 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF },
+ { 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x00 },
+ { 0x7F, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x7F, 0x00 },
+ { 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00 },
+ { 0x88, 0x88, 0x88, 0xFF, 0x88, 0x88, 0x88, 0xFF },
+ { 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0xFF },
+ { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF },
+ { 0x01, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82 },
+ { 0x11, 0x82, 0x45, 0xAB, 0xD7, 0xAB, 0x45, 0x82 },
+ { 0xF7, 0x7F, 0xBE, 0x5D, 0x2A, 0x5D, 0xBE, 0x7F },
+ { 0xFE, 0x7D, 0xBB, 0xD7, 0xEF, 0xD7, 0xBB, 0x7D },
+ { 0xFE, 0x7F, 0xBF, 0xDF, 0xEF, 0xDF, 0xBF, 0x7F },
+ { 0xEE, 0x77, 0xBB, 0xDD, 0xEE, 0xDD, 0xBB, 0x77 },
+ { 0x11, 0x88, 0x44, 0x22, 0x11, 0x22, 0x44, 0x88 },
+ { 0x01, 0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80 },
+ { 0x22, 0x00, 0x01, 0x22, 0x54, 0x88, 0x01, 0x00 },
+ { 0xBF, 0xAF, 0xAB, 0xAA, 0xEA, 0xFA, 0xFE, 0xFF },
+ { 0xFF, 0xFF, 0xBE, 0x9C, 0xAA, 0xB6, 0xBE, 0xFF }
+};
+
+static byte director3QuickDrawPatterns[][8] = {
+ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
+ { 0xDD, 0xFF, 0x77, 0xFF, 0xDD, 0xFF, 0x77, 0xFF },
+ { 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77 },
+ { 0xEE, 0xDD, 0xBB, 0x77, 0xEE, 0xDD, 0xBB, 0x77 },
+ { 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA },
+ { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
+ { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 },
+ { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
+ { 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00 },
+ { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
+ { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 },
+ { 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x04, 0x08 },
+ { 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00 },
+ { 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
+ { 0x58, 0xDF, 0x00, 0xDF, 0xDF, 0x58, 0x58, 0x58 },
+ { 0xB1, 0x36, 0x06, 0x60, 0x63, 0x1B, 0x18, 0x81 },
+ { 0x08, 0xFF, 0x01, 0x01, 0x01, 0xFF, 0x08, 0x08 },
+ { 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00 },
+ { 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0x80 },
+ { 0x80, 0x10, 0x02, 0x40, 0x04, 0x20, 0x09, 0x00 },
+ { 0x80, 0x01, 0x82, 0x44, 0x38, 0x10, 0x20, 0x40 },
+ { 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00 },
+ { 0x22, 0xFF, 0x22, 0x22, 0x22, 0xFF, 0x22, 0x22 },
+ { 0x00, 0x08, 0x14, 0x2A, 0x55, 0x2A, 0x14, 0x08 },
+ { 0x81, 0xAA, 0x14, 0x08, 0x08, 0xAA, 0x41, 0x80 },
+ { 0x3E, 0x1D, 0x88, 0xD1, 0xE3, 0xC5, 0x88, 0x5C },
+ { 0xAA, 0x00, 0x80, 0x00, 0x88, 0x00, 0x80, 0x00 },
+ { 0x00, 0x11, 0x82, 0x44, 0x28, 0x11, 0x00, 0x55 },
+ { 0x7C, 0x10, 0x10, 0x28, 0xC7, 0x01, 0x01, 0x82 },
+ { 0xEE, 0x31, 0xF1, 0xF1, 0xEE, 0x13, 0x1F, 0x1F },
+ { 0x00, 0x40, 0x20, 0x10, 0x00, 0x01, 0x02, 0x04 },
+ { 0x00, 0x00, 0x40, 0xA0, 0x00, 0x04, 0x0A, 0x00 },
+ { 0x20, 0x60, 0x90, 0x09, 0x06, 0x81, 0x40, 0x20 },
+ { 0x00, 0x7F, 0x43, 0x5F, 0x5F, 0x5F, 0x7F, 0x7F },
+ { 0x01, 0x02, 0x45, 0xAA, 0xFF, 0x20, 0x40, 0x80 },
+ { 0x00, 0x44, 0x0A, 0x11, 0x11, 0x11, 0x51, 0x24 },
+ { 0x0F, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0, 0xF0 },
+ { 0xF8, 0xFC, 0xFA, 0xFC, 0xFA, 0x54, 0x2A, 0x00 },
+ { 0x42, 0xC3, 0x3C, 0x3C, 0x3C, 0x3C, 0xC3, 0x42 },
+ { 0x10, 0x38, 0x7C, 0xFE, 0x7D, 0x3A, 0x14, 0x08 },
+ { 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF },
+ { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
+ { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
+ { 0xBB, 0xDD, 0xAE, 0x77, 0xEE, 0xDD, 0xAB, 0x77 },
+ { 0x80, 0x40, 0x40, 0x20, 0x20, 0x18, 0x06, 0x01 },
+ { 0x01, 0x82, 0x44, 0x28, 0x10, 0x28, 0x44, 0x82 },
+ { 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF },
+ { 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF, 0xFF },
+ { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00 },
+ { 0xC3, 0x87, 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xE1 },
+ { 0xF0, 0xF0, 0x0F, 0x0F, 0x0F, 0xF0, 0xF0, 0xF0 },
+ { 0xFF, 0xFF, 0xE7, 0xC3, 0x81, 0x18, 0x3C, 0x7E },
+ { 0x1F, 0x8F, 0xC7, 0xE3, 0xC7, 0x8F, 0x1F, 0x3E },
+ { 0xFF, 0x2A, 0xFF, 0xC8, 0xFF, 0x65, 0xFF, 0x9D }
};
void DirectorEngine::loadPatterns() {
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index f554f43cd8..cb6a7d67ec 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -21,7 +21,11 @@
*/
#include "common/system.h"
+#include "common/events.h"
+
#include "director/lingo/lingo.h"
+#include "director/frame.h"
+#include "director/sprite.h"
namespace Director {
@@ -379,7 +383,7 @@ void Lingo::printSTUBWithArglist(const char *funcname, int nargs, const char *pr
s += ")";
- warning("%s: %s", prefix, s.c_str());
+ warning("%s %s", prefix, s.c_str());
}
void Lingo::convertVOIDtoString(int arg, int nargs) {
@@ -1163,9 +1167,12 @@ void Lingo::b_move(int nargs) {
}
void Lingo::b_moveableSprite(int nargs) {
- g_lingo->printSTUBWithArglist("b_moveableSprite", nargs);
+ Frame *frame = g_director->getCurrentScore()->_frames[g_director->getCurrentScore()->getCurrentFrame()];
- g_lingo->dropStack(nargs);
+ // Will have no effect
+ frame->_sprites[g_lingo->_currentEntityId]->_moveable = true;
+
+ g_director->setDraggedSprite(frame->_sprites[g_lingo->_currentEntityId]->_castId);
}
void Lingo::b_pasteClipBoardInto(int nargs) {
@@ -1216,9 +1223,26 @@ void Lingo::b_ramNeeded(int nargs) {
void Lingo::b_rollOver(int nargs) {
Datum d = g_lingo->pop();
- warning("STUB: b_rollOver(%d)", d.u.i);
- g_lingo->push(Datum(0));
+ d.toInt();
+
+ int arg = d.u.i;
+
+ d.u.i = 0; // FALSE
+
+ Frame *frame = g_director->getCurrentScore()->_frames[g_director->getCurrentScore()->getCurrentFrame()];
+
+ if (arg >= frame->_sprites.size()) {
+ g_lingo->push(d);
+ return;
+ }
+
+ Common::Point pos = g_system->getEventManager()->getMousePos();
+
+ if (frame->checkSpriteIntersection(arg, pos))
+ d.u.i = 1; // TRUE
+
+ g_lingo->push(d);
}
void Lingo::b_spriteBox(int nargs) {
diff --git a/engines/director/lingo/lingo-code.cpp b/engines/director/lingo/lingo-code.cpp
index 7bc82eddcf..d0d29dd04c 100644
--- a/engines/director/lingo/lingo-code.cpp
+++ b/engines/director/lingo/lingo-code.cpp
@@ -307,10 +307,14 @@ void Lingo::c_assign() {
}
if (d1.type == REFERENCE) {
- if (!g_director->getCurrentScore()->_castsInfo.contains(d1.u.i)) {
- warning("c_assign: Unknown REFERENCE %d", d1.u.i);
- g_lingo->pushVoid();
- return;
+ if (!g_director->getCurrentScore()->_loadedText->contains(d1.u.i)) {
+ if (!g_director->getCurrentScore()->_loadedText->contains(d1.u.i - 1024)) {
+ warning("c_assign: Unknown REFERENCE %d", d1.u.i);
+ g_lingo->pushVoid();
+ return;
+ } else {
+ d1.u.i -= 1024;
+ }
}
warning("STUB: c_assing REFERENCE");
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 8f874435f7..68999f66ef 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -332,8 +332,8 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
switch (field) {
case kTheCastNum:
- if (_vm->getCurrentScore()->_casts.contains(d.u.i)) {
- sprite->_cast = _vm->getCurrentScore()->_casts[d.u.i];
+ if (_vm->getCurrentScore()->_castTypes.contains(d.u.i)) {
+ _vm->getCurrentScore()->loadCastInto(sprite, d.u.i);
sprite->_castId = d.u.i;
}
break;
@@ -638,9 +638,9 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
return d;
}
- Cast *cast;
+ CastType castType;
CastInfo *castInfo;
- if (!_vm->getCurrentScore()->_casts.contains(id)) {
+ if (!_vm->getCurrentScore()->_castTypes.contains(id)) {
if (field == kTheLoaded) {
d.type = INT;
d.u.i = 0;
@@ -651,14 +651,14 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
warning("The cast %d found", id);
}
- cast = _vm->getCurrentScore()->_casts[id];
+ castType = _vm->getCurrentScore()->_castTypes[id];
castInfo = _vm->getCurrentScore()->_castsInfo[id];
d.type = INT;
switch (field) {
case kTheCastType:
- d.u.i = cast->type;
+ d.u.i = castType;
break;
case kTheFileName:
d.toString();
@@ -673,32 +673,32 @@ Datum Lingo::getTheCast(Datum &id1, int field) {
d.u.s = &castInfo->script;
break;
case kTheWidth:
- d.u.i = cast->initialRect.width();
+ d.u.i = _vm->getCurrentScore()->getCastMemberInitialRect(id).width();
break;
case kTheHeight:
- d.u.i = cast->initialRect.height();
+ d.u.i = _vm->getCurrentScore()->getCastMemberInitialRect(id).height();
break;
case kTheBackColor:
{
- if (cast->type != kCastShape) {
+ if (castType != kCastShape) {
warning("Field %d of cast %d not found", field, id);
d.type = VOID;
return d;
}
- ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+ ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
d.u.i = shape->bgCol;
}
break;
case kTheForeColor:
{
- if (cast->type != kCastShape) {
+ if (castType != kCastShape) {
warning("Field %d of cast %d not found", field, id);
d.type = VOID;
return d;
}
- ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+ ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
d.u.i = shape->fgCol;
}
break;
@@ -729,18 +729,20 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
return;
}
- Cast *cast = _vm->getCurrentScore()->_casts[id];
+ CastType castType = _vm->getCurrentScore()->_castTypes[id];
CastInfo *castInfo = _vm->getCurrentScore()->_castsInfo[id];
- if (!cast) {
+ if (!castInfo) {
warning("The cast %d found", id);
return;
}
switch (field) {
case kTheCastType:
- cast->type = static_cast<CastType>(d.u.i);
- cast->modified = 1;
+ // TODO: You can actually switch the cast type!?
+ warning("Tried to switch cast type of %d", id);
+ //cast->type = static_cast<CastType>(d.u.i);
+ //cast->modified = 1;
break;
case kTheFileName:
castInfo->fileName = *d.u.s;
@@ -752,30 +754,30 @@ void Lingo::setTheCast(Datum &id1, int field, Datum &d) {
castInfo->script = *d.u.s;
break;
case kTheWidth:
- cast->initialRect.setWidth(d.u.i);
- cast->modified = 1;
+ _vm->getCurrentScore()->getCastMemberInitialRect(id).setWidth(d.u.i);
+ _vm->getCurrentScore()->setCastMemberModified(id);
break;
case kTheHeight:
- cast->initialRect.setHeight(d.u.i);
- cast->modified = 1;
+ _vm->getCurrentScore()->getCastMemberInitialRect(id).setHeight(d.u.i);
+ _vm->getCurrentScore()->setCastMemberModified(id);
break;
case kTheBackColor:
{
- if (cast->type != kCastShape) {
+ if (castType != kCastShape) {
warning("Field %d of cast %d not found", field, id);
}
- ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+ ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
shape->bgCol = d.u.i;
shape->modified = 1;
}
break;
case kTheForeColor:
{
- if (cast->type != kCastShape) {
+ if (castType != kCastShape) {
warning("Field %d of cast %d not found", field, id);
return;
}
- ShapeCast *shape = static_cast<ShapeCast *>(_vm->getCurrentScore()->_casts[id]);
+ ShapeCast *shape = _vm->getCurrentScore()->_loadedShapes->getVal(id);
shape->fgCol = d.u.i;
shape->modified = 1;
}
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 706f76777d..a51ff222c7 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -299,7 +299,7 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) {
if (entityId < 0)
return;
- debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d)", _eventHandlerTypes[event], scriptType2str(st), entityId);
+ debugC(9, kDebugEvents, "Lingo::processEvent(%s, %s, %d)", _eventHandlerTypes[event], scriptType2str(st), entityId);
_currentEntityId = entityId;
@@ -307,8 +307,11 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) {
error("processEvent: Unknown event %d for entity %d", event, entityId);
if (_handlers.contains(ENTITY_INDEX(event, entityId))) {
+ debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), _eventHandler", _eventHandlerTypes[event], scriptType2str(st), entityId);
call(_eventHandlerTypes[event], 0); // D4+ Events
} else if (_scripts[st].contains(entityId)) {
+ debugC(1, kDebugEvents, "Lingo::processEvent(%s, %s, %d), script", _eventHandlerTypes[event], scriptType2str(st), entityId);
+
executeScript(st, entityId); // D3 list of scripts.
} else {
debugC(3, kDebugLingoExec, "STUB: processEvent(%s) for %d", _eventHandlerTypes[event], entityId);
@@ -318,6 +321,13 @@ void Lingo::processEvent(LEvent event, ScriptType st, int entityId) {
void Lingo::restartLingo() {
warning("STUB: restartLingo()");
+ for (int i = 0; i <= kMaxScriptType; i++) {
+ for (ScriptHash::iterator it = _scripts[i].begin(); it != _scripts[i].end(); ++it)
+ delete it->_value;
+
+ _scripts[i].clear();
+ }
+
// TODO
//
// reset the following:
@@ -403,6 +413,9 @@ Common::String *Datum::toString() {
case VAR:
*s = Common::String::format("var: #%s", u.sym->name.c_str());
break;
+ case REFERENCE:
+ *s = Common::String::format("field#%d", u.i);
+ break;
default:
warning("Incorrect operation toString() for type: %s", type2str());
}
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 6dace8bcb2..7dbd5a78a6 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -76,6 +76,7 @@ void DirectorEngine::loadEXE(const Common::String movie) {
exeStream->seek(exeStream->readUint32LE());
switch (getVersion()) {
+ case 2:
case 3:
loadEXEv3(exeStream);
break;
@@ -100,12 +101,23 @@ void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) {
stream->skip(5); // unknown
- stream->readUint32LE(); // Main MMM size
+ uint32 mmmSize = stream->readUint32LE(); // Main MMM size
+
Common::String mmmFileName = stream->readPascalString();
Common::String directoryName = stream->readPascalString();
debugC(1, kDebugLoading, "Main MMM: '%s'", mmmFileName.c_str());
debugC(1, kDebugLoading, "Directory Name: '%s'", directoryName.c_str());
+ debugC(1, kDebugLoading, "Main mmmSize: %d (0x%x)", mmmSize, mmmSize);
+
+ if (mmmSize) {
+ uint32 riffOffset = stream->pos();
+
+ _mainArchive = new RIFFArchive();
+
+ if (!_mainArchive->openStream(stream, riffOffset))
+ error("Failed to load RIFF from EXE");
+ }
openMainArchive(mmmFileName);
@@ -200,19 +212,21 @@ void DirectorEngine::loadMac(const Common::String movie) {
void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Archive *shardcst = createArchive();
- debug(0, "Loading Shared cast '%s'", filename.c_str());
+ debug(0, "****** Loading Shared cast '%s'", filename.c_str());
+ _sharedDIB = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+ _sharedSTXT = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+ _sharedSound = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+ _sharedBMP = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
+
+ _sharedScore = new Score(this);
if (!shardcst->openFile(filename)) {
warning("No shared cast %s", filename.c_str());
return;
}
- _sharedDIB = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
- _sharedSTXT = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
- _sharedSound = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
- _sharedBMP = new Common::HashMap<int, Common::SeekableSubReadStreamEndian *>;
- _sharedScore = new Score(this, shardcst);
+ _sharedScore->setArchive(shardcst);
if (shardcst->hasResource(MKTAG('F', 'O', 'N', 'D'), -1)) {
debug("Shared cast has fonts. Loading....");
@@ -227,12 +241,16 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> cast = shardcst->getResourceIDList(MKTAG('C','A','S','t'));
if (cast.size() > 0) {
+ debug(0, "****** Loading %d CASt resources", cast.size());
+
for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator)
_sharedScore->loadCastData(*shardcst->getResource(MKTAG('C','A','S','t'), *iterator), *iterator, NULL);
}
Common::Array<uint16> vwci = shardcst->getResourceIDList(MKTAG('V', 'W', 'C', 'I'));
if (vwci.size() > 0) {
+ debug(0, "****** Loading %d CastInfo resources", vwci.size());
+
for (Common::Array<uint16>::iterator iterator = vwci.begin(); iterator != vwci.end(); ++iterator)
_sharedScore->loadCastInfo(*shardcst->getResource(MKTAG('V', 'W', 'C', 'I'), *iterator), *iterator);
}
@@ -241,7 +259,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> dib = shardcst->getResourceIDList(MKTAG('D','I','B',' '));
if (dib.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d DIBs", dib.size());
+ debugC(3, kDebugLoading, "****** Loading %d DIBs", dib.size());
for (Common::Array<uint16>::iterator iterator = dib.begin(); iterator != dib.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared DIB %d", *iterator);
@@ -251,7 +269,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> stxt = shardcst->getResourceIDList(MKTAG('S','T','X','T'));
if (stxt.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d STXTs", stxt.size());
+ debugC(3, kDebugLoading, "****** Loading %d STXTs", stxt.size());
for (Common::Array<uint16>::iterator iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared STXT %d", *iterator);
@@ -261,7 +279,7 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> bmp = shardcst->getResourceIDList(MKTAG('B','I','T','D'));
if (bmp.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d BITDs", bmp.size());
+ debugC(3, kDebugLoading, "****** Loading %d BITDs", bmp.size());
for (Common::Array<uint16>::iterator iterator = bmp.begin(); iterator != bmp.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared BITD %d (%s)", *iterator, numToCastNum(*iterator - 1024));
_sharedBMP->setVal(*iterator, shardcst->getResource(MKTAG('B','I','T','D'), *iterator));
@@ -270,12 +288,14 @@ void DirectorEngine::loadSharedCastsFrom(Common::String filename) {
Common::Array<uint16> sound = shardcst->getResourceIDList(MKTAG('S','N','D',' '));
if (sound.size() != 0) {
- debugC(3, kDebugLoading, "Loading %d SNDs", sound.size());
+ debugC(3, kDebugLoading, "****** Loading %d SNDs", sound.size());
for (Common::Array<uint16>::iterator iterator = sound.begin(); iterator != sound.end(); ++iterator) {
debugC(3, kDebugLoading, "Shared SND %d", *iterator);
_sharedSound->setVal(*iterator, shardcst->getResource(MKTAG('S','N','D',' '), *iterator));
}
}
+
+ _sharedScore->loadSpriteImages(true);
}
} // End of namespace Director
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 1ba0ab4683..472bd739c5 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -30,6 +30,7 @@
#include "graphics/palette.h"
#include "graphics/macgui/macfontmanager.h"
#include "graphics/macgui/macwindowmanager.h"
+#include "image/bmp.h"
#include "director/cast.h"
#include "director/score.h"
@@ -59,11 +60,10 @@ const char *scriptType2str(ScriptType scr) {
}
-Score::Score(DirectorEngine *vm, Archive *archive) {
+Score::Score(DirectorEngine *vm) {
_vm = vm;
_surface = new Graphics::ManagedSurface;
_trailSurface = new Graphics::ManagedSurface;
- _movieArchive = archive;
_lingo = _vm->getLingo();
_soundManager = _vm->getSoundManager();
_currentMouseDownSpriteId = 0;
@@ -87,6 +87,15 @@ Score::Score(DirectorEngine *vm, Archive *archive) {
_stopPlay = false;
_stageColor = 0;
+ _loadedBitmaps = new Common::HashMap<int, BitmapCast *>();
+ _loadedText = new Common::HashMap<int, TextCast *>();
+ _loadedButtons = new Common::HashMap<int, ButtonCast *>();
+ _loadedShapes = new Common::HashMap<int, ShapeCast *>();
+ _loadedScripts = new Common::HashMap<int, ScriptCast *>();
+}
+
+void Score::setArchive(Archive *archive) {
+ _movieArchive = archive;
if (archive->hasResource(MKTAG('M', 'C', 'N', 'M'), 0)) {
_macName = archive->getName(MKTAG('M', 'C', 'N', 'M'), 0).c_str();
} else {
@@ -111,6 +120,7 @@ void Score::loadArchive() {
} else {
Common::SeekableSubReadStreamEndian *pal = _movieArchive->getResource(MKTAG('C', 'L', 'U', 'T'), clutList[0]);
+ debugC(2, kDebugLoading, "****** Loading Palette");
loadPalette(*pal);
g_system->getPaletteManager()->setPalette(_vm->getPalette(), 0, _vm->getPaletteColorCount());
}
@@ -146,12 +156,16 @@ void Score::loadArchive() {
Common::Array<uint16> vwci = _movieArchive->getResourceIDList(MKTAG('V', 'W', 'C', 'I'));
if (vwci.size() > 0) {
+ debugC(2, kDebugLoading, "****** Loading %d CastInfos", vwci.size());
+
for (Common::Array<uint16>::iterator iterator = vwci.begin(); iterator != vwci.end(); ++iterator)
loadCastInfo(*_movieArchive->getResource(MKTAG('V', 'W', 'C', 'I'), *iterator), *iterator);
}
Common::Array<uint16> cast = _movieArchive->getResourceIDList(MKTAG('C', 'A', 'S', 't'));
if (cast.size() > 0) {
+ debugC(2, kDebugLoading, "****** Loading %d CASt resources", cast.size());
+
for (Common::Array<uint16>::iterator iterator = cast.begin(); iterator != cast.end(); ++iterator) {
Common::SeekableSubReadStreamEndian *stream = _movieArchive->getResource(MKTAG('C', 'A', 'S', 't'), *iterator);
Resource res = _movieArchive->getResourceDetail(MKTAG('C', 'A', 'S', 't'), *iterator);
@@ -160,11 +174,14 @@ void Score::loadArchive() {
}
setSpriteCasts();
+ loadSpriteImages(false);
// Try to load movie script, it sits in resource A11
if (_vm->getVersion() <= 3) {
Common::Array<uint16> stxt = _movieArchive->getResourceIDList(MKTAG('S','T','X','T'));
if (stxt.size() > 0) {
+ debugC(2, kDebugLoading, "****** Loading %d STXT resources", stxt.size());
+
for (Common::Array<uint16>::iterator iterator = stxt.begin(); iterator != stxt.end(); ++iterator) {
loadScriptText(*_movieArchive->getResource(MKTAG('S','T','X','T'), *iterator));
}
@@ -172,6 +189,65 @@ void Score::loadArchive() {
}
}
+void Score::loadSpriteImages(bool isSharedCast) {
+ debugC(1, kDebugLoading, "****** Preloading sprite images");
+
+ Common::HashMap<int, BitmapCast *>::iterator bc;
+ for (bc = _loadedBitmaps->begin(); bc != _loadedBitmaps->end(); ++bc) {
+ if (bc->_value) {
+ uint16 imgId = bc->_key + 1024;
+ BitmapCast *bitmapCast = bc->_value;
+
+ if (_vm->getVersion() >= 4 && bitmapCast->children.size() > 0)
+ imgId = bitmapCast->children[0].index;
+
+ Image::ImageDecoder *img = NULL;
+
+ if (_movieArchive->hasResource(MKTAG('D', 'I', 'B', ' '), imgId)) {
+ img = new DIBDecoder();
+ img->loadStream(*_movieArchive->getResource(MKTAG('D', 'I', 'B', ' '), imgId));
+ bitmapCast->surface = img->getSurface();
+ }
+
+ if (isSharedCast && _vm->getSharedDIB() != NULL && _vm->getSharedDIB()->contains(imgId)) {
+ img = new DIBDecoder();
+ img->loadStream(*_vm->getSharedDIB()->getVal(imgId));
+ bitmapCast->surface = img->getSurface();
+ }
+
+ Common::SeekableReadStream *pic = NULL;
+
+ if (isSharedCast) {
+ debugC(4, kDebugImages, "Shared cast BMP: id: %d", imgId);
+ pic = _vm->getSharedBMP()->getVal(imgId);
+ if (pic != NULL)
+ pic->seek(0); // TODO: this actually gets re-read every loop... we need to rewind it!
+ } else if (_movieArchive->hasResource(MKTAG('B', 'I', 'T', 'D'), imgId)) {
+ pic = _movieArchive->getResource(MKTAG('B', 'I', 'T', 'D'), imgId);
+ }
+
+ int w = bitmapCast->initialRect.width(), h = bitmapCast->initialRect.height();
+ debugC(4, kDebugImages, "id: %d, w: %d, h: %d, flags: %x, some: %x, unk1: %d, unk2: %d",
+ imgId, w, h, bitmapCast->flags, bitmapCast->someFlaggyThing, bitmapCast->unk1, bitmapCast->unk2);
+
+ if (pic != NULL && bitmapCast != NULL) {
+ if (_vm->getVersion() < 4) {
+ img = new BITDDecoder(w, h);
+ } else if (_vm->getVersion() < 6) {
+ img = new BITDDecoderV4(w, h, bitmapCast->bitsPerPixel);
+ } else {
+ img = new Image::BitmapDecoder();
+ }
+
+ img->loadStream(*pic);
+ bitmapCast->surface = img->getSurface();
+ }
+
+ warning("Image %d not found", imgId);
+ }
+ }
+}
+
Score::~Score() {
if (_surface)
_surface->free();
@@ -210,6 +286,8 @@ void Score::loadPalette(Common::SeekableSubReadStreamEndian &stream) {
}
void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(1, kDebugLoading, "****** Loading frames");
+
uint32 size = stream.readUint32();
size -= 4;
@@ -267,7 +345,7 @@ void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
//Common::hexdump(channelData, ARRAYSIZE(channelData));
frame->readChannels(str);
- debugC(3, kDebugLoading, "Frame %d actionId: %d", _frames.size() + 1, frame->_actionId);
+ debugC(3, kDebugLoading, "Frame %d actionId: %d", _frames.size(), frame->_actionId);
delete str;
@@ -276,6 +354,8 @@ void Score::loadFrames(Common::SeekableSubReadStreamEndian &stream) {
}
void Score::loadConfig(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(1, kDebugLoading, "****** Loading Config");
+
/*uint16 unk1 = */ stream.readUint16();
/*ver1 = */ stream.readUint16();
_movieRect = Score::readRect(stream);
@@ -295,7 +375,7 @@ void Score::readVersion(uint32 rid) {
}
void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
- debugC(1, kDebugLoading, "Score::loadCastDataVWCR(). start: %d, end: %d", _castArrayStart, _castArrayEnd);
+ debugC(1, kDebugLoading, "****** Score::loadCastDataVWCR(). start: %d, end: %d", _castArrayStart, _castArrayEnd);
for (uint16 id = _castArrayStart; id <= _castArrayEnd; id++) {
byte size = stream.readByte();
@@ -309,20 +389,24 @@ void Score::loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream) {
switch (castType) {
case kCastBitmap:
- _casts[id] = new BitmapCast(stream);
- _casts[id]->type = kCastBitmap;
+ debugC(3, kDebugLoading, "CastTypes id: %d BitmapCast", id);
+ _loadedBitmaps->setVal(id, new BitmapCast(stream));
+ _castTypes[id] = kCastBitmap;
break;
case kCastText:
- _casts[id] = new TextCast(stream);
- _casts[id]->type = kCastText;
+ debugC(3, kDebugLoading, "CastTypes id: %d TextCast", id);
+ _loadedText->setVal(id, new TextCast(stream));
+ _castTypes[id] = kCastText;
break;
case kCastShape:
- _casts[id] = new ShapeCast(stream);
- _casts[id]->type = kCastShape;
+ debugC(3, kDebugLoading, "CastTypes id: %d ShapeCast", id);
+ _loadedShapes->setVal(id, new ShapeCast(stream));
+ _castTypes[id] = kCastShape;
break;
case kCastButton:
- _casts[id] = new ButtonCast(stream);
- _casts[id]->type = kCastButton;
+ debugC(3, kDebugLoading, "CastTypes id: %d ButtonCast", id);
+ _loadedButtons->setVal(id, new ButtonCast(stream));
+ _castTypes[id] = kCastButton;
break;
default:
warning("Score::loadCastDataVWCR(): Unhandled cast type: %d", castType);
@@ -336,10 +420,34 @@ void Score::setSpriteCasts() {
// Set cast pointers to sprites
for (uint16 i = 0; i < _frames.size(); i++) {
for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
- byte castId = _frames[i]->_sprites[j]->_castId;
+ uint16 castId = _frames[i]->_sprites[j]->_castId;
+
+ if (_vm->getSharedScore()->_loadedBitmaps->contains(castId)) {
+ _frames[i]->_sprites[j]->_bitmapCast = _vm->getSharedScore()->_loadedBitmaps->getVal(castId);
+ } else if (_loadedBitmaps->contains(castId)) {
+ _frames[i]->_sprites[j]->_bitmapCast = _loadedBitmaps->getVal(castId);
+ }
+
+ if (_vm->getSharedScore()->_loadedButtons->contains(castId)) {
+ _frames[i]->_sprites[j]->_buttonCast = _vm->getSharedScore()->_loadedButtons->getVal(castId);
+ } else if (_loadedButtons->contains(castId)) {
+ _frames[i]->_sprites[j]->_buttonCast = _loadedButtons->getVal(castId);
+ }
+
+ //if (_loadedScripts->contains(castId))
+ // _frames[i]->_sprites[j]->_bitmapCast = _loadedBitmaps->getVal(castId);
+
+ if (_vm->getSharedScore()->_loadedText->contains(castId)) {
+ _frames[i]->_sprites[j]->_textCast = _vm->getSharedScore()->_loadedText->getVal(castId);
+ } else if (_loadedText->contains(castId)) {
+ _frames[i]->_sprites[j]->_textCast = _loadedText->getVal(castId);
+ }
- if (_casts.contains(castId))
- _frames[i]->_sprites[j]->_cast = _casts.find(castId)->_value;
+ if (_vm->getSharedScore()->_loadedShapes->contains(castId)) {
+ _frames[i]->_sprites[j]->_shapeCast = _vm->getSharedScore()->_loadedShapes->getVal(castId);
+ } else if (_loadedShapes->contains(castId)) {
+ _frames[i]->_sprites[j]->_shapeCast = _loadedShapes->getVal(castId);
+ }
}
}
}
@@ -398,35 +506,32 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
switch (castType) {
case kCastBitmap:
- _casts[id] = new BitmapCast(castStream, _vm->getVersion());
- _casts[id]->type = kCastBitmap;
+ _loadedBitmaps->setVal(id, new BitmapCast(castStream, _vm->getVersion()));
+ for (uint child = 0; child < res->children.size(); child++)
+ _loadedBitmaps->getVal(id)->children.push_back(res->children[child]);
+ _castTypes[id] = kCastBitmap;
break;
case kCastText:
- _casts[id] = new TextCast(castStream, _vm->getVersion());
- _casts[id]->type = kCastText;
+ _loadedText->setVal(id, new TextCast(castStream, _vm->getVersion()));
+ _castTypes[id] = kCastText;
break;
case kCastShape:
- _casts[id] = new ShapeCast(castStream, _vm->getVersion());
- _casts[id]->type = kCastShape;
+ _loadedShapes->setVal(id, new ShapeCast(castStream, _vm->getVersion()));
+ _castTypes[id] = kCastShape;
break;
case kCastButton:
- _casts[id] = new ButtonCast(castStream, _vm->getVersion());
- _casts[id]->type = kCastButton;
+ _loadedButtons->setVal(id, new ButtonCast(castStream, _vm->getVersion()));
+ _castTypes[id] = kCastButton;
break;
case kCastLingoScript:
- _casts[id] = new ScriptCast(castStream, _vm->getVersion());
- _casts[id]->type = kCastLingoScript;
+ _loadedScripts->setVal(id, new ScriptCast(castStream, _vm->getVersion()));
+ _castTypes[id] = kCastLingoScript;
break;
default:
warning("Score::loadCastData(): Unhandled cast type: %d", castType);
break;
}
- if (res != NULL) {
- for (uint child = 0; child < res->children.size(); child++)
- _casts[id]->children.push_back(res->children[child]);
- }
-
free(data);
if (size2) {
@@ -467,6 +572,60 @@ void Score::loadCastData(Common::SeekableSubReadStreamEndian &stream, uint16 id,
warning("size3: %x", size3);
}
+void Score::loadCastInto(Sprite *sprite, int castId) {
+ switch (_castTypes[castId]) {
+ case kCastBitmap:
+ sprite->_bitmapCast = _loadedBitmaps->getVal(castId);
+ break;
+ case kCastShape:
+ sprite->_shapeCast = _loadedShapes->getVal(castId);
+ break;
+ case kCastButton:
+ sprite->_buttonCast = _loadedButtons->getVal(castId);
+ break;
+ case kCastText:
+ sprite->_textCast = _loadedText->getVal(castId);
+ break;
+ default:
+ warning("Score::loadCastInto(..., %d): Unhandled castType %d", castId, _castTypes[castId]);
+ }
+}
+
+Common::Rect Score::getCastMemberInitialRect(int castId) {
+ switch (_castTypes[castId]) {
+ case kCastBitmap:
+ return _loadedBitmaps->getVal(castId)->initialRect;
+ case kCastShape:
+ return _loadedShapes->getVal(castId)->initialRect;
+ case kCastButton:
+ return _loadedButtons->getVal(castId)->initialRect;
+ case kCastText:
+ return _loadedText->getVal(castId)->initialRect;
+ default:
+ warning("Score::getCastMemberInitialRect(%d): Unhandled castType %d", castId, _castTypes[castId]);
+ return Common::Rect(0, 0);
+ }
+}
+
+void Score::setCastMemberModified(int castId) {
+ switch (_castTypes[castId]) {
+ case kCastBitmap:
+ _loadedBitmaps->getVal(castId)->modified = 1;
+ break;
+ case kCastShape:
+ _loadedShapes->getVal(castId)->modified = 1;
+ break;
+ case kCastButton:
+ _loadedButtons->getVal(castId)->modified = 1;
+ break;
+ case kCastText:
+ _loadedText->getVal(castId)->modified = 1;
+ break;
+ default:
+ warning("Score::setCastMemberModified(%d): Unhandled castType %d", castId, _castTypes[castId]);
+ }
+}
+
void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) {
_labels = new Common::SortedArray<Label *>(compareLabels);
uint16 count = stream.readUint16() + 1;
@@ -496,6 +655,7 @@ void Score::loadLabels(Common::SeekableSubReadStreamEndian &stream) {
Common::SortedArray<Label *>::iterator j;
+ debugC(2, kDebugLoading, "****** Loading labels");
for (j = _labels->begin(); j != _labels->end(); ++j) {
debugC(2, kDebugLoading, "Frame %d, Label %s", (*j)->number, (*j)->name.c_str());
}
@@ -506,6 +666,8 @@ int Score::compareLabels(const void *a, const void *b) {
}
void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(2, kDebugLoading, "****** Loading Actions");
+
uint16 count = stream.readUint16() + 1;
uint16 offset = count * 4 + 2;
@@ -530,7 +692,7 @@ void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
_actions[i + 1] += ch;
}
- debugC(3, kDebugLoading, "id: %d nextId: %d subId: %d, code: %s", id, nextId, subId, _actions[id].c_str());
+ debugC(3, kDebugLoading, "Action id: %d nextId: %d subId: %d, code: %s", id, nextId, subId, _actions[id].c_str());
stream.seek(streamPos);
@@ -551,8 +713,22 @@ void Score::loadActions(Common::SeekableSubReadStreamEndian &stream) {
}
for (j = _actions.begin(); j != _actions.end(); ++j)
- if (!j->_value.empty())
+ if (!j->_value.empty()) {
_lingo->addCode(j->_value.c_str(), kFrameScript, j->_key);
+
+ processImmediateFrameScript(j->_value, j->_key);
+ }
+}
+
+bool Score::processImmediateFrameScript(Common::String s, int id) {
+ s.trim();
+
+ // In D2/D3 this specifies immediately the sprite/field properties
+ if (!s.compareToIgnoreCase("moveableSprite") || !s.compareToIgnoreCase("editableText")) {
+ _immediateActions[id] = true;
+ }
+
+ return false;
}
void Score::loadScriptText(Common::SeekableSubReadStreamEndian &stream) {
@@ -621,6 +797,9 @@ void Score::dumpScript(const char *script, ScriptType type, uint16 id) {
case kCastScript:
typeName = "cast";
break;
+ case kGlobalScript:
+ typeName = "global";
+ break;
}
sprintf(buf, "./dumps/%s-%s-%d.txt", _macName.c_str(), typeName.c_str(), id);
@@ -776,6 +955,8 @@ Common::String Score::getString(Common::String str) {
}
void Score::loadFileInfo(Common::SeekableSubReadStreamEndian &stream) {
+ debugC(2, kDebugLoading, "****** Loading FileInfo");
+
Common::Array<Common::String> fileInfoStrings = loadStrings(stream, _flags);
_script = fileInfoStrings[0];
@@ -805,6 +986,8 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
uint16 count = stream.readUint16() + 1;
+ debugC(3, kDebugLoading, "Strings: %d entries", count);
+
uint32 *entries = (uint32 *)calloc(count, sizeof(uint32));
for (uint i = 0; i < count; i++)
@@ -823,6 +1006,8 @@ Common::Array<Common::String> Score::loadStrings(Common::SeekableSubReadStreamEn
entryString += data[j];
strings.push_back(entryString);
+
+ debugC(6, kDebugLoading, "String %d:\n%s\n", i, entryString.c_str());
}
free(data);
@@ -835,6 +1020,8 @@ void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
if (stream.size() == 0)
return;
+ debugC(2, kDebugLoading, "****** Loading FontMap");
+
uint16 count = stream.readUint16();
uint32 offset = (count * 2) + 2;
uint16 currentRawPosition = offset;
@@ -855,7 +1042,7 @@ void Score::loadFontMap(Common::SeekableSubReadStreamEndian &stream) {
_fontMap[id] = font;
_vm->_wm->_fontMan->registerFontMapping(id, font);
- debug(3, "Fontmap. ID %d Font %s", id, font.c_str());
+ debugC(3, kDebugLoading, "Fontmap. ID %d Font %s", id, font.c_str());
currentRawPosition = stream.pos();
stream.seek(positionInfo);
}
@@ -902,9 +1089,10 @@ void Score::update() {
_surface->clear();
_surface->copyFrom(*_trailSurface);
+ _frames[_currentFrame]->executeImmediateScripts();
+
// Enter and exit from previous frame (Director 4)
_lingo->processEvent(kEventEnterFrame, kFrameScript, _frames[_currentFrame]->_actionId);
- _lingo->processEvent(kEventExitFrame, kFrameScript, _frames[_currentFrame]->_actionId);
// TODO Director 6 - another order
// TODO Director 6 step: send beginSprite event to any sprites whose span begin in the upcoming frame
@@ -972,6 +1160,8 @@ void Score::update() {
}
}
+ _lingo->processEvent(kEventExitFrame, kFrameScript, _frames[_currentFrame]->_actionId);
+
_nextFrameTime = g_system->getMillis() + (float)_currentFrameRate / 60 * 1000;
}
diff --git a/engines/director/score.h b/engines/director/score.h
index 3e7aa62c4f..021dcb5577 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -26,6 +26,8 @@
#include "common/substream.h"
#include "common/rect.h"
#include "director/archive.h"
+#include "director/cast.h"
+#include "director/images.h"
namespace Graphics {
class ManagedSurface;
@@ -48,15 +50,16 @@ enum ScriptType {
kSpriteScript = 1,
kFrameScript = 2,
kCastScript = 3,
+ kGlobalScript = 4,
kNoneScript = -1,
- kMaxScriptType = 3
+ kMaxScriptType = 4
};
const char *scriptType2str(ScriptType scr);
class Score {
public:
- Score(DirectorEngine *vm, Archive *);
+ Score(DirectorEngine *vm);
~Score();
static Common::Rect readRect(Common::ReadStreamEndian &stream);
@@ -67,6 +70,7 @@ public:
void gotoNext();
void gotoPrevious();
void startLoop();
+ void setArchive(Archive *archive);
Archive *getArchive() const { return _movieArchive; };
void loadConfig(Common::SeekableSubReadStreamEndian &stream);
void loadCastDataVWCR(Common::SeekableSubReadStreamEndian &stream);
@@ -77,8 +81,13 @@ public:
Common::String getMacName() const { return _macName; }
Sprite *getSpriteById(uint16 id);
void setSpriteCasts();
+ void loadSpriteImages(bool isSharedCast);
Graphics::ManagedSurface *getSurface() { return _surface; }
+ void loadCastInto(Sprite *sprite, int castId);
+ Common::Rect getCastMemberInitialRect(int castId);
+ void setCastMemberModified(int castId);
+
int getPreviousLabelNumber(int referenceFrame);
int getCurrentLabelNumber();
int getNextLabelNumber(int referenceFrame);
@@ -97,13 +106,16 @@ private:
Common::String getString(Common::String str);
Common::Array<Common::String> loadStrings(Common::SeekableSubReadStreamEndian &stream, uint32 &entryType, bool hasHeader = true);
+ bool processImmediateFrameScript(Common::String s, int id);
+
public:
Common::Array<Frame *> _frames;
- Common::HashMap<int, Cast *> _casts;
+ Common::HashMap<int, CastType> _castTypes;
Common::HashMap<uint16, CastInfo *> _castsInfo;
Common::HashMap<Common::String, int> _castsNames;
Common::SortedArray<Label *> *_labels;
Common::HashMap<uint16, Common::String> _actions;
+ Common::HashMap<uint16, bool> _immediateActions;
Common::HashMap<uint16, Common::String> _fontMap;
Graphics::ManagedSurface *_surface;
Graphics::ManagedSurface *_trailSurface;
@@ -115,6 +127,13 @@ public:
bool _stopPlay;
uint32 _nextFrameTime;
+ Common::HashMap<int, ButtonCast *> *_loadedButtons;
+ Common::HashMap<int, TextCast *> *_loadedText;
+ //Common::HashMap<int, SoundCast *> _loadedSound;
+ Common::HashMap<int, BitmapCast *> *_loadedBitmaps;
+ Common::HashMap<int, ShapeCast *> *_loadedShapes;
+ Common::HashMap<int, ScriptCast *> *_loadedScripts;
+
private:
uint16 _versionMinor;
uint16 _versionMajor;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 019966762e..9d219d6076 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -53,7 +53,11 @@ Sprite::Sprite() {
_stretch = 0;
_type = kInactiveSprite;
- _cast = nullptr;
+ _bitmapCast = nullptr;
+ _textCast = nullptr;
+ _buttonCast = nullptr;
+ _shapeCast = nullptr;
+
_blend = 0;
_lineSize = 1;
@@ -90,7 +94,11 @@ Sprite::Sprite(const Sprite &sprite) {
_stretch = sprite._stretch;
_type = sprite._type;
- _cast = sprite._cast;
+ _bitmapCast = sprite._bitmapCast;
+ _shapeCast = sprite._shapeCast;
+ _textCast = sprite._textCast;
+ _buttonCast = sprite._buttonCast;
+
_constraint = sprite._constraint;
_moveable = sprite._moveable;
_blend = sprite._blend;
@@ -107,7 +115,14 @@ Sprite::Sprite(const Sprite &sprite) {
}
Sprite::~Sprite() {
- delete _cast;
+ if (_bitmapCast)
+ delete _bitmapCast;
+ if (_shapeCast)
+ delete _shapeCast;
+ if (_textCast)
+ delete _textCast;
+ if (_buttonCast)
+ delete _buttonCast;
}
} // End of namespace Director
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index c43418828c..de1965dc2a 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -110,7 +110,14 @@ public:
byte _spriteType;
InkType _ink;
uint16 _trails;
- Cast *_cast;
+
+ BitmapCast *_bitmapCast;
+ ShapeCast *_shapeCast;
+ //SoundCast *_soundCast;
+ TextCast *_textCast;
+ ButtonCast *_buttonCast;
+ //ScriptCast *_scriptCast;
+
uint16 _flags;
Common::Point _startPoint;
uint16 _width;
diff --git a/engines/director/util.cpp b/engines/director/util.cpp
index ccde2b3127..dbd1cd351f 100644
--- a/engines/director/util.cpp
+++ b/engines/director/util.cpp
@@ -48,7 +48,7 @@ char *numToCastNum(int num) {
res[3] = '\0';
num--;
- if (num > 0 && num <= 512) {
+ if (num >= 0 && num < 512) {
int c = num / 64;
res[0] = 'A' + c;
num -= 64 * c;
diff --git a/engines/mohawk/detection_tables.h b/engines/mohawk/detection_tables.h
index 9cc52a78b3..7da3c14633 100644
--- a/engines/mohawk/detection_tables.h
+++ b/engines/mohawk/detection_tables.h
@@ -48,6 +48,24 @@ static const MohawkGameDescription gameDescriptions[] = {
0,
},
+ // Myst
+ // English Windows 3.11, v1.0
+ // From vonLeheCreative, #9645
+ {
+ {
+ "myst",
+ "",
+ AD_ENTRY1("MYST.DAT", "0e4b6fcbd2419d4371365314fb7443f8"),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_NO_FLAGS,
+ GUI_OPTIONS_MYST
+ },
+ GType_MYST,
+ 0,
+ 0,
+ },
+
// Myst Demo
// English Windows 3.11
// From CD-ROM Today July, 1994
diff --git a/engines/mohawk/myst_scripts.cpp b/engines/mohawk/myst_scripts.cpp
index 596180ddb2..267d644b65 100644
--- a/engines/mohawk/myst_scripts.cpp
+++ b/engines/mohawk/myst_scripts.cpp
@@ -355,7 +355,26 @@ void MystScriptParser::o_changeCardSwitchRtL(uint16 op, uint16 var, uint16 argc,
}
void MystScriptParser::o_takePage(uint16 op, uint16 var, uint16 argc, uint16 *argv) {
- uint16 cursorId = argv[0];
+ // In most game releases, the first opcode argument is the new mouse cursor.
+ // However, in the original v1.0 English release this opcode takes no argument.
+ uint16 cursorId; // = argv[0];
+ switch (var) {
+ case 41: // Vault white page
+ cursorId = kWhitePageCursor;
+ break;
+ case 25: // Fireplace red page
+ case 102: // Red page
+ cursorId = kRedPageCursor;
+ break;
+ case 24: // Fireplace blue page
+ case 103: // Blue page
+ cursorId = kBluePageCursor;
+ break;
+ default:
+ warning("Unexpected take page variable '%d'", var);
+ cursorId = kDefaultMystCursor;
+ }
+
uint16 oldPage = _globals.heldPage;
debugC(kDebugScript, "Opcode %d: takePage Var %d CursorId %d", op, var, cursorId);
diff --git a/engines/mohawk/myst_stacks/channelwood.cpp b/engines/mohawk/myst_stacks/channelwood.cpp
index 21c3042359..f006a8e3ea 100644
--- a/engines/mohawk/myst_stacks/channelwood.cpp
+++ b/engines/mohawk/myst_stacks/channelwood.cpp
@@ -368,6 +368,7 @@ void Channelwood::o_waterTankValveOpen(uint16 op, uint16 var, uint16 argc, uint1
for (uint i = 0; i < 2; i++)
for (uint16 imageId = 3601; imageId >= 3595; imageId--) {
_vm->_gfx->copyImageToScreen(imageId, rect);
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
@@ -699,6 +700,7 @@ void Channelwood::o_waterTankValveClose(uint16 op, uint16 var, uint16 argc, uint
for (uint i = 0; i < 2; i++)
for (uint16 imageId = 3595; imageId <= 3601; imageId++) {
_vm->_gfx->copyImageToScreen(imageId, rect);
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
diff --git a/engines/mohawk/myst_stacks/myst.cpp b/engines/mohawk/myst_stacks/myst.cpp
index f9ba6a42fa..424dd2f07c 100644
--- a/engines/mohawk/myst_stacks/myst.cpp
+++ b/engines/mohawk/myst_stacks/myst.cpp
@@ -864,6 +864,7 @@ void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, uint16 argc, uint16 *a
// Unset button
for (uint i = 4795; i >= 4779; i--) {
_vm->_gfx->copyImageToScreen(i, getInvokingResource<MystArea>()->getRect());
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
_fireplaceLines[var - 17] &= ~bitmask;
@@ -871,6 +872,7 @@ void Myst::o_fireplaceToggleButton(uint16 op, uint16 var, uint16 argc, uint16 *a
// Set button
for (uint i = 4779; i <= 4795; i++) {
_vm->_gfx->copyImageToScreen(i, getInvokingResource<MystArea>()->getRect());
+ _vm->pollAndDiscardEvents();
_vm->_system->updateScreen();
}
_fireplaceLines[var - 17] |= bitmask;
diff --git a/engines/sci/engine/script_patches.cpp b/engines/sci/engine/script_patches.cpp
index c542be7ef2..cf3a981347 100644
--- a/engines/sci/engine/script_patches.cpp
+++ b/engines/sci/engine/script_patches.cpp
@@ -103,6 +103,7 @@ static const char *const selectorNameTable[] = {
"modNum", // King's Quest 6 CD / Laura Bow 2 CD for audio+text support
"cycler", // Space Quest 4 / system selector
"setLoop", // Laura Bow 1 Colonel's Bequest
+ "ignoreActors", // Laura Bow 1 Colonel's Bequest
#ifdef ENABLE_SCI32
"newWith", // SCI2 array script
"scrollSelections", // GK2
@@ -135,7 +136,8 @@ enum ScriptPatcherSelectors {
SELECTOR_startAudio,
SELECTOR_modNum,
SELECTOR_cycler,
- SELECTOR_setLoop
+ SELECTOR_setLoop,
+ SELECTOR_ignoreActors
#ifdef ENABLE_SCI32
,
SELECTOR_newWith,
@@ -554,14 +556,12 @@ static const uint16 freddypharkasSignatureIntroScaling[] = {
static const uint16 freddypharkasPatchIntroScaling[] = {
// remove setLoop(), objects in heap are already prepared, saves 5 bytes
0x38,
- PATCH_GETORIGINALBYTE(+6),
- PATCH_GETORIGINALBYTE(+7), // pushi (setStep)
+ PATCH_GETORIGINALUINT16(+6), // pushi (setStep)
0x7a, // push2
0x39, 0x05, // pushi 05
0x3c, // dup
0x72,
- PATCH_GETORIGINALBYTE(+13),
- PATCH_GETORIGINALBYTE(+14), // lofsa (view)
+ PATCH_GETORIGINALUINT16(+13), // lofsa (view)
0x4a, 0x18, // send 18 - adjusted
0x35, 0x0a, // ldi 0a
0xa3, 0x02, // sal local[2]
@@ -1314,8 +1314,7 @@ static const uint16 kq6PatchInventoryStackFix[] = {
0x12, // and
0x65, 0x30, // aTop state
0x38, // pushi "show"
- PATCH_GETORIGINALBYTE(+22),
- PATCH_GETORIGINALBYTE(+23),
+ PATCH_GETORIGINALUINT16(+22),
0x78, // push1
0x87, 0x00, // lap param[0]
0x31, 0x04, // bnt [call show using global 0]
@@ -1600,8 +1599,7 @@ static const uint16 kq6CDPatchAudioTextSupport3[] = {
0x65, 0x12, // aTop dialog
// followed by original addText-calling code
0x38,
- PATCH_GETORIGINALBYTE(+95),
- PATCH_GETORIGINALBYTE(+96), // pushi addText
+ PATCH_GETORIGINALUINT16(+95), // pushi (addText)
0x78, // push1
0x8f, 0x02, // lsp param[2]
0x59, 0x03, // &rest 03
@@ -1949,8 +1947,7 @@ static const uint16 kq7PatchSubtitleFix3[] = {
PATCH_ADDTOOFFSET(+2), // skip over "pToa initialized code"
0x2f, 0x0c, // bt [skip init code] - saved 1 byte
0x38,
- PATCH_GETORIGINALBYTE(+6),
- PATCH_GETORIGINALBYTE(+7), // pushi (init)
+ PATCH_GETORIGINALUINT16(+6), // pushi (init)
0x76, // push0
0x54, PATCH_UINT16(0x0004), // self 04
// additionally set background color here (5 bytes)
@@ -2488,12 +2485,79 @@ static const uint16 laurabow1PatchArmorOilingArmFix[] = {
PATCH_END
};
+// When you tell Lilly about Gertie in room 35, Lilly will then walk to the left and off the screen.
+// In case Laura (ego) is in the way, the whole game will basically block and you won't be able
+// to do anything except saving + restoring the game.
+//
+// If this happened already, the player can enter
+// "send Lillian ignoreActors 1" inside the debugger to fix this situation.
+//
+// This issue is very difficult to solve, because Lilly also walks diagonally after walking to the left right
+// under the kitchen table. This means that even if we added a few more rectangle checks, there could still be
+// spots, where the game would block.
+//
+// Also the mover "PathOut" is used for Lillian instead of the regular "MoveTo", which would avoid other
+// actors by itself.
+//
+// So instead we set Lilly to ignore other actors during that cutscene, which is the least invasive solution.
+//
+// Applies to at least: English PC Floppy, English Amiga Floppy, English Atari ST Floppy
+// Responsible method: goSee::changeState(1) in script 236
+// Fixes bug: (happened during GOG Let's Play)
+static const uint16 laurabow1SignatureTellLillyAboutGerieBlockingFix1[] = {
+ 0x7a, // puah2
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x00c1), // pushi 00C1h
+ 0x38, SIG_UINT16(0x008f), // pushi 008Fh
+ 0x38, SIG_SELECTOR16(ignoreActors), // pushi (ignoreActors)
+ 0x78, // push1
+ 0x76, // push0
+ SIG_END
+};
+
+static const uint16 laurabow1PatchTellLillyAboutGertieBlockingFix1[] = {
+ PATCH_ADDTOOFFSET(+11), // skip over until push0
+ 0x78, // push1 (change push0 to push1)
+ PATCH_END
+};
+
+// a second patch to call Lillian::ignoreActors(1) on goSee::changeState(9) in script 236
+static const uint16 laurabow1SignatureTellLillyAboutGerieBlockingFix2[] = {
+ 0x3c, // dup
+ 0x35, 0x09, // ldi 09
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x003f), // bnt [ret]
+ 0x39, SIG_ADDTOOFFSET(+1), // pushi (view)
+ 0x78, // push1
+ 0x38, SIG_UINT16(0x0203), // pushi 203h (515d)
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi (posn)
+ 0x7a, // push2
+ 0x38, SIG_UINT16(0x00c9), // pushi C9h (201d)
+ SIG_MAGICDWORD,
+ 0x38, SIG_UINT16(0x0084), // pushi 84h (132d)
+ 0x72, SIG_ADDTOOFFSET(+2), // lofsa Lillian (different offsets for different platforms)
+ 0x4a, 0x0e, // send 0Eh
+ SIG_END
+};
+
+static const uint16 laurabow1PatchTellLillyAboutGertieBlockingFix2[] = {
+ 0x38, PATCH_SELECTOR16(ignoreActors), // pushi (ignoreActors)
+ 0x78, // push1
+ 0x76, // push0
+ 0x33, 0x00, // ldi 00 (waste 2 bytes)
+ PATCH_ADDTOOFFSET(+19), // skip over until send
+ 0x4a, 0x14, // send 14h
+ PATCH_END
+};
+
// script, description, signature patch
static const SciScriptPatcherEntry laurabow1Signatures[] = {
- { true, 4, "easter egg view fix", 1, laurabow1SignatureEasterEggViewFix, laurabow1PatchEasterEggViewFix },
- { true, 37, "armor open visor fix", 1, laurabow1SignatureArmorOpenVisorFix, laurabow1PatchArmorOpenVisorFix },
- { true, 37, "armor move to fix", 2, laurabow1SignatureArmorMoveToFix, laurabow1PatchArmorMoveToFix },
- { true, 37, "allowing input, after oiling arm", 1, laurabow1SignatureArmorOilingArmFix, laurabow1PatchArmorOilingArmFix },
+ { true, 4, "easter egg view fix", 1, laurabow1SignatureEasterEggViewFix, laurabow1PatchEasterEggViewFix },
+ { true, 37, "armor open visor fix", 1, laurabow1SignatureArmorOpenVisorFix, laurabow1PatchArmorOpenVisorFix },
+ { true, 37, "armor move to fix", 2, laurabow1SignatureArmorMoveToFix, laurabow1PatchArmorMoveToFix },
+ { true, 37, "allowing input, after oiling arm", 1, laurabow1SignatureArmorOilingArmFix, laurabow1PatchArmorOilingArmFix },
+ { true, 236, "tell Lilly about Gertie blocking fix 1/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix1, laurabow1PatchTellLillyAboutGertieBlockingFix1 },
+ { true, 236, "tell Lilly about Gertie blocking fix 2/2", 1, laurabow1SignatureTellLillyAboutGerieBlockingFix2, laurabow1PatchTellLillyAboutGertieBlockingFix2 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -2614,6 +2678,98 @@ static const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
PATCH_END
};
+// When entering the main musem party room (w/ the golden Egyptian head),
+// Laura is waslking a bit into the room automatically.
+// In case you press a mouse button while this is happening, you will get
+// stuck inside that room and won't be able to exit it anymore.
+//
+// Users, who played the game w/ a previous version of ScummVM can simply
+// enter the debugger and then enter "send rm350 script 0:0", which will
+// fix the script state.
+//
+// This is caused by the user controls not being locked at that point.
+// Pressing a button will cause the cue from the PolyPath walker to never
+// happen, which then causes sEnterSouth to never dispose itself.
+//
+// User controls are locked in the previous room 335, but controls
+// are unlocked by frontDoor::cue.
+// We do not want to change this, because it could have side-effects.
+// We instead add another LB2::handsOff call inside the script responsible
+// for making Laura walk into the room (sEnterSouth::changeState(0).
+//
+// Applies to at least: English PC-CD, English PC-Floppy, German PC-Floppy
+// Responsible method: sEnterSouth::changeState
+// Fixes bug: (no bug report, from GOG forum post)
+static const uint16 laurabow2SignatureMuseumPartyFixEnteringSouth1[] = {
+ 0x3c, // dup
+ 0x35, 0x00, // ldi 00
+ 0x1a, // eq?
+ 0x30, SIG_UINT16(0x0097), // bnt [state 1 code]
+ SIG_ADDTOOFFSET(+141), // skip to end of follow-up code
+ 0x32, SIG_ADDTOOFFSET(+2), // jmp [ret] (0x008d for CD, 0x007d for floppy)
+ 0x35, 0x01, // ldi 01
+ 0x65, 0x1a, // aTop cycles
+ 0x32, SIG_ADDTOOFFSET(+2), // jmp [ret] (0x0086 for CD, 0x0076 for floppy)
+ // state 1 code
+ 0x3c, // dup
+ 0x35, 0x01, // ldi 01
+ 0x1a, // eq?
+ SIG_MAGICDWORD,
+ 0x31, 0x05, // bnt [state 2 code]
+ 0x35, 0x00, // ldi 00
+ 0x32, SIG_ADDTOOFFSET(+2), // jmp [ret] (0x007b for CD, 0x006b for floppy)
+ // state 2 code
+ 0x3c, // dup
+ SIG_END
+};
+
+static const uint16 laurabow2PatchMuseumPartyFixEnteringSouth1[] = {
+ 0x2e, PATCH_UINT16(0x00a6), // bt [state 2 code] (we skip state 1, because it's a NOP anyways)
+ // state 0 processing
+ 0x32, PATCH_UINT16(+151),
+ SIG_ADDTOOFFSET(+149), // skip to end of follow-up code
+ // save 1 byte by replacing jump to [ret] into straight toss/ret
+ 0x3a, // toss
+ 0x48, // ret
+
+ // additional code, that gets called right at the start of step 0 processing
+ 0x18, // not -- this here is where pushi handsOff will be inserted by the second patch
+ 0x18, // not offset and handsOff is different for floppy + CD, that's why we do this
+ 0x18, // not floppy also does not have a selector table, so we can't go by "handsOff" name
+ 0x18, // not
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04
+ 0x32, PATCH_UINT16(0xFF5e), // jmp [back to start of step 0 processing]
+ PATCH_END
+};
+
+// second patch, which only inserts pushi handsOff inside our new code
+// There is no other way to do this except making 2 full patches for floppy + CD, because handsOff/handsOn
+// is not the same value between floppy + CD *and* floppy doesn't even have a vocab, so we can't figure out the id
+// by ourselves.
+static const uint16 laurabow2SignatureMuseumPartyFixEnteringSouth2[] = {
+ 0x18, // our injected code
+ 0x18,
+ 0x18,
+ SIG_ADDTOOFFSET(+92), // skip to the handsOn code, that we are interested in
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi handsOn (0x0189 for CD, 0x024b for floppy)
+ 0x76, // push0
+ 0x81, 0x01, // lag global[1]
+ 0x4a, 0x04, // send 04
+ 0x38, SIG_ADDTOOFFSET(+2), // pushi 0274h
+ SIG_MAGICDWORD,
+ 0x78, // push1
+ 0x38, SIG_UINT16(0x033f), // pushi 033f
+ SIG_END
+};
+
+static const uint16 laurabow2PatchMuseumPartyFixEnteringSouth2[] = {
+ 0x38, // pushi
+ PATCH_GETORIGINALUINT16ADJUST(+96, -1), // get handsOff code and ubstract 1 from it to get handsOn
+ PATCH_END
+};
+
// Opening/Closing the east door in the pterodactyl room doesn't
// check, if it's locked and will open/close the door internally
// even when it is.
@@ -2628,7 +2784,7 @@ static const uint16 laurabow2CDPatchFixProblematicIconBar[] = {
// Responsible method (CD): eastDoor::doVerb
// Responsible method (Floppy): eastDoor::<noname300>
// Fixes bug: #6458 (partly, see additional patch below)
-static const uint16 laurabow2CDSignatureFixWiredEastDoor[] = {
+static const uint16 laurabow2SignatureFixWiredEastDoor[] = {
0x30, SIG_UINT16(0x0022), // bnt [skip hand action]
0x67, SIG_ADDTOOFFSET(+1), // pTos CD: doorState, Floppy: state
0x35, 0x00, // ldi 00
@@ -2651,7 +2807,7 @@ static const uint16 laurabow2CDSignatureFixWiredEastDoor[] = {
SIG_END
};
-static const uint16 laurabow2CDPatchFixWiredEastDoor[] = {
+static const uint16 laurabow2PatchFixWiredEastDoor[] = {
0x31, 0x23, // bnt [skip hand action] (saves 1 byte)
0x81, 97, // lag 97d (get our eastDoor-wired-global)
0x31, 0x04, // bnt [skip setting locked property]
@@ -2780,20 +2936,22 @@ static const uint16 laurabow2CDPatchAudioTextMenuSupport2[] = {
// script, description, signature patch
static const SciScriptPatcherEntry laurabow2Signatures[] = {
- { true, 560, "CD: painting closing immediately", 1, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
- { true, 0, "CD: fix problematic icon bar", 1, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
- { true, 430, "CD/Floppy: make wired east door persistent", 1, laurabow2SignatureRememberWiredEastDoor, laurabow2PatchRememberWiredEastDoor },
- { true, 430, "CD/Floppy: fix wired east door", 1, laurabow2CDSignatureFixWiredEastDoor, laurabow2CDPatchFixWiredEastDoor },
+ { true, 560, "CD: painting closing immediately", 1, laurabow2CDSignaturePaintingClosing, laurabow2CDPatchPaintingClosing },
+ { true, 0, "CD: fix problematic icon bar", 1, laurabow2CDSignatureFixProblematicIconBar, laurabow2CDPatchFixProblematicIconBar },
+ { true, 350, "CD/Floppy: museum party fix entering south 1/2", 1, laurabow2SignatureMuseumPartyFixEnteringSouth1, laurabow2PatchMuseumPartyFixEnteringSouth1 },
+ { true, 350, "CD/Floppy: museum party fix entering south 2/2", 1, laurabow2SignatureMuseumPartyFixEnteringSouth2, laurabow2PatchMuseumPartyFixEnteringSouth2 },
+ { true, 430, "CD/Floppy: make wired east door persistent", 1, laurabow2SignatureRememberWiredEastDoor, laurabow2PatchRememberWiredEastDoor },
+ { true, 430, "CD/Floppy: fix wired east door", 1, laurabow2SignatureFixWiredEastDoor, laurabow2PatchFixWiredEastDoor },
// King's Quest 6 and Laura Bow 2 share basic patches for audio + text support
- { false, 924, "CD: audio + text support 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
- { false, 924, "CD: audio + text support 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
- { false, 924, "CD: audio + text support 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
- { false, 928, "CD: audio + text support 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
- { false, 928, "CD: audio + text support 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
- { false, 0, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
- { false, 100, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
- { false, 24, "CD: audio + text support LB2 menu 1", 1, laurabow2CDSignatureAudioTextMenuSupport1, laurabow2CDPatchAudioTextMenuSupport1 },
- { false, 24, "CD: audio + text support LB2 menu 2", 1, laurabow2CDSignatureAudioTextMenuSupport2, laurabow2CDPatchAudioTextMenuSupport2 },
+ { false, 924, "CD: audio + text support 1", 1, kq6laurabow2CDSignatureAudioTextSupport1, kq6laurabow2CDPatchAudioTextSupport1 },
+ { false, 924, "CD: audio + text support 2", 1, kq6laurabow2CDSignatureAudioTextSupport2, kq6laurabow2CDPatchAudioTextSupport2 },
+ { false, 924, "CD: audio + text support 3", 1, kq6laurabow2CDSignatureAudioTextSupport3, kq6laurabow2CDPatchAudioTextSupport3 },
+ { false, 928, "CD: audio + text support 4", 1, kq6laurabow2CDSignatureAudioTextSupport4, kq6laurabow2CDPatchAudioTextSupport4 },
+ { false, 928, "CD: audio + text support 5", 2, kq6laurabow2CDSignatureAudioTextSupport5, kq6laurabow2CDPatchAudioTextSupport5 },
+ { false, 0, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
+ { false, 100, "CD: audio + text support disable mode reset", 1, laurabow2CDSignatureAudioTextSupportModeReset, laurabow2CDPatchAudioTextSupportModeReset },
+ { false, 24, "CD: audio + text support LB2 menu 1", 1, laurabow2CDSignatureAudioTextMenuSupport1, laurabow2CDPatchAudioTextMenuSupport1 },
+ { false, 24, "CD: audio + text support LB2 menu 2", 1, laurabow2CDSignatureAudioTextMenuSupport2, laurabow2CDPatchAudioTextMenuSupport2 },
SCI_SIGNATUREENTRY_TERMINATOR
};
@@ -3939,8 +4097,7 @@ static const uint16 qfg3PatchMissingPoints1[] = {
PATCH_UINT16(0xFFD6), // -42 "Greet"
PATCH_UINT16(0xFFB0), // -80 "Say Good-bye"
PATCH_UINT16(0x03E7), // 999 END MARKER
- PATCH_GETORIGINALBYTE(+28), // local[$aa][0].low
- PATCH_GETORIGINALBYTE(+29), // local[$aa][0].high
+ PATCH_GETORIGINALUINT16(+28), // local[$aa][0]
PATCH_END
};
@@ -4841,14 +4998,6 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
break;
}
case PATCH_CODE_GETORIGINALBYTE: {
- // get original byte from script
- if (patchValue >= orgDataSize)
- error("Script-Patcher: can not get requested original byte from script");
- scriptData[offset] = orgData[patchValue];
- offset++;
- break;
- }
- case PATCH_CODE_GETORIGINALBYTEADJUST: {
// get original byte from script and adjust it
if (patchValue >= orgDataSize)
error("Script-Patcher: can not get requested original byte from script");
@@ -4859,6 +5008,30 @@ void ScriptPatcher::applyPatch(const SciScriptPatcherEntry *patchEntry, byte *sc
offset++;
break;
}
+ case PATCH_CODE_GETORIGINALUINT16: {
+ // get original byte from script and adjust it
+ if ((patchValue >= orgDataSize) || (((uint32)patchValue + 1) >= orgDataSize))
+ error("Script-Patcher: can not get requested original uint16 from script");
+ uint16 orgUINT16;
+ int16 adjustValue;
+
+ if (!_isMacSci11) {
+ orgUINT16 = orgData[patchValue] | (orgData[patchValue + 1] << 8);
+ } else {
+ orgUINT16 = orgData[patchValue + 1] | (orgData[patchValue] << 8);
+ }
+ patchData++; adjustValue = (int16)(*patchData);
+ orgUINT16 += adjustValue;
+ if (!_isMacSci11) {
+ scriptData[offset] = orgUINT16 & 0xFF;
+ scriptData[offset + 1] = orgUINT16 >> 8;
+ } else {
+ scriptData[offset] = orgUINT16 >> 8;
+ scriptData[offset + 1] = orgUINT16 & 0xFF;
+ }
+ offset += 2;
+ break;
+ }
case PATCH_CODE_UINT16:
case PATCH_CODE_SELECTOR16: {
byte byte1;
@@ -5134,7 +5307,8 @@ void ScriptPatcher::calculateMagicDWordAndVerify(const char *signatureDescriptio
}
break;
}
- case PATCH_CODE_GETORIGINALBYTEADJUST: {
+ case PATCH_CODE_GETORIGINALBYTE:
+ case PATCH_CODE_GETORIGINALUINT16: {
signatureData++; // skip over extra uint16
break;
}
diff --git a/engines/sci/engine/script_patches.h b/engines/sci/engine/script_patches.h
index f95806a3f3..b5797be847 100644
--- a/engines/sci/engine/script_patches.h
+++ b/engines/sci/engine/script_patches.h
@@ -44,23 +44,25 @@ namespace Sci {
#define SIG_UINT16(_value_) SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
#define SIG_CODE_BYTE 0x0000
-#define PATCH_END SIG_END
-#define PATCH_COMMANDMASK SIG_COMMANDMASK
-#define PATCH_VALUEMASK SIG_VALUEMASK
-#define PATCH_BYTEMASK SIG_BYTEMASK
-#define PATCH_CODE_ADDTOOFFSET SIG_CODE_ADDTOOFFSET
-#define PATCH_ADDTOOFFSET(_offset_) SIG_CODE_ADDTOOFFSET | (_offset_)
-#define PATCH_CODE_GETORIGINALBYTE 0xD000
-#define PATCH_GETORIGINALBYTE(_offset_) PATCH_CODE_GETORIGINALBYTE | (_offset_)
-#define PATCH_CODE_GETORIGINALBYTEADJUST 0xC000
-#define PATCH_GETORIGINALBYTEADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALBYTEADJUST | (_offset_), (uint16)(_adjustValue_)
-#define PATCH_CODE_SELECTOR16 SIG_CODE_SELECTOR16
-#define PATCH_SELECTOR16(_selectorID_) SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
-#define PATCH_CODE_SELECTOR8 SIG_CODE_SELECTOR8
-#define PATCH_SELECTOR8(_selectorID_) SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
-#define PATCH_CODE_UINT16 SIG_CODE_UINT16
-#define PATCH_UINT16(_value_) SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
-#define PATCH_CODE_BYTE SIG_CODE_BYTE
+#define PATCH_END SIG_END
+#define PATCH_COMMANDMASK SIG_COMMANDMASK
+#define PATCH_VALUEMASK SIG_VALUEMASK
+#define PATCH_BYTEMASK SIG_BYTEMASK
+#define PATCH_CODE_ADDTOOFFSET SIG_CODE_ADDTOOFFSET
+#define PATCH_ADDTOOFFSET(_offset_) SIG_CODE_ADDTOOFFSET | (_offset_)
+#define PATCH_CODE_GETORIGINALBYTE 0xC000
+#define PATCH_GETORIGINALBYTE(_offset_) PATCH_CODE_GETORIGINALBYTE | (_offset_), 0
+#define PATCH_GETORIGINALBYTEADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALBYTE | (_offset_), (uint16)(_adjustValue_)
+#define PATCH_CODE_GETORIGINALUINT16 0xD000
+#define PATCH_GETORIGINALUINT16(_offset_) PATCH_CODE_GETORIGINALUINT16 | (_offset_), 0
+#define PATCH_GETORIGINALUINT16ADJUST(_offset_, _adjustValue_) PATCH_CODE_GETORIGINALUINT16 | (_offset_), (uint16)(_adjustValue_)
+#define PATCH_CODE_SELECTOR16 SIG_CODE_SELECTOR16
+#define PATCH_SELECTOR16(_selectorID_) SIG_CODE_SELECTOR16 | SELECTOR_##_selectorID_
+#define PATCH_CODE_SELECTOR8 SIG_CODE_SELECTOR8
+#define PATCH_SELECTOR8(_selectorID_) SIG_CODE_SELECTOR8 | SELECTOR_##_selectorID_
+#define PATCH_CODE_UINT16 SIG_CODE_UINT16
+#define PATCH_UINT16(_value_) SIG_CODE_UINT16 | ((_value_) & 0xFF), ((_value_) >> 8)
+#define PATCH_CODE_BYTE SIG_CODE_BYTE
// defines maximum scratch area for getting original bytes from unpatched script data
#define PATCH_VALUELIMIT 4096
diff --git a/engines/titanic/module.mk b/engines/titanic/module.mk
index aaa2a99671..cdb3a64b3c 100644
--- a/engines/titanic/module.mk
+++ b/engines/titanic/module.mk
@@ -436,10 +436,10 @@ MODULE_OBJS := \
star_control/dvector.o \
star_control/fmatrix.o \
star_control/fpoint.o \
+ star_control/frange.o \
star_control/frect.o \
star_control/fvector.o \
star_control/star_control_sub2.o \
- star_control/star_control_sub4.o \
star_control/star_control_sub5.o \
star_control/star_control_sub6.o \
star_control/star_control_sub7.o \
@@ -457,6 +457,7 @@ MODULE_OBJS := \
star_control/star_field.o \
star_control/star_points1.o \
star_control/star_points2.o \
+ star_control/star_ref.o \
star_control/star_view.o \
star_control/surface_area.o \
star_control/surface_fader_base.o \
diff --git a/engines/titanic/star_control/base_star.cpp b/engines/titanic/star_control/base_star.cpp
index a32263a926..ffe5fd05b4 100644
--- a/engines/titanic/star_control/base_star.cpp
+++ b/engines/titanic/star_control/base_star.cpp
@@ -22,6 +22,7 @@
#include "titanic/star_control/base_star.h"
#include "titanic/star_control/star_control_sub12.h"
+#include "titanic/star_control/star_ref.h"
#include "titanic/titanic.h"
namespace Titanic {
@@ -44,6 +45,15 @@ void CBaseStarEntry::load(Common::SeekableReadStream &s) {
_data[idx] = s.readUint32LE();
}
+bool CBaseStarEntry::operator==(const CBaseStarEntry &s) const {
+ return _field0 == s._field0 && _field1 == s._field1
+ && _field2 == s._field2 && _field3 == s._field3
+ && _value == s._value && _position == s._position
+ && _data[0] == s._data[0] && _data[1] == s._data[1]
+ && _data[2] == s._data[2] && _data[3] == s._data[3]
+ && _data[4] == s._data[4];
+}
+
/*------------------------------------------------------------------------*/
CBaseStar::CBaseStar() : _minVal(0.0), _maxVal(1.0), _range(0.0),
@@ -57,11 +67,11 @@ void CBaseStar::clear() {
void CBaseStar::initialize() {
_minVal = 9.9999998e10;
_maxVal = -9.9999998e10;
- _sub4.initialize();
+ _minMax.reset();
for (uint idx = 0; idx < _data.size(); ++idx) {
const CBaseStarEntry *entry = getDataPtr(idx);
- _sub4.checkEntry(entry->_position);
+ _minMax.expand(entry->_position);
if (entry->_value < _minVal)
_minVal = entry->_value;
@@ -191,13 +201,17 @@ void CBaseStar::draw4(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12, CStar
// TODO
}
-void CBaseStar::baseFn1(int v1, int v2, int v3, int v4) {
- // TODO
+int CBaseStar::baseFn1(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12,
+ const Common::Point &pt) {
+ CStarRef1 ref(this, pt);
+ ref.process(surfaceArea, sub12);
+ return ref._index;
}
int CBaseStar::baseFn2(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12) {
- // TODO
- return 0;
+ CStarRef3 ref(this);
+ ref.process(surfaceArea, sub12);
+ return ref._index;
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/base_star.h b/engines/titanic/star_control/base_star.h
index 1450b25bb3..8fc36ba6c7 100644
--- a/engines/titanic/star_control/base_star.h
+++ b/engines/titanic/star_control/base_star.h
@@ -24,7 +24,7 @@
#define TITANIC_STAR_CONTROL_SUB3_H
#include "titanic/support/simple_file.h"
-#include "titanic/star_control/star_control_sub4.h"
+#include "titanic/star_control/frange.h"
#include "titanic/star_control/star_control_sub5.h"
#include "titanic/star_control/surface_area.h"
@@ -44,7 +44,23 @@ struct CBaseStarEntry {
uint _data[5];
CBaseStarEntry();
+
+ /**
+ * Loads the data for a star
+ */
void load(Common::SeekableReadStream &s);
+
+ bool operator==(const CBaseStarEntry &s) const;
+};
+
+struct CStarPosition : public Common::Point {
+ int _index1;
+ int _index2;
+ CStarPosition() : _index1(0), _index2(0) {}
+
+ bool operator==(const CStarPosition &sp) const {
+ return x == sp.x && y == sp.y && _index1 == sp._index1 && _index2 == sp._index2;
+ }
};
class CBaseStar {
@@ -55,7 +71,7 @@ private:
void draw4(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12, CStarControlSub5 *sub5);
protected:
Common::Array<CBaseStarEntry> _data;
- CStarControlSub4 _sub4;
+ FRange _minMax;
double _minVal;
double _maxVal;
double _range;
@@ -76,9 +92,6 @@ protected:
* Reset the data for an entry
*/
void resetEntry(CBaseStarEntry &entry);
-
- void baseFn1(int v1, int v2, int v3, int v4);
- int baseFn2(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12);
public:
CBaseStar();
virtual ~CBaseStar() {}
@@ -94,7 +107,7 @@ public:
* Selects a star
*/
virtual bool selectStar(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12,
- int flags, const Common::Point &pt) { return false; }
+ const Common::Point &pt, void *handler = nullptr) { return false; }
/**
* Adds a new star, or removes one if already present at the given co-ordinates
@@ -126,6 +139,11 @@ public:
* Get a pointer to a data entry
*/
const CBaseStarEntry *getDataPtr(int index) const;
+
+ int baseFn1(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12,
+ const Common::Point &pt);
+
+ int baseFn2(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/dmatrix.cpp b/engines/titanic/star_control/dmatrix.cpp
index 70008054b6..940b34833f 100644
--- a/engines/titanic/star_control/dmatrix.cpp
+++ b/engines/titanic/star_control/dmatrix.cpp
@@ -29,25 +29,40 @@ namespace Titanic {
DMatrix *DMatrix::_static;
DMatrix::DMatrix() :
- _row1(1.0, 0.0, 0.0), _row2(0.0, 1.0, 0.0), _row3(0.0, 0.0, 1.0) {
+ _row1(1.875, 0.0, 0.0), _row2(0.0, 1.875, 0.0), _row3(0.0, 0.0, 1.875) {
}
-DMatrix::DMatrix(int mode, const FMatrix *src) {
- assert(!mode);
-
- _row1._x = 1.0;
- _row2._y = 1.0;
- _row3._z = 1.0;
- _frow1._x = src->_row1._x;
- _frow1._y = src->_row1._y;
- _frow1._z = src->_row1._z;
- _frow2._x = src->_row2._x;
- _frow2._y = src->_row2._y;
- _frow2._z = src->_row2._z;
+DMatrix::DMatrix(int mode, const DVector &src) {
+ switch (mode) {
+ case 0:
+ _row1._x = 1.0;
+ _row2._y = 1.0;
+ _row3._z = 1.0;
+ _row4 = src;
+ break;
+
+ case 1:
+ _row1._x = src._x;
+ _row2._y = src._y;
+ _row3._z = src._z;
+ break;
+
+ default:
+ _row1._x = 1.0;
+ _row2._y = 1.0;
+ _row3._z = 1.0;
+ break;
+ }
}
-DMatrix::DMatrix(int mode, double val) {
- set(mode, val);
+DMatrix::DMatrix(Axis axis, double amount) {
+ setRotationMatrix(axis, amount);
+}
+
+DMatrix::DMatrix(const FMatrix &src) {
+ _row1 = src._row1;
+ _row2 = src._row2;
+ _row3 = src._row3;
}
void DMatrix::init() {
@@ -59,13 +74,13 @@ void DMatrix::deinit() {
_static = nullptr;
}
-void DMatrix::set(int mode, double amount) {
+void DMatrix::setRotationMatrix(Axis axis, double amount) {
const double FACTOR = 0.0174532925199433;
double sinVal = sin(amount * FACTOR);
double cosVal = cos(amount * FACTOR);
- switch (mode) {
- case 0:
+ switch (axis) {
+ case X_AXIS:
_row1._x = 1.0;
_row2._y = cosVal;
_row2._z = sinVal;
@@ -73,7 +88,7 @@ void DMatrix::set(int mode, double amount) {
_row3._z = cosVal;
break;
- case 1:
+ case Y_AXIS:
_row1._x = cosVal;
_row1._z = sinVal;
_row2._y = 1.0;
@@ -81,7 +96,7 @@ void DMatrix::set(int mode, double amount) {
_row3._z = cosVal;
break;
- case 2:
+ case Z_AXIS:
_row1._x = cosVal;
_row1._y = sinVal;
_row2._x = -sinVal;
@@ -94,6 +109,10 @@ void DMatrix::set(int mode, double amount) {
}
}
+void DMatrix::fn1(DMatrix &m) {
+ // TODO
+}
+
void DMatrix::fn3(CStarControlSub26 *sub26) {
double v = sub26->fn1();
v = (v < 0.0) ? 0.0 : 2.0 / v;
@@ -101,4 +120,9 @@ void DMatrix::fn3(CStarControlSub26 *sub26) {
error("TODO: DMatrix::fn3 %d", (int)v);
}
+const DMatrix *DMatrix::fn4(DMatrix &dest, const DMatrix &m1, const DMatrix &m2) {
+ // TODO
+ return nullptr;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/dmatrix.h b/engines/titanic/star_control/dmatrix.h
index 14f6bb0331..c3490770fb 100644
--- a/engines/titanic/star_control/dmatrix.h
+++ b/engines/titanic/star_control/dmatrix.h
@@ -42,22 +42,25 @@ public:
DVector _row1;
DVector _row2;
DVector _row3;
- FVector _frow1;
- FVector _frow2;
+ DVector _row4;
public:
static void init();
static void deinit();
public:
DMatrix();
- DMatrix(int mode, const FMatrix *src);
- DMatrix(int mode, double val);
+ DMatrix(int mode, const DVector &src);
+ DMatrix(Axis axis, double amount);
+ DMatrix(const FMatrix &src);
/**
- * Sets up data for the matrix
+ * Sets up a matrix for rotating on a given axis by a given amount
*/
- void set(int mode, double amount);
+ void setRotationMatrix(Axis axis, double amount);
+ void fn1(DMatrix &m);
void fn3(CStarControlSub26 *sub26);
+
+ const DMatrix *fn4(DMatrix &dest, const DMatrix &m1, const DMatrix &m2);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/dvector.cpp b/engines/titanic/star_control/dvector.cpp
index e4c5b15cb0..dc1376537e 100644
--- a/engines/titanic/star_control/dvector.cpp
+++ b/engines/titanic/star_control/dvector.cpp
@@ -25,7 +25,7 @@
namespace Titanic {
-void DVector::fn3() {
+void DVector::normalize() {
double hyp = sqrt(_x * _x + _y * _y + _z * _z);
assert(hyp);
@@ -34,4 +34,29 @@ void DVector::fn3() {
_z *= 1.0 / hyp;
}
+double DVector::getDistance(const DVector &src) {
+ return sqrt((src._x - _x) * (src._x - _x) + (src._y - _y) * (src._y - _y) + (src._z - _z) * (src._z - _z));
+}
+
+void DVector::fn1(DVector &dest, const DMatrix &m) {
+ // TODO
+}
+
+void DVector::fn2(double val) {
+ // TODO
+}
+
+void DVector::fn3(DVector &dest) {
+ // TODO
+}
+
+const DMatrix *DVector::fn4(const DVector &v, DMatrix &m) {
+ // TODO
+ return nullptr;
+}
+
+void DVector::fn5(DMatrix &dest) {
+ // TODO
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/dvector.h b/engines/titanic/star_control/dvector.h
index 7aca407c1c..a216be15fe 100644
--- a/engines/titanic/star_control/dvector.h
+++ b/engines/titanic/star_control/dvector.h
@@ -23,8 +23,12 @@
#ifndef TITANIC_DVECTOR_H
#define TITANIC_DVECTOR_H
+#include "titanic/star_control/fvector.h"
+
namespace Titanic {
+class DMatrix;
+
/**
* Double based vector class.
* @remarks TODO: See if it can be merged with FVector
@@ -35,8 +39,20 @@ public:
public:
DVector() : _x(0), _y(0), _z(0) {}
DVector(double x, double y, double z) : _x(x), _y(y), _z(z) {}
+ DVector(const FVector &v) : _x(v._x), _y(v._y), _z(v._z) {}
+
+ void normalize();
+
+ /**
+ * Returns the distance between this vector and the passed one
+ */
+ double getDistance(const DVector &src);
- void fn3();
+ void fn1(DVector &dest, const DMatrix &m);
+ void fn2(double val);
+ void fn3(DVector &dest);
+ const DMatrix *fn4(const DVector &v, DMatrix &m);
+ void fn5(DMatrix &dest);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/fmatrix.cpp b/engines/titanic/star_control/fmatrix.cpp
index af15477d04..02da11576c 100644
--- a/engines/titanic/star_control/fmatrix.cpp
+++ b/engines/titanic/star_control/fmatrix.cpp
@@ -28,17 +28,17 @@ FMatrix::FMatrix() :
_row1(1.0, 0.0, 0.0), _row2(0.0, 1.0, 0.0), _row3(0.0, 0.0, 1.0) {
}
-FMatrix::FMatrix(DMatrix *src) {
+FMatrix::FMatrix(const DMatrix &src) {
copyFrom(src);
}
-FMatrix::FMatrix(FMatrix *src) {
- _row1 = src->_row1;
- _row2 = src->_row2;
- _row3 = src->_row3;
+FMatrix::FMatrix(const FMatrix &src) {
+ _row1 = src._row1;
+ _row2 = src._row2;
+ _row3 = src._row3;
}
-void FMatrix::copyFrom(const DMatrix *src) {
+void FMatrix::copyFrom(const DMatrix &src) {
// TODO
}
@@ -67,19 +67,25 @@ void FMatrix::save(SimpleFile *file, int indent) {
}
void FMatrix::clear() {
+ _row1.clear();
+ _row2.clear();
+ _row3.clear();
+}
+
+void FMatrix::identity() {
_row1 = FVector(1.0, 0.0, 0.0);
_row2 = FVector(0.0, 1.0, 0.0);
_row3 = FVector(0.0, 0.0, 1.0);
}
-void FMatrix::set(FVector *row1, FVector *row2, FVector *row3) {
- _row1 = *row1;
- _row2 = *row2;
- _row3 = *row3;
+void FMatrix::set(const FVector &row1, const FVector &row2, const FVector &row3) {
+ _row1 = row1;
+ _row2 = row2;
+ _row3 = row3;
}
-void FMatrix::fn1(const FVector *v) {
- _row3._x = v->_x;
+void FMatrix::fn1(const FVector &v) {
+ _row3._x = v._x;
FVector tempVector;
_row3.fn1(&tempVector);
@@ -88,45 +94,45 @@ void FMatrix::fn1(const FVector *v) {
_row2._y = tempVector._y;
_row2._z = tempVector._z;
- _row3.multiply(&tempVector, &_row2);
+ _row3.crossProduct(&tempVector, &_row2);
_row1._x = _row2._x;
_row1._y = _row2._y;
_row1._z = _row2._z;
- _row1.fn3();
+ _row1.normalize();
- _row3.multiply(&tempVector, &_row1);
+ _row3.crossProduct(&tempVector, &_row1);
_row2._x = _row1._x;
_row2._y = _row1._y;
_row2._z = _row1._z;
- _row2.fn3();
+ _row2.normalize();
}
-void FMatrix::fn2(FMatrix *m) {
- double x1 = _row1._y * m->_row2._x + _row1._z * m->_row3._x + _row1._x * m->_row1._x;
- double y1 = _row1._x * m->_row1._y + m->_row2._y * _row1._y + m->_row3._y * _row1._z;
- double z1 = _row1._x * m->_row1._z + _row1._y * m->_row2._z + _row1._z * m->_row3._z;
- double x2 = m->_row1._x * _row2._x + m->_row3._x * _row2._z + m->_row2._x * _row2._y;
- double y2 = m->_row3._y * _row2._z + m->_row1._y * _row2._x + m->_row2._y * _row2._y;
- double z2 = _row2._z * m->_row3._z + _row2._x * m->_row1._z + _row2._y * m->_row2._z;
- double x3 = m->_row1._x * _row3._x + _row3._z * m->_row3._x + _row3._y * m->_row2._x;
- double y3 = _row3._y * m->_row2._y + _row3._z * m->_row3._y + _row3._x * m->_row1._y;
- double z3 = _row3._x * m->_row1._z + _row3._y * m->_row2._z + _row3._z * m->_row3._z;
+void FMatrix::fn2(const FMatrix &m) {
+ double x1 = _row1._y * m._row2._x + _row1._z * m._row3._x + _row1._x * m._row1._x;
+ double y1 = _row1._x * m._row1._y + m._row2._y * _row1._y + m._row3._y * _row1._z;
+ double z1 = _row1._x * m._row1._z + _row1._y * m._row2._z + _row1._z * m._row3._z;
+ double x2 = m._row1._x * _row2._x + m._row3._x * _row2._z + m._row2._x * _row2._y;
+ double y2 = m._row3._y * _row2._z + m._row1._y * _row2._x + m._row2._y * _row2._y;
+ double z2 = _row2._z * m._row3._z + _row2._x * m._row1._z + _row2._y * m._row2._z;
+ double x3 = m._row1._x * _row3._x + _row3._z * m._row3._x + _row3._y * m._row2._x;
+ double y3 = _row3._y * m._row2._y + _row3._z * m._row3._y + _row3._x * m._row1._y;
+ double z3 = _row3._x * m._row1._z + _row3._y * m._row2._z + _row3._z * m._row3._z;
_row1 = FVector(x1, y1, z1);
_row2 = FVector(x2, y2, z2);
_row3 = FVector(x3, y3, z3);
}
-void FMatrix::fn3(FMatrix *m) {
- double x1 = _row2._x * m->_row1._y + m->_row1._z * _row3._x + _row1._x * m->_row1._x;
- double y1 = m->_row1._x * _row1._y + _row3._y * m->_row1._z + _row2._y * m->_row1._y;
- double z1 = m->_row1._x * _row1._z + m->_row1._y * _row2._z + m->_row1._z * _row3._z;
- double x2 = _row1._x * m->_row2._x + _row2._x * m->_row2._y + _row3._x * m->_row2._z;
- double y2 = _row3._y * m->_row2._z + _row1._y * m->_row2._x + _row2._y * m->_row2._y;
- double z2 = m->_row2._z * _row3._z + m->_row2._x * _row1._z + m->_row2._y * _row2._z;
- double x3 = _row1._x * m->_row3._x + m->_row3._z * _row3._x + m->_row3._y * _row2._x;
- double y3 = m->_row3._y * _row2._y + m->_row3._z * _row3._y + m->_row3._x * _row1._y;
- double z3 = m->_row3._x * _row1._z + m->_row3._y * _row2._z + m->_row3._z * _row3._z;
+void FMatrix::fn3(const FMatrix &m) {
+ double x1 = _row2._x * m._row1._y + m._row1._z * _row3._x + _row1._x * m._row1._x;
+ double y1 = m._row1._x * _row1._y + _row3._y * m._row1._z + _row2._y * m._row1._y;
+ double z1 = m._row1._x * _row1._z + m._row1._y * _row2._z + m._row1._z * _row3._z;
+ double x2 = _row1._x * m._row2._x + _row2._x * m._row2._y + _row3._x * m._row2._z;
+ double y2 = _row3._y * m._row2._z + _row1._y * m._row2._x + _row2._y * m._row2._y;
+ double z2 = m._row2._z * _row3._z + m._row2._x * _row1._z + m._row2._y * _row2._z;
+ double x3 = _row1._x * m._row3._x + m._row3._z * _row3._x + m._row3._y * _row2._x;
+ double y3 = m._row3._y * _row2._y + m._row3._z * _row3._y + m._row3._x * _row1._y;
+ double z3 = m._row3._x * _row1._z + m._row3._y * _row2._z + m._row3._z * _row3._z;
_row1 = FVector(x1, y1, z1);
_row2 = FVector(x2, y2, z2);
diff --git a/engines/titanic/star_control/fmatrix.h b/engines/titanic/star_control/fmatrix.h
index d7c4acfbdc..6fa847f950 100644
--- a/engines/titanic/star_control/fmatrix.h
+++ b/engines/titanic/star_control/fmatrix.h
@@ -39,15 +39,15 @@ private:
/**
* Copys data from a given source
*/
- void copyFrom(const DMatrix *src);
+ void copyFrom(const DMatrix &src);
public:
FVector _row1;
FVector _row2;
FVector _row3;
public:
FMatrix();
- FMatrix(DMatrix *src);
- FMatrix(FMatrix *src);
+ FMatrix(const DMatrix &src);
+ FMatrix(const FMatrix &src);
/**
* Load the data for the class from file
@@ -65,14 +65,18 @@ public:
void clear();
/**
- * Sets the data for the matrix
+ * Sets up an identity matrix
*/
- void set(FVector *row1, FVector *row2, FVector *row3);
+ void identity();
- void fn1(const FVector *v);
+ /**
+ * Sets the data for the matrix
+ */
+ void set(const FVector &row1, const FVector &row2, const FVector &row3);
- void fn2(FMatrix *m);
- void fn3(FMatrix *m);
+ void fn1(const FVector &v);
+ void fn2(const FMatrix &m);
+ void fn3(const FMatrix &m);
/**
* Returns true if the passed matrix equals this one
@@ -91,4 +95,4 @@ public:
} // End of namespace Titanic
-#endif /* TITANIC_MATRIX3_H */
+#endif /* TITANIC_FMATRIX_H */
diff --git a/engines/titanic/star_control/star_control_sub4.cpp b/engines/titanic/star_control/frange.cpp
index 6ce0795c25..e70976d6cd 100644
--- a/engines/titanic/star_control/star_control_sub4.cpp
+++ b/engines/titanic/star_control/frange.cpp
@@ -21,19 +21,19 @@
*/
#include "common/algorithm.h"
-#include "titanic/star_control/star_control_sub4.h"
+#include "titanic/star_control/frange.h"
namespace Titanic {
-CStarControlSub4::CStarControlSub4() {
+FRange::FRange() {
}
-void CStarControlSub4::initialize() {
+void FRange::reset() {
_min._x = _min._y = _min._z = 9.9999994e27;
_max._x = _max._y = _max._z = -9.9999994e27;
}
-void CStarControlSub4::checkEntry(const FVector &v) {
+void FRange::expand(const FVector &v) {
_min._x = MIN(_min._x, v._x);
_min._y = MIN(_min._y, v._y);
_min._z = MIN(_min._z, v._z);
diff --git a/engines/titanic/star_control/star_control_sub4.h b/engines/titanic/star_control/frange.h
index 43c8ab5f79..f36aa2c538 100644
--- a/engines/titanic/star_control/star_control_sub4.h
+++ b/engines/titanic/star_control/frange.h
@@ -20,25 +20,31 @@
*
*/
-#ifndef TITANIC_STAR_CONTROL_SUB4_H
-#define TITANIC_STAR_CONTROL_SUB4_H
+#ifndef TITANIC_FRANGE_H
+#define TITANIC_FRANGE_H
#include "titanic/star_control/fvector.h"
namespace Titanic {
-class CStarControlSub4 {
+class FRange {
private:
FVector _min;
FVector _max;
public:
- CStarControlSub4();
+ FRange();
- void initialize();
+ /**
+ * Resets the minimum & maximum vector values
+ */
+ void reset();
- void checkEntry(const FVector &v);
+ /**
+ * Expands the minimum & maximum as necessary to encompass the passed vector/
+ */
+ void expand(const FVector &v);
};
} // End of namespace Titanic
-#endif /* TITANIC_STAR_CONTROL_SUB4_H */
+#endif /* TITANIC_FRANGE_H */
diff --git a/engines/titanic/star_control/fvector.cpp b/engines/titanic/star_control/fvector.cpp
index aa99e8b4d1..92c17a09b4 100644
--- a/engines/titanic/star_control/fvector.cpp
+++ b/engines/titanic/star_control/fvector.cpp
@@ -34,19 +34,27 @@ void FVector::fn1(FVector *v) {
v->_z = _z;
}
-void FVector::multiply(FVector *dest, const FVector *src) {
+void FVector::crossProduct(FVector *dest, const FVector *src) {
dest->_x = (src->_z * _y) - (_z * src->_y);
dest->_y = (src->_x * _z) - (_x * src->_z);
dest->_z = (src->_y * _x) - (_y * src->_x);
}
-void FVector::fn3() {
+double FVector::normalize() {
double hyp = sqrt(_x * _x + _y * _y + _z * _z);
assert(hyp);
_x *= 1.0 / hyp;
_y *= 1.0 / hyp;
_z *= 1.0 / hyp;
+ return hyp;
+}
+
+void FVector::addAndNormalize(FVector *dest, const FVector *v1, const FVector *v2) {
+ FVector tempVector(v1->_x + v2->_x, v1->_y + v2->_y, v1->_z + v2->_z);
+ tempVector.normalize();
+
+ *dest = tempVector;
}
double FVector::getDistance(const FVector *src) const {
@@ -57,14 +65,7 @@ double FVector::getDistance(const FVector *src) const {
return sqrt(xd * xd + yd * yd + zd * zd);
}
-void FVector::fn4(FVector *dest, const FVector *v1, const FVector *v2) {
- FVector tempVector(v1->_x + v2->_x, v1->_y + v2->_y, v1->_z + v2->_z);
- tempVector.fn3();
-
- *dest = tempVector;
-}
-
-void FVector::fn5(FVector *dest, const CStarControlSub6 *sub6) const {
+FVector FVector::fn5(const CStarControlSub6 *sub6) const {
error("TODO: FVector::fn5");
}
diff --git a/engines/titanic/star_control/fvector.h b/engines/titanic/star_control/fvector.h
index e19419bf20..4582072f50 100644
--- a/engines/titanic/star_control/fvector.h
+++ b/engines/titanic/star_control/fvector.h
@@ -27,6 +27,8 @@
namespace Titanic {
+enum Axis { X_AXIS, Y_AXIS, Z_AXIS };
+
class CStarControlSub6;
/**
@@ -48,16 +50,28 @@ public:
}
void fn1(FVector *v);
- void multiply(FVector *dest, const FVector *src);
- void fn3();
+
+ /**
+ * Calculates the cross-product between this matrix and a passed one
+ */
+ void crossProduct(FVector *dest, const FVector *src);
+
+ /**
+ * Normalizes the vector so the length from origin equals 1.0
+ */
+ double normalize();
+
+ /**
+ * Adds two vectors together and then normalizes the result
+ */
+ static void addAndNormalize(FVector *dest, const FVector *v1, const FVector *v2);
/**
* Returns the distance between a specified point and this one
*/
double getDistance(const FVector *src) const;
- static void fn4(FVector *dest, const FVector *v1, const FVector *v2);
- void fn5(FVector *dest, const CStarControlSub6 *sub6) const;
+ FVector fn5(const CStarControlSub6 *sub6) const;
/**
* Returns true if the passed vector equals this one
diff --git a/engines/titanic/star_control/star_control_sub12.cpp b/engines/titanic/star_control/star_control_sub12.cpp
index 79061301d3..4e6a6bc0f2 100644
--- a/engines/titanic/star_control/star_control_sub12.cpp
+++ b/engines/titanic/star_control/star_control_sub12.cpp
@@ -29,9 +29,8 @@ namespace Titanic {
FMatrix *CStarControlSub12::_matrix1;
FMatrix *CStarControlSub12::_matrix2;
-CStarControlSub12::CStarControlSub12(void *val1, const CStar20Data *data) :
- _currentIndex(-1), _handlerP(nullptr), _field108(0),
- _sub13(val1) {
+CStarControlSub12::CStarControlSub12(const CStar20Data *data) :
+ _currentIndex(-1), _handlerP(nullptr), _field108(0) {
setupHandler(data);
}
@@ -55,7 +54,7 @@ CStarControlSub12::~CStarControlSub12() {
deleteHandler();
}
-void CStarControlSub12::proc2(const void *src) {
+void CStarControlSub12::proc2(const CStarControlSub13 *src) {
_sub13.copyFrom(src);
}
@@ -114,12 +113,11 @@ void CStarControlSub12::proc13(CStarControlSub13 *dest) {
*dest = _sub13;
}
-void CStarControlSub12::proc14(int v) {
- FMatrix matrix;
- _sub13.getMatrix(&matrix);
+void CStarControlSub12::proc14(FVector &v) {
+ FMatrix matrix = _sub13.getMatrix();
FVector vector = _sub13._position;
- _handlerP->proc9(&vector, v, &matrix);
+ _handlerP->proc9(vector, v, matrix);
}
void CStarControlSub12::proc15(CErrorCode *errorCode) {
@@ -128,12 +126,12 @@ void CStarControlSub12::proc15(CErrorCode *errorCode) {
if (!_matrix2)
_matrix2 = new FMatrix();
- _sub13.getMatrix(_matrix1);
+ *_matrix1 = _sub13.getMatrix();
*_matrix2 = *_matrix1;
FVector v1 = _sub13._position;
FVector v2 = _sub13._position;
- _handlerP->proc11(*errorCode, v2, _matrix2);
+ _handlerP->proc11(*errorCode, v2, *_matrix2);
if (v1 != v2) {
_sub13.setPosition(v2);
@@ -141,7 +139,7 @@ void CStarControlSub12::proc15(CErrorCode *errorCode) {
}
if (_matrix1 != _matrix2) {
- _sub13.setMatrix(_matrix2);
+ _sub13.setMatrix(*_matrix2);
}
}
@@ -161,12 +159,12 @@ void CStarControlSub12::proc19() {
_handlerP->proc7();
}
-void CStarControlSub12::proc20(double v) {
+void CStarControlSub12::proc20(double factor) {
if (!isLocked())
- _sub13.fn14(v);
+ _sub13.reposition(factor);
}
-void CStarControlSub12::proc21(CStarControlSub6 &sub6) {
+void CStarControlSub12::proc21(const CStarControlSub6 *sub6) {
if (!isLocked()) {
_sub13.setPosition(sub6);
set108();
@@ -217,8 +215,103 @@ FVector CStarControlSub12::proc31(int index, const FVector &v) {
return _sub13.fn18(index, v);
}
-void CStarControlSub12::setViewportPosition(const FPoint &pt) {
- // TODO
+void CStarControlSub12::setViewportPosition(const FPoint &angles) {
+ if (isLocked())
+ return;
+
+ if (_currentIndex == -1) {
+ CStarControlSub6 subX(X_AXIS, angles._x);
+ CStarControlSub6 subY(Y_AXIS, angles._y);
+ CStarControlSub6 sub(&subX, &subY);
+ subY.copyFrom(&sub);
+ proc22(subY);
+ } else if (_currentIndex == 0) {
+ FVector row1 = _matrix._row1;
+ CStarControlSub6 subX(X_AXIS, angles._x);
+ CStarControlSub6 subY(Y_AXIS, angles._y);
+ CStarControlSub6 sub(&subX, &subY);
+ subX.copyFrom(&sub);
+
+ FMatrix m1 = _sub13.getMatrix();
+ FVector tempV1 = _sub13._position;
+ FVector tempV2, tempV3, tempV4, tempV5, tempV6;
+ tempV2._y = m1._row1._y * 100000.0;
+ tempV2._z = m1._row1._z * 100000.0;
+ tempV3._x = m1._row1._x * 100000.0 + tempV1._x;
+ tempV4._x = tempV3._x;
+ tempV3._y = tempV2._y + tempV1._y;
+ tempV4._y = tempV3._y;
+ tempV3._z = tempV2._z + tempV1._z;
+ tempV4._z = tempV3._z;
+ tempV2._x = m1._row2._x * 100000.0;
+ tempV2._y = m1._row2._y * 100000.0;
+ tempV2._z = m1._row2._z * 100000.0;
+ tempV2._x = m1._row3._x * 100000.0;
+ tempV2._y = m1._row3._y * 100000.0;
+ tempV2._z = m1._row3._z * 100000.0;
+ tempV2._x = tempV2._x + tempV1._x;
+ tempV2._y = tempV2._y + tempV1._y;
+ tempV2._z = tempV2._z + tempV1._z;
+ tempV3._x = tempV2._x + tempV1._x;
+ tempV3._y = tempV2._y + tempV1._y;
+ tempV5._x = tempV2._x;
+ tempV5._y = tempV2._y;
+ tempV3._z = tempV2._z + tempV1._z;
+ tempV5._z = tempV2._z;
+ tempV6._x = tempV3._x;
+ tempV6._y = tempV3._y;
+ tempV6._z = tempV3._z;
+ tempV1._x = tempV1._x - row1._x;
+ tempV1._y = tempV1._y - row1._y;
+ tempV1._z = tempV1._z - row1._z;
+ tempV4._x = tempV3._x - row1._x;
+ tempV4._y = tempV4._y - row1._y;
+ tempV4._z = tempV4._z - row1._z;
+ tempV5._x = tempV2._x - row1._x;
+
+ tempV5._y = tempV5._y - row1._y;
+ tempV5._z = tempV5._z - row1._z;
+ tempV6._x = tempV3._x - row1._x;
+ tempV6._y = tempV6._y - row1._y;
+ tempV6._z = tempV6._z - row1._z;
+
+ FVector modV1 = tempV1.fn5(&subX);
+ FVector modV2 = tempV4.fn5(&subX);
+ FVector modV3 = tempV5.fn5(&subX);
+ FVector modV4 = tempV6.fn5(&subX);
+ tempV1 = modV1;
+ tempV4 = modV2;
+ tempV5 = modV3;
+ tempV4 = modV4;
+
+ tempV2._x = tempV4._x - tempV1._x;
+ tempV2._y = tempV4._y - tempV1._y;
+ tempV2._z = tempV4._z - tempV1._z;
+ tempV4._x = tempV2._x;
+ tempV4._y = tempV2._y;
+ tempV2._x = tempV5._x - tempV1._x;
+ tempV4._z = tempV2._z;
+ tempV5._x = tempV2._x;
+ tempV2._y = tempV5._y - tempV1._y;
+ tempV5._y = tempV2._y;
+ tempV2._z = tempV5._z - tempV1._z;
+ tempV5._z = tempV2._z;
+ tempV2._x = tempV6._x - tempV1._x;
+ tempV2._y = tempV6._y - tempV1._y;
+ tempV2._z = tempV6._z - tempV1._z;
+ tempV6 = tempV2;
+
+ tempV4.normalize();
+ tempV5.normalize();
+ tempV6.normalize();
+ tempV1 += row1;
+
+ m1.set(tempV4, tempV5, tempV6);
+ _sub13.setMatrix(m1);
+ _sub13.setPosition(tempV1);
+ } else if (_currentIndex == 1) {
+ // TODO
+ }
}
bool CStarControlSub12::setArrayVector(const FVector &v) {
diff --git a/engines/titanic/star_control/star_control_sub12.h b/engines/titanic/star_control/star_control_sub12.h
index 5fac6bf11a..b1a25682d7 100644
--- a/engines/titanic/star_control/star_control_sub12.h
+++ b/engines/titanic/star_control/star_control_sub12.h
@@ -39,7 +39,7 @@ private:
static FMatrix *_matrix2;
private:
int _currentIndex;
- FVector _array[3];
+ FMatrix _matrix;
CStarControlSub20 *_handlerP;
CStarControlSub13 _sub13;
int _field108;
@@ -62,11 +62,11 @@ public:
static void init();
static void deinit();
public:
- CStarControlSub12(void *val1, const CStar20Data *data);
+ CStarControlSub12(const CStar20Data *data);
CStarControlSub12(CStarControlSub13 *src);
virtual ~CStarControlSub12();
- virtual void proc2(const void *src);
+ virtual void proc2(const CStarControlSub13 *src);
virtual void proc3(const CStar20Data *src);
virtual void setPosition(const FVector &v);
virtual void proc5(const FVector &v);
@@ -78,14 +78,14 @@ public:
virtual void proc11();
virtual void proc12(StarMode mode, double v2);
virtual void proc13(CStarControlSub13 *dest);
- virtual void proc14(int v);
+ virtual void proc14(FVector &v);
virtual void proc15(CErrorCode *errorCode);
virtual void proc16();
virtual void proc17();
virtual void proc18();
virtual void proc19();
- virtual void proc20(double v);
- virtual void proc21(CStarControlSub6 &sub6);
+ virtual void proc20(double factor);
+ virtual void proc21(const CStarControlSub6 *sub6);
virtual void proc22(FMatrix &m);
virtual CStarControlSub6 proc23();
virtual CStarControlSub6 proc24();
@@ -100,7 +100,7 @@ public:
/**
* Sets the viewport position within the starfield
*/
- virtual void setViewportPosition(const FPoint &pt);
+ virtual void setViewportPosition(const FPoint &angles);
virtual int getCurrentIndex() const { return _currentIndex; }
virtual bool setArrayVector(const FVector &v);
diff --git a/engines/titanic/star_control/star_control_sub13.cpp b/engines/titanic/star_control/star_control_sub13.cpp
index d70ad55f4a..6512d12232 100644
--- a/engines/titanic/star_control/star_control_sub13.cpp
+++ b/engines/titanic/star_control/star_control_sub13.cpp
@@ -21,29 +21,27 @@
*/
#include "titanic/star_control/star_control_sub13.h"
+#include "titanic/titanic.h"
namespace Titanic {
-CStarControlSub13::CStarControlSub13(void *src) :
- _fieldC0(0), _fieldC4(0), _fieldC8(0.0), _fieldCC(0.0), _fieldD0(0.0) {
- if (src) {
- setup(src);
- } else {
- _fieldC = 0;
- _field10 = 0x44480000;
- _field14 = 0x461C4000;
- _field18 = 0x41A00000;
- _field1C = 0x41A00000;
- _width = 600;
- _height = 340;
- _field24 = 0;
- }
-
- _fieldD4 = 0;
+CStarControlSub13::CStarControlSub13() {
+ _fieldC = 0;
+ _field10 = 800.0;
+ _field14 = 10000.0;
+ _field18 = 20.0;
+ _field1C = 20.0;
+ _width = 600;
+ _height = 340;
+ _field24 = 0;
+ _fieldC0 = _fieldC4 = _fieldC8 = 0.0;
+ _fieldCC = _fieldD0 = 0.0;
+ _flag = false;
+ Common::fill(&_valArray[0], &_valArray[5], 0.0);
}
CStarControlSub13::CStarControlSub13(CStarControlSub13 *src) :
- _matrix(&src->_matrix), _sub1(&src->_sub1), _sub2(&src->_sub2) {
+ _matrix(src->_matrix), _sub1(&src->_sub1), _sub2(&src->_sub2) {
_position = src->_position;
_fieldC = src->_fieldC;
_field10 = src->_field10;
@@ -60,26 +58,17 @@ CStarControlSub13::CStarControlSub13(CStarControlSub13 *src) :
_fieldC8 = src->_fieldC8;
_field24 = src->_field24;
- _valArray[0] = src->_valArray[0];
- _valArray[2] = src->_valArray[2];
- _valArray[3] = src->_valArray[3];
- _fieldD4 = 0;
-}
-
-void CStarControlSub13::setup(void *ptr) {
- // TODO
+ Common::copy(&src->_valArray[0], &src->_valArray[4], &_valArray[0]);
+ _flag = false;
}
-void CStarControlSub13::copyFrom(const void *src) {
- if (!src)
- return;
-/*
- _field0 = src->_field0;
- _field4 = src->_field4;
- _field8 = src->_field8;
- _fieldC = src->_field18;
- _field10 = src->_field1C;
- */
+void CStarControlSub13::copyFrom(const CStarControlSub13 *src) {
+ if (src) {
+ // TODO: Not really certain src is a CStarControlSub13
+ _position = src->_position;
+ _fieldC = src->_field18;
+ _field10 = src->_field1C;
+ }
}
void CStarControlSub13::load(SimpleFile *file, int param) {
@@ -101,7 +90,7 @@ void CStarControlSub13::load(SimpleFile *file, int param) {
_valArray[idx] = file->readFloat();
_matrix.load(file, param);
- _fieldD4 = 0;
+ _flag = false;
}
void CStarControlSub13::save(SimpleFile *file, int indent) {
@@ -123,53 +112,62 @@ void CStarControlSub13::save(SimpleFile *file, int indent) {
void CStarControlSub13::setPosition(const FVector &v) {
_position = v;
- _fieldD4 = 0;
+ _flag = false;
}
-void CStarControlSub13::setPosition(const CStarControlSub6 &sub6) {
- FVector vector;
- _position.fn5(&vector, &sub6);
- _position = sub6._row1;
- _fieldD4 = 0;
+void CStarControlSub13::setPosition(const CStarControlSub6 *sub6) {
+ _position.fn5(sub6);
+ _position = sub6->_row1;
+ _flag = false;
}
void CStarControlSub13::setMatrix(const FMatrix &m) {
_matrix = m;
- _fieldD4 = 0;
+ _flag = false;
}
void CStarControlSub13::fn11(const FVector &v) {
- _matrix.fn1(&v);
- _fieldD4 = 0;
+ _matrix.fn1(v);
+ _flag = false;
}
-void CStarControlSub13::setC(int v) {
+void CStarControlSub13::setC(double v) {
_fieldC = v;
- _fieldD4 = 0;
+ _flag = false;
}
-void CStarControlSub13::set10(int v) {
+void CStarControlSub13::set10(double v) {
_field10 = v;
- _fieldD4 = 0;
+ _flag = false;
}
-void CStarControlSub13::set14(int v) {
+void CStarControlSub13::set14(double v) {
_field10 = v;
}
-void CStarControlSub13::set18(int v) {
+void CStarControlSub13::set18(double v) {
_field18 = v;
- _fieldD4 = 0;
+ _flag = false;
}
-void CStarControlSub13::set1C(int v) {
+void CStarControlSub13::set1C(double v) {
_field1C = v;
- _fieldD4 = 0;
+ _flag = false;
}
void CStarControlSub13::fn12() {
- _matrix.clear();
- error("TODO: CStarControlSub13::fn12");
+ _matrix.identity();
+
+ CStarControlSub6 m1(X_AXIS, g_vm->getRandomNumber(359));
+ CStarControlSub6 m2(Y_AXIS, g_vm->getRandomNumber(359));
+ CStarControlSub6 m3(Z_AXIS, g_vm->getRandomNumber(359));
+
+ CStarControlSub6 s1(&m1, &m2);
+ CStarControlSub6 s2(&s1, &m3);
+
+ m1.copyFrom(s2);
+ _matrix.fn2(m1);
+ _flag = false;
}
void CStarControlSub13::fn13(StarMode mode, double v2) {
@@ -185,52 +183,95 @@ void CStarControlSub13::fn13(StarMode mode, double v2) {
_field24 = v2 ? 2 : 0;
}
-void CStarControlSub13::fn14(double v) {
- error("TODO: CStarControlSub13::fn14");
+void CStarControlSub13::reposition(double factor) {
+ _position._x = _matrix._row3._x * factor + _position._x;
+ _position._y = _matrix._row3._y * factor + _position._y;
+ _position._z = _matrix._row3._z * factor + _position._z;
+ _flag = false;
}
-void CStarControlSub13::fn15(FMatrix &matrix) {
- _matrix.fn3(&matrix);
- _fieldD4 = 0;
+void CStarControlSub13::fn15(const FMatrix &matrix) {
+ _matrix.fn3(matrix);
+ _flag = false;
}
CStarControlSub6 CStarControlSub13::getSub1() {
- if (!_fieldD4)
+ if (!_flag)
reset();
return _sub1;
}
CStarControlSub6 CStarControlSub13::getSub2() {
- if (!_fieldD4)
+ if (!_flag)
reset();
return _sub2;
}
void CStarControlSub13::fn16(int index, const FVector &src, FVector &dest) {
- error("TODO: CStarControlSub13::fn16");
+ CStarControlSub6 temp = getSub1();
+
+ dest._x = temp._row3._x * src._z + temp._row2._x * src._y
+ + src._x * temp._row1._x + temp._vector._x;
+ dest._y = temp._row3._y * src._z + temp._row2._y * src._y
+ + src._x * temp._row1._y + temp._vector._y;
+ dest._z = temp._row3._z * src._z + temp._row2._z * src._y
+ + src._x * temp._row1._z + temp._vector._z;
}
-FVector CStarControlSub13::fn17(int index, const FVector &v) {
- error("TODO: CStarControlSub13::fn17");
+FVector CStarControlSub13::fn17(int index, const FVector &src) {
+ FVector dest;
+ CStarControlSub6 sub6 = getSub1();
+ FVector tv = src.fn5(&sub6);
+
+ dest._x = (_valArray[index] + tv._x)
+ * _fieldC8 / (_fieldCC * tv._z);
+ dest._y = (tv._y * _fieldC8) / (_fieldD0 * tv._z);
+ dest._z = tv._z;
+ return dest;
}
-FVector CStarControlSub13::fn18(int index, const FVector &v) {
- error("TODO: CStarControlSub13::fn17");
+FVector CStarControlSub13::fn18(int index, const FVector &src) {
+ FVector dest;
+ CStarControlSub6 sub6 = getSub2();
+ FVector tv = src.fn5(&sub6);
+
+ dest._x = (_valArray[index] + tv._x)
+ * _fieldC8 / (_fieldCC * tv._z);
+ dest._y = (tv._y * _fieldC8) / (_fieldD0 * tv._z);
+ dest._z = tv._z;
+ return dest;
}
void CStarControlSub13::fn19(double *v1, double *v2, double *v3, double *v4) {
- error("TODO: CStarControlSub13::fn19");
+ *v1 = _fieldC8 / _fieldCC;
+ *v2 = _fieldC8 / _fieldD0;
+ *v3 = _valArray[3];
+ *v4 = _valArray[4];
}
void CStarControlSub13::reset() {
- //const double FACTOR = 3.1415927 * 0.0055555557;
- error("TODO: CStarControlSub13::reset");
+ const double FACTOR = 2 * M_PI / 360.0;
+
+ _sub2.copyFrom(_matrix);
+ _sub2._vector._x = _position._x;
+ _sub2._vector._y = _position._y;
+ _sub2._vector._z = _position._z;
+ _sub2.fn4(&_sub1);
+
+ double widthV = (double)_width * 0.5;
+ double heightV = (double)_height * 0.5;
+ _fieldC0 = widthV;
+ _fieldC4 = heightV;
+ _fieldC8 = MIN(widthV, heightV);
+ _fieldCC = tan(_field18 * FACTOR);
+ _fieldD0 = tan(_field1C * FACTOR);
+ _flag = true;
}
-void CStarControlSub13::getMatrix(FMatrix *matrix) {
- *matrix = _matrix;
+const FMatrix &CStarControlSub13::getMatrix() const {
+ return _matrix;
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub13.h b/engines/titanic/star_control/star_control_sub13.h
index 047df987d2..80b2e55c4b 100644
--- a/engines/titanic/star_control/star_control_sub13.h
+++ b/engines/titanic/star_control/star_control_sub13.h
@@ -42,10 +42,8 @@ private:
CStarControlSub6 _sub2;
double _fieldC0;
double _fieldC4;
- int _fieldD4;
+ bool _flag;
private:
- void setup(void *ptr);
-
void reset();
public:
FVector _position;
@@ -57,10 +55,13 @@ public:
double _fieldCC;
double _fieldD0;
public:
- CStarControlSub13(void *ptr);
+ CStarControlSub13();
CStarControlSub13(CStarControlSub13 *src);
- void copyFrom(const void *src);
+ /**
+ * Copys the data from another instance
+ */
+ void copyFrom(const CStarControlSub13 *src);
/**
* Load the data for the class from file
@@ -80,7 +81,7 @@ public:
/**
* Sets the position
*/
- void setPosition(const CStarControlSub6 &sub6);
+ void setPosition(const CStarControlSub6 *sub6);
/**
* Sets the matrix
@@ -90,25 +91,25 @@ public:
void fn11(const FVector &v);
void fn12();
void fn13(StarMode mode, double v2);
- void fn14(double v);
- void fn15(FMatrix &matrix);
+ void reposition(double factor);
+ void fn15(const FMatrix &matrix);
CStarControlSub6 getSub1();
CStarControlSub6 getSub2();
void fn16(int index, const FVector &src, FVector &dest);
- FVector fn17(int index, const FVector &v);
- FVector fn18(int index, const FVector &v);
+ FVector fn17(int index, const FVector &src);
+ FVector fn18(int index, const FVector &src);
void fn19(double *v1, double *v2, double *v3, double *v4);
/**
- * Makes a copy of the instance's matrix into the passed matrix
+ * Returns the instance's matrix
*/
- void getMatrix(FMatrix *matrix);
+ const FMatrix &getMatrix() const;
- void setC(int v);
- void set10(int v);
- void set14(int v);
- void set18(int v);
- void set1C(int v);
+ void setC(double v);
+ void set10(double v);
+ void set14(double v);
+ void set18(double v);
+ void set1C(double v);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub2.cpp b/engines/titanic/star_control/star_control_sub2.cpp
index cf7190fb34..ebeb9bf239 100644
--- a/engines/titanic/star_control/star_control_sub2.cpp
+++ b/engines/titanic/star_control/star_control_sub2.cpp
@@ -21,9 +21,15 @@
*/
#include "titanic/star_control/star_control_sub2.h"
+#include "titanic/star_control/star_control_sub12.h"
namespace Titanic {
+bool CStarControlSub2::setup() {
+ loadData("STARFIELD/132");
+ return true;
+}
+
bool CStarControlSub2::loadYale(int v1) {
clear();
error("Original loadYale not supported");
@@ -31,19 +37,20 @@ bool CStarControlSub2::loadYale(int v1) {
}
bool CStarControlSub2::selectStar(CSurfaceArea *surfaceArea,
- CStarControlSub12 *sub12, int flags, const Common::Point &pt) {
- // TODO
- return true;
+ CStarControlSub12 *sub12, const Common::Point &pt, void *handler) {
+ int index = baseFn1(surfaceArea, sub12, pt);
+ if (index == -1) {
+ return false;
+ } else if (!handler) {
+ sub12->proc14(_data[index]._position);
+ return true;
+ } else {
+ error("no handler ever passed in original");
+ }
}
bool CStarControlSub2::loadStar() {
- // TODO
- return true;
-}
-
-bool CStarControlSub2::setup() {
- // TODO
- return true;
+ error("loadStar not supported");
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub2.h b/engines/titanic/star_control/star_control_sub2.h
index 9de2da4583..bcf7397fe1 100644
--- a/engines/titanic/star_control/star_control_sub2.h
+++ b/engines/titanic/star_control/star_control_sub2.h
@@ -37,7 +37,7 @@ public:
* Selects a star
*/
virtual bool selectStar(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12,
- int flags, const Common::Point &pt);
+ const Common::Point &pt, void *handler = nullptr);
virtual bool loadStar();
diff --git a/engines/titanic/star_control/star_control_sub20.cpp b/engines/titanic/star_control/star_control_sub20.cpp
index cc1029896a..ca60cc9948 100644
--- a/engines/titanic/star_control/star_control_sub20.cpp
+++ b/engines/titanic/star_control/star_control_sub20.cpp
@@ -32,7 +32,7 @@ CStarControlSub20::CStarControlSub20(const CStar20Data *src) {
if (src) {
copyFrom(src);
} else {
- _field0 = 0.0;
+ _size = 0.0;
_field4 = 0.0;
_field8 = 20.0;
_fieldC = 0.0;
@@ -56,22 +56,22 @@ void CStarControlSub20::copyTo(CStar20Data *dest) {
}
void CStarControlSub20::proc4() {
- if (!isLocked() && _field0 < _field10) {
- _field4 += _field0;
+ if (!isLocked() && _size < _field10) {
+ _field4 += _size;
if (_field8 == _field4)
- _field0 -= _field4;
+ _size -= _field4;
else
- _field0 += _field4;
+ _size += _field4;
}
}
void CStarControlSub20::proc5() {
if (!isLocked()) {
_field4 -= _field8;
- if (_field4 == _field0)
- _field0 += _field4;
+ if (_field4 == _size)
+ _size += _field4;
else
- _field0 -= _field4;
+ _size -= _field4;
if (_field4 < 0.0)
_field4 = 0.0;
@@ -80,19 +80,23 @@ void CStarControlSub20::proc5() {
void CStarControlSub20::proc6() {
if (!isLocked())
- _field0 = _field10;
+ _size = _field10;
}
void CStarControlSub20::proc7() {
if (!isLocked()) {
- _field0 = 0.0;
+ _size = 0.0;
_field4 = 0.0;
}
}
void CStarControlSub20::proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
- if (_field0 > 0.0) {
- warning("TODO: CStarControlSub20::proc11");
+ if (_size > 0.0) {
+ v._x += m._row3._x * _size;
+ v._y += m._row3._y * _size;
+ v._z += m._row3._z * _size;
+
+ errorCode.set();
}
}
@@ -110,7 +114,7 @@ void CStarControlSub20::clear() {
void CStarControlSub20::load(SimpleFile *file, int val) {
if (!val) {
- _field0 = file->readFloat();
+ _size = file->readFloat();
_field4 = file->readFloat();
_field8 = file->readFloat();
_fieldC = file->readFloat();
@@ -122,7 +126,7 @@ void CStarControlSub20::load(SimpleFile *file, int val) {
}
void CStarControlSub20::save(SimpleFile *file, int indent) {
- file->writeFloatLine(_field0, indent);
+ file->writeFloatLine(_size, indent);
file->writeFloatLine(_field4, indent);
file->writeFloatLine(_field8, indent);
file->writeFloatLine(_fieldC, indent);
diff --git a/engines/titanic/star_control/star_control_sub20.h b/engines/titanic/star_control/star_control_sub20.h
index 9dbabbb7f1..49b63d5d5d 100644
--- a/engines/titanic/star_control/star_control_sub20.h
+++ b/engines/titanic/star_control/star_control_sub20.h
@@ -30,7 +30,7 @@
namespace Titanic {
struct CStar20Data {
- double _field0;
+ double _size;
double _field4;
double _field8;
double _fieldC;
@@ -54,9 +54,9 @@ public:
virtual void proc5();
virtual void proc6();
virtual void proc7();
- virtual void proc8() {}
- virtual void proc9(FVector *v, int v2, FMatrix *matrix) {}
- virtual void proc10() {}
+ virtual void proc8(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2) {}
+ virtual void proc9(FVector &v1, FVector &v2, FMatrix &matrix) {}
+ virtual void proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) {}
virtual void proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m);
/**
diff --git a/engines/titanic/star_control/star_control_sub21.cpp b/engines/titanic/star_control/star_control_sub21.cpp
index 41d24d55c0..1e676b7703 100644
--- a/engines/titanic/star_control/star_control_sub21.cpp
+++ b/engines/titanic/star_control/star_control_sub21.cpp
@@ -21,15 +21,51 @@
*/
#include "titanic/star_control/star_control_sub21.h"
+#include "titanic/star_control/dmatrix.h"
+#include "titanic/star_control/dvector.h"
#include "common/textconsole.h"
namespace Titanic {
CStarControlSub21::CStarControlSub21(const CStar20Data *src) :
CStarControlSub20(src) {
-#if 0
- _sub24()
-#endif
+}
+
+void CStarControlSub21::proc9(FVector &v1, FVector &v2, FMatrix &matrix) {
+ if (isLocked())
+ decLockCount();
+
+ _sub24.proc4(v1, v2, matrix);
+}
+
+void CStarControlSub21::proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m) {
+ if (isLocked())
+ decLockCount();
+
+ DVector vector1 = v1;
+ DVector vector2 = v2;
+ DMatrix matrix1, matrix2 = m, matrix3;
+ vector2.fn4(vector1, matrix1);
+ const DMatrix *matrixP = matrix1.fn4(matrix3, matrix1, matrix2);
+
+ FMatrix matrix4 = *matrixP;
+ _sub24.proc3(m, matrix4);
+ incLockCount();
+}
+
+void CStarControlSub21::proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
+ if (_sub24.get8()) {
+ int val = _sub24.proc5(errorCode, v, m);
+ if (val == 1)
+ incLockCount();
+ if (val == 2) {
+ proc7();
+ error("TODO: _dataP");
+ }
+ } else if (_size != 0.0) {
+ // TODO
+ error("TODO");
+ }
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub21.h b/engines/titanic/star_control/star_control_sub21.h
index 3f47a1a3e1..66ce535993 100644
--- a/engines/titanic/star_control/star_control_sub21.h
+++ b/engines/titanic/star_control/star_control_sub21.h
@@ -30,11 +30,14 @@ namespace Titanic {
class CStarControlSub21 : public CStarControlSub20 {
private:
-#if 0
CStarControlSub24 _sub24;
-#endif
public:
CStarControlSub21(const CStar20Data *src);
+ virtual ~CStarControlSub21() {}
+
+ virtual void proc9(FVector &v1, FVector &v2, FMatrix &matrix);
+ virtual void proc10(const FVector &v1, const FVector &v2, const FVector &v3, const FMatrix &m);
+ virtual void proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub22.cpp b/engines/titanic/star_control/star_control_sub22.cpp
index 05a1cec87d..b76d96e47a 100644
--- a/engines/titanic/star_control/star_control_sub22.cpp
+++ b/engines/titanic/star_control/star_control_sub22.cpp
@@ -27,9 +27,18 @@ namespace Titanic {
CStarControlSub22::CStarControlSub22(const CStar20Data *src) :
CStarControlSub20(src) {
-#if 0
- _sub27()
-#endif
+}
+
+void CStarControlSub22::proc8(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2) {
+ if (isLocked())
+ decLockCount();
+
+ _sub27.proc2(v1, v2, m1, m2);
+ incLockCount();
+}
+
+void CStarControlSub22::proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
+ // TODO
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub22.h b/engines/titanic/star_control/star_control_sub22.h
index 4d353aa074..61f60b10f1 100644
--- a/engines/titanic/star_control/star_control_sub22.h
+++ b/engines/titanic/star_control/star_control_sub22.h
@@ -30,11 +30,13 @@ namespace Titanic {
class CStarControlSub22 : public CStarControlSub20 {
private:
-#if 0
CStarControlSub27 _sub27;
-#endif
public:
CStarControlSub22(const CStar20Data *src);
+ virtual ~CStarControlSub22() {}
+
+ virtual void proc8(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2);
+ virtual void proc11(CErrorCode &errorCode, FVector &v, const FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub23.cpp b/engines/titanic/star_control/star_control_sub23.cpp
index b009cbc35b..4587fd3e27 100644
--- a/engines/titanic/star_control/star_control_sub23.cpp
+++ b/engines/titanic/star_control/star_control_sub23.cpp
@@ -25,4 +25,89 @@
namespace Titanic {
+CStarControlSub23::CStarControlSub23() : _row1(0.0, 1000000.0, 0.0) {
+ _field4 = 0;
+ _field8 = 0;
+ _field24 = 0.0;
+ _field34 = 0;
+ _field38 = 0;
+ _field3C = 0;
+ _field40 = 0;
+ _field44 = 0;
+ _field48 = 0;
+ _field4C = 0;
+ _field54 = 0;
+ _field58 = 0;
+ _field5C = 0;
+ _field60 = 0;
+ _field64 = 0;
+}
+
+void CStarControlSub23::proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2) {
+ _row1 = v1;
+ _row2 = v2;
+ _row3 = _row2 - _row1;
+ _field24 = _row3.normalize();
+
+ _field58 = 0;
+ _field8 = 0;
+ _field34 = 0;
+ _field5C = 1.875;
+ _field40 = -1;
+ _field44 = -1;
+ _field48 = -1;
+ _field4C = 0;
+}
+
+void CStarControlSub23::proc3(const FMatrix &m1, const FMatrix &m2) {
+ _row1.clear();
+ _row2.clear();
+ _field58 = 0;
+ _field24 = 0.0;
+ _field8 = 0;
+ _field34 = 0;
+ _field5C = 1.875;
+}
+
+void CStarControlSub23::proc4(FVector &v1, FVector &v2, FMatrix &m) {
+ _row1 = v1;
+ _row2 = v2;
+ FVector vector = _row2 - _row1;
+ _row3 = vector;
+ _field24 = _row3.normalize();
+
+ _field8 = 0;
+ _field34 = 0;
+ _field40 = -1;
+ _field44 = -1;
+ _field48 = -1;
+ _field4C = -1;
+ _field58 = 0;
+ _field5C = 1.875;
+}
+
+void CStarControlSub23::proc6(int val1, int val2, float val) {
+ _field44 = val1;
+ _field4C = val1 + 62;
+ _field38 = val / (double)(val1 + val2 * 2);
+ _field40 = 31;
+ _field48 = 31;
+ _field3C = (double)val2 * _field38;
+
+ if (_powers.empty())
+ _powers.resize(32);
+
+ // Calculate the powers table
+ double exponent = 0.0, total = 0.0;
+ for (int idx = 31; idx >= 0; --idx) {
+ _powers[idx] = pow(4.0, exponent);
+ total += _powers[idx];
+ exponent += 0.03125;
+ }
+
+ for (int idx = 0; idx < 32; ++idx) {
+ _powers[idx] = _powers[idx] * _field3C / total;
+ }
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub23.h b/engines/titanic/star_control/star_control_sub23.h
index 136401e329..9e90e021a2 100644
--- a/engines/titanic/star_control/star_control_sub23.h
+++ b/engines/titanic/star_control/star_control_sub23.h
@@ -23,9 +23,45 @@
#ifndef TITANIC_STAR_CONTROL_SUB23_H
#define TITANIC_STAR_CONTROL_SUB23_H
+#include "titanic/star_control/error_code.h"
+#include "titanic/star_control/fmatrix.h"
+#include "titanic/star_control/fvector.h"
+#include "titanic/star_control/star_control_sub25.h"
+
namespace Titanic {
class CStarControlSub23 {
+protected:
+ int _field4;
+ int _field8;
+ FVector _row1, _row2;
+ double _field24;
+ FVector _row3;
+ int _field34;
+ double _field38;
+ int _field3C;
+ int _field40;
+ int _field44;
+ int _field48;
+ int _field4C;
+ Common::Array<double> _powers;
+ int _field54;
+ int _field58;
+ double _field5C;
+ double _field60;
+ double _field64;
+ CStarControlSub25 _sub25;
+public:
+ CStarControlSub23();
+ virtual ~CStarControlSub23() {}
+
+ virtual void proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2);
+ virtual void proc3(const FMatrix &m1, const FMatrix &m2);
+ virtual void proc4(FVector &v1, FVector &v2, FMatrix &m);
+ virtual int proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m) { return 2; }
+ virtual void proc6(int val1, int val2, float val);
+
+ int get8() const { return _field8; }
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub24.cpp b/engines/titanic/star_control/star_control_sub24.cpp
index 6f17eb7193..27f29b41ca 100644
--- a/engines/titanic/star_control/star_control_sub24.cpp
+++ b/engines/titanic/star_control/star_control_sub24.cpp
@@ -25,5 +25,19 @@
namespace Titanic {
+void CStarControlSub24::proc3(const FMatrix &m1, const FMatrix &m2) {
+
+}
+
+void CStarControlSub24::proc4(FVector &v1, FVector &v2, FMatrix &m) {
+ CStarControlSub23::proc4(v1, v2, m);
+
+ // TODO
+}
+
+int CStarControlSub24::proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
+ // TODO
+ return 0;
+}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub24.h b/engines/titanic/star_control/star_control_sub24.h
index e0970fc1de..34b9cf4eac 100644
--- a/engines/titanic/star_control/star_control_sub24.h
+++ b/engines/titanic/star_control/star_control_sub24.h
@@ -28,6 +28,12 @@
namespace Titanic {
class CStarControlSub24 : public CStarControlSub23 {
+public:
+ virtual ~CStarControlSub24() {}
+
+ virtual void proc3(const FMatrix &m1, const FMatrix &m2);
+ virtual void proc4(FVector &v1, FVector &v2, FMatrix &m);
+ virtual int proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub25.cpp b/engines/titanic/star_control/star_control_sub25.cpp
index f91c75af6a..73c72e6a77 100644
--- a/engines/titanic/star_control/star_control_sub25.cpp
+++ b/engines/titanic/star_control/star_control_sub25.cpp
@@ -25,4 +25,10 @@
namespace Titanic {
+void CStarControlSub25::fn1(const FMatrix &m1, const FMatrix &m2) {
+ _matrix1 = m1;
+ _matrix2 = m2;
+
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub25.h b/engines/titanic/star_control/star_control_sub25.h
index b61569c49d..85692cf62d 100644
--- a/engines/titanic/star_control/star_control_sub25.h
+++ b/engines/titanic/star_control/star_control_sub25.h
@@ -35,7 +35,7 @@ public:
CStarControlSub26 _sub1;
CStarControlSub26 _sub2;
public:
-
+ void fn1(const FMatrix &m1, const FMatrix &m2);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub26.cpp b/engines/titanic/star_control/star_control_sub26.cpp
index 89ff93c347..546a3e9fae 100644
--- a/engines/titanic/star_control/star_control_sub26.cpp
+++ b/engines/titanic/star_control/star_control_sub26.cpp
@@ -30,5 +30,16 @@ double CStarControlSub26::fn1() const {
_sub._v3 * _sub._v3 + _field0 * _field0;
}
+void CStarControlSub26::setup(double val1, double val2, double val3, double val4) {
+ _field0 = val1;
+ _sub._v1 = val2;
+ _sub._v2 = val3;
+ _sub._v3 = val4;
+}
+
+void CStarControlSub26::copyFrom(const CStarControlSub26 *src) {
+ _field0 = src->_field0;
+ _sub = src->_sub;
+}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub26.h b/engines/titanic/star_control/star_control_sub26.h
index 4054a2ba6e..9023da906c 100644
--- a/engines/titanic/star_control/star_control_sub26.h
+++ b/engines/titanic/star_control/star_control_sub26.h
@@ -39,7 +39,18 @@ public:
public:
CStarControlSub26() : _field0(1.0) {}
+ /**
+ * Sets the field values
+ */
+ void setup(double val1, double val2, double val3, double val4);
+
+ /**
+ * Copies from another instance
+ */
+ void copyFrom(const CStarControlSub26 *src);
+
double fn1() const;
+
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub27.cpp b/engines/titanic/star_control/star_control_sub27.cpp
index 6f17eb7193..706e947a05 100644
--- a/engines/titanic/star_control/star_control_sub27.cpp
+++ b/engines/titanic/star_control/star_control_sub27.cpp
@@ -20,10 +20,40 @@
*
*/
-#include "titanic/star_control/star_control_sub24.h"
+#include "titanic/star_control/star_control_sub27.h"
#include "common/textconsole.h"
namespace Titanic {
+void CStarControlSub27::proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2) {
+ CStarControlSub23::proc2(v1, v2, m1, m2);
+
+ int v24 = _field24;
+ if (_field24 > 0.0) {
+ _field8 = 1;
+ _field34 = 1;
+ proc6(120, 4, _field24);
+ }
+
+ if (m1 != m2) {
+ _sub25.fn1(m1, m2);
+ _field58 = 0;
+ _field5C = 0.0;
+
+ if (_field4C == 0) {
+ _field60 = -1.5881868e-23;
+ _field64 = 1.4499999;
+ _field8 = 1;
+ } else {
+ _field60 = 1.0 / (double)v24;
+ _field8 = 1;
+ }
+ }
+}
+
+int CStarControlSub27::proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m) {
+ // TODO
+ return 0;
+}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub27.h b/engines/titanic/star_control/star_control_sub27.h
index 01782b69ca..801591294e 100644
--- a/engines/titanic/star_control/star_control_sub27.h
+++ b/engines/titanic/star_control/star_control_sub27.h
@@ -28,6 +28,11 @@
namespace Titanic {
class CStarControlSub27 : public CStarControlSub23 {
+public:
+ virtual ~CStarControlSub27() {}
+
+ virtual void proc2(FVector &v1, FVector &v2, FMatrix &m1, FMatrix &m2);
+ virtual int proc5(CErrorCode &errorCode, FVector &v, const FMatrix &m);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub5.cpp b/engines/titanic/star_control/star_control_sub5.cpp
index 5023a59383..8c332975c6 100644
--- a/engines/titanic/star_control/star_control_sub5.cpp
+++ b/engines/titanic/star_control/star_control_sub5.cpp
@@ -26,6 +26,8 @@
namespace Titanic {
+#define MKTAG_BE(a3,a2,a1,a0) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24)))
+
void CStarControlSub5::SubEntry::clear() {
_data1.clear();
_data2.clear();
@@ -37,7 +39,7 @@ bool CStarControlSub5::SineTable::setup() {
if (_data.empty()) {
_data.resize(1024);
for (int idx = 0; idx < 1024; ++idx)
- _data[idx] = sin((double)idx * 6.283185307179586 * 0.001953125);
+ _data[idx] = sin((double)idx * 2 * M_PI / 512.0);
}
return true;
@@ -63,7 +65,7 @@ bool CStarControlSub5::setup() {
bool CStarControlSub5::setup2(int val1, int val2) {
// TODO: Original set an explicit random seed here. Could be
// problematic if following random values need to be deterministic
- const double FACTOR = 3.1415927 * 0.0055555557;
+ const double FACTOR = 2 * M_PI / 360.0;
const int VALUES1[] = { 0x800, 0xC00, 0x1000, 0x1400, 0x1800 };
const int VALUES2[] = {
0xF95BCD, 0xA505A0, 0xFFAD43, 0x98F4EB, 0xF3EFA5, 0,
@@ -76,9 +78,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
for (int idx = 0; idx < 256; ++idx) {
if (idx == 0) {
e->_field0 = 0x4C8;
- e->_field4 = 0x40;
- e->_field5 = 0x40;
- e->_field6 = 0x40;
+ e->_pixel1 = 0x40;
+ e->_pixel2 = 0x40;
+ e->_pixel3 = 0x40;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 7.0;
@@ -86,9 +88,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x574;
- e->_field4 = 0x7f;
- e->_field5 = 0;
- e->_field6 = 0;
+ e->_pixel1 = 0x7f;
+ e->_pixel2 = 0;
+ e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 3.0;
@@ -96,9 +98,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x603;
- e->_field4 = 0;
- e->_field5 = 0;
- e->_field6 = 0xff;
+ e->_pixel1 = 0;
+ e->_pixel2 = 0;
+ e->_pixel3 = 0xff;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = 0;
@@ -106,9 +108,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x712;
- e->_field4 = 0xff;
- e->_field5 = 0;
- e->_field6 = 0;
+ e->_pixel1 = 0xff;
+ e->_pixel2 = 0;
+ e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 2.0;
@@ -116,9 +118,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0xe7f;
- e->_field4 = 0xe6;
- e->_field5 = 0xbe;
- e->_field6 = 0;
+ e->_pixel1 = 0xe6;
+ e->_pixel2 = 0xbe;
+ e->_pixel3 = 0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 1.0;
@@ -126,9 +128,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x173f;
- e->_field4 = 0xf0;
- e->_field5 = 0xf0;
- e->_field6 = 0xe6;
+ e->_pixel1 = 0xf0;
+ e->_pixel2 = 0xf0;
+ e->_pixel3 = 0xe6;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 3.0;
@@ -136,9 +138,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x2ab8;
- e->_field4 = 0x28;
- e->_field5 = 0x32;
- e->_field6 = 0x28;
+ e->_pixel1 = 0x28;
+ e->_pixel2 = 0x32;
+ e->_pixel3 = 0x28;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 1.0;
@@ -146,9 +148,9 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x40ac;
- e->_field4 = 0x0;
- e->_field5 = 0xbe;
- e->_field6 = 0xf0;
+ e->_pixel1 = 0x0;
+ e->_pixel2 = 0xbe;
+ e->_pixel3 = 0xf0;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 2.0;
@@ -156,27 +158,27 @@ bool CStarControlSub5::setup2(int val1, int val2) {
++e;
e->_field0 = 0x539c;
- e->_field4 = 0x20;
- e->_field5 = 0x20;
- e->_field6 = 0x20;
+ e->_pixel1 = 0x20;
+ e->_pixel2 = 0x20;
+ e->_pixel3 = 0x20;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * 17.0;
- e->_field14 = 0.00390625;
+ e->_field14 = 1 / 256.0;
} else {
for (int ctr = 0; ctr < 5; ++ctr) {
e->_field0 = static_cast<int>(g_vm->getRandomFloat() * 1350.0
- 675.0) + VALUES1[idx];
int val = VALUES2[g_vm->getRandomNumber(15)];
- e->_field4 = val & 0xff;
- e->_field5 = (val >> 8) & 0xff;
- e->_field6 = (val >> 16) & 0xff;
+ e->_pixel1 = val & 0xff;
+ e->_pixel2 = (val >> 8) & 0xff;
+ e->_pixel3 = (val >> 16) & 0xff;
e->_field8 = g_vm->getRandomNumber(3) + 3;
e->_fieldC = g_vm->getRandomNumber(255);
e->_field10 = FACTOR * (double)g_vm->getRandomNumber(15);
- e->_field14 = ((double)g_vm->getRandomNumber(0xffffffff)
- * 50.0 * 0.000015259022) * 0.00390625;
+ e->_field14 = ((double)g_vm->getRandomNumber(0xfffffffe)
+ * 50.0 / 65536.0) / 256.0;
}
}
}
@@ -194,13 +196,23 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1,
const int VALUES[] = { 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4 };
double val1 = sub12->proc25();
int val2 = sub12->proc27();
+ if (!_flag)
+ return;
+
+ int f1, f3, size2, size1;
+ double f2, f4, f5, f6, f7, f8, f9;
+ double f10, f11, f12, f13, f14, f15, f16, f17, f18, f19;
+ double f20, f21, f22, f23, f24, f25, f26, f27, f28;
+ double f34, f35, f36, f37, f38, f39, f40;
+ double f41, f42, f43, f44, f45, f46;
+ FVector tempV;
if (v3 >= 6.0e9) {
int count, start;
if (vector->_x != 0.0 && (vector->_y != 0.0 || vector->_z != 0.0)) {
- // TODO: Non-sensical randSeed((int)vector->_x);
+ // WORKAROUND: Ignoring non-sensical randSeed((int)vector->_x);
count = VALUES[g_vm->getRandomNumber(15)];
- start = g_vm->getRandomNumber(255);
+ start = 5 * g_vm->getRandomNumber(255);
} else {
count = 9;
start = 0;
@@ -208,45 +220,280 @@ void CStarControlSub5::proc2(CStarControlSub6 *sub6, FVector *vector, double v1,
Entry *entryP = &_entries[start];
for (; count > 0; --count, ++entryP) {
- //eax=sineIndex1, ecx=sineIndex2,
- int sineIndex1 = (entryP->_field8 * _multiplier) & 0x1ff;
- int sineIndex2 = (entryP->_fieldC * _multiplier + entryP->_fieldC) & 0x1ff;
-
- double t1 = _sineTable[sineIndex2];
- double t2 = sin(_sineTable[sineIndex1] * entryP->_field10);
- double t3 = cos(_sineTable[sineIndex1] * entryP->_field10);
- double t4 = _sineTable[sineIndex2 + 512];
- double t5 = t3 * t4;
- t3 = t3 * t1;
- double t6 = entryP->_field14 * t5;
- double t7 = t2 * entryP->_field14;
- double t8 = entryP->_field14 * t3;
- double t9 = -(t2 * t4 * entryP->_field14);
- double t10 = t3 * entryP->_field14;
- double t11 = -(t2 * t1 * entryP->_field14);
- t4 = -(t1 * entryP->_field14);
- t1 = t4 * entryP->_field14;
-
- _sub1._row1._x = t6;
- _sub1._row1._y = t2 * entryP->_field14;
- _sub1._row1._z = entryP->_field14 * t3;
- _sub1._row2._x = -(t2 * t4 * entryP->_field14);
- _sub1._row2._y = t3 * entryP->_field14;
- _sub1._row2._z = -(t2 * t1 * entryP->_field14);
- _sub1._row3._x = -(t1 * entryP->_field14);
- _sub1._row3._z = t4 * entryP->_field14;
-
- double t12 = entryP->_field0;
- _sub1._vector._x = t12 * t5 + vector->_x;
- _sub1._vector._y = t12 * t2 + vector->_y;
- _sub1._vector._z = t12 * t3 + vector->_z;
-
- // TODO
- warning("TODO: %f %f %f %f %f %f %d", t7, t8, t9, t10, t11, val1, val2);
+ f1 = _multiplier * entryP->_field8;
+ f2 = entryP->_field14;
+ f3 = (f1 + entryP->_fieldC) & 0x1FF;
+ f4 = _sineTable[f1 & 0x1FF] * entryP->_field10;
+ f5 = _sineTable[f3];
+ f6 = cos(f4);
+ f7 = sin(f4);
+ f8 = _sineTable[f3 + 128];
+ f9 = f7;
+ f10 = f6 * f8;
+ f11 = f6;
+ f12 = f6 * f5;
+ f13 = f2 * f10;
+ f14 = f8 * f2;
+ f15 = f9 * f2;
+ f16 = f2 * f12;
+ f17 = -(f7 * f8 * f2);
+ f18 = f11 * f2;
+ f19 = -(f9 * f5 * f2);
+ f20 = -(f5 * f2);
+ f21 = f14;
+ _sub1._row1._x = f13;
+ _sub1._row1._y = f15;
+ _sub1._row1._z = f16;
+ _sub1._row2._x = f17;
+ _sub1._row2._y = f18;
+ _sub1._row2._z = f19;
+ _sub1._row3._x = f20;
+ _sub1._row3._z = f14;
+
+ f22 = (double)entryP->_field0;
+ _sub1._vector._x = f22 * f10 + vector->_x;
+ _sub1._vector._y = f9 * f22 + vector->_y;
+ _sub1._vector._z = f22 * f12 + vector->_z;
+ _sub2._row1._x = sub6->_row1._x * f13 + f16 * sub6->_row3._x + f15 * sub6->_row2._x;
+ _sub2._row1._y = f15 * sub6->_row2._y + f16 * sub6->_row3._y + f13 * sub6->_row1._y;
+ _sub2._row1._z = f16 * sub6->_row3._z + f13 * sub6->_row1._z + f15 * sub6->_row2._z;
+ _sub2._row2._x = sub6->_row1._x * f17 + f19 * sub6->_row3._x + f18 * sub6->_row2._x;
+ _sub2._row2._y = f18 * sub6->_row2._y + f17 * sub6->_row1._y + f19 * sub6->_row3._y;
+ _sub2._row2._z = f18 * sub6->_row2._z + f19 * sub6->_row3._z + f17 * sub6->_row1._z;
+ _sub2._row3._x = sub6->_row1._x * f20 + f21 * sub6->_row3._x;
+ _sub2._row3._y = f20 * sub6->_row1._y + f21 * sub6->_row3._y;
+ _sub2._row3._z = f20 * sub6->_row1._z + f21 * sub6->_row3._z;
+
+ f23 = _sub1._vector._y;
+ f24 = _sub1._vector._z;
+ f25 = _sub1._vector._x;
+ f26 = _sub1._vector._z;
+ f27 = _sub1._vector._x;
+
+ f28 = _sub1._vector._y;
+ _sub2._vector._x = sub6->_row1._x * _sub1._vector._x
+ + sub6->_row3._x * _sub1._vector._z
+ + sub6->_row2._x * f28
+ + sub6->_vector._x;
+ _sub2._vector._y = f23 * sub6->_row2._y
+ + f24 * sub6->_row3._y
+ + f25 * sub6->_row1._y
+ + sub6->_vector._y;
+ _sub2._vector._z = f26 * sub6->_row3._z
+ + f27 * sub6->_row1._z
+ + f28 * sub6->_row2._z
+ + sub6->_vector._z;
+
+ size2 = (int)_array[1]._data2.size();
+ size1 = (int)_array[1]._data1.size();
+
+ if (size2 > 0) {
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ FVector &currVector = _array[1]._data2[ctr2];
+ GridEntry &gridEntry = _grid[ctr2];
+
+ f34 = currVector._x;
+ f35 = currVector._y;
+ f36 = f35 * _sub2._row2._x;
+ f37 = currVector._z;
+ f38 = f37 * _sub2._row3._x + f36;
+ f39 = f38 + f34 * _sub2._row1._x;
+ f40 = f39 + _sub2._vector._x;
+
+ gridEntry._x = f40;
+ gridEntry._y = f37 * _sub2._row3._y
+ + f35 * _sub2._row2._y
+ + f34 * _sub2._row1._y
+ + _sub2._vector._y;
+ gridEntry._z = f37 * _sub2._row3._z
+ + f35 * _sub2._row2._z
+ + f34 * _sub2._row1._z
+ + _sub2._vector._z;
+ }
+ }
+
+ if (val2 <= 0) {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = MKTAG_BE(entryP->_pixel1, entryP->_pixel2,
+ entryP->_pixel3, 0);
+ surfaceArea->setColorFromPixel();
+
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ GridEntry &gridEntry = _grid[ctr2];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
+ Data1 &d1 = _array[1]._data1[ctr2];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid1._z > val1 && grid2._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ } else {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = entryP->_pixel1;
+ surfaceArea->setColorFromPixel();
+
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ GridEntry &gridEntry = _grid[ctr2];
+ sub12->proc28(0, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
+ Data1 &d1 = _array[1]._data1[ctr2];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid1._z > val1 && grid2._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+
+ surfaceArea->_pixel = entryP->_pixel3;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(SA_MODE2);
+
+ for (int ctr2 = 0; ctr2 < size2; ++ctr2) {
+ GridEntry &gridEntry = _grid[ctr2];
+ sub12->proc28(1, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (int ctr2 = 0; ctr2 < size1; ++ctr2) {
+ Data1 &d1 = _array[1]._data1[ctr2];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid1._z > val1 && grid2._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ }
+ }
+ }
+
+ uint pixel1 = 0x81EEF5, pixel2 = 0xF5, pixel3 = 0x810000;
+ int arrIndex = 0;
+
+ if (v3 >= 200000000.0) {
+ if (v3 >= 900000000.0) {
+ if (v3 >= 6000000000.0) {
+ arrIndex = 3;
+ if (v3 >= 1.0e10)
+ arrIndex = 4;
+ } else {
+ arrIndex = 2;
+ }
+ } else {
+ arrIndex = 1;
}
+ } else {
+ arrIndex = 0;
}
- // TODO
+ SubEntry &entry = _array[arrIndex];
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ const FVector &d2v = entry._data2[ctr];
+ FVector newV = d2v + *vector;
+
+ f41 = sub6->_row1._x;
+ f42 = sub6->_row3._x;
+ f43 = sub6->_row2._x;
+ f44 = f43 * newV._y;
+ f45 = f41 * newV._x + f42 * newV._z + f44;
+ f46 = f45 + sub6->_vector._x;
+
+ gridEntry._x = f46;
+ gridEntry._y = newV._y * sub6->_row2._y
+ + newV._z * sub6->_row3._y
+ + newV._x * sub6->_row1._y
+ + sub6->_vector._y;
+ gridEntry._z = newV._z * sub6->_row3._z
+ + newV._y * sub6->_row2._z
+ + newV._x * sub6->_row1._z
+ + sub6->_vector._z;
+ }
+
+ if (val2 <= 0) {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = pixel1;
+ surfaceArea->setColorFromPixel();
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
+ Data1 &d1 = entry._data1[ctr];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid2._z > val1 && grid1._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ } else {
+ surfaceArea->setMode(SA_NONE);
+ surfaceArea->_pixel = pixel2;
+ surfaceArea->setColorFromPixel();
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
+ Data1 &d1 = entry._data1[ctr];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid2._z > val1 && grid1._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+
+ surfaceArea->_pixel = pixel3;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(SA_MODE2);
+
+ for (uint ctr = 0; ctr < entry._data2.size(); ++ctr) {
+ GridEntry &gridEntry = _grid[ctr];
+ sub12->proc28(2, gridEntry, tempV);
+ gridEntry._position._x = tempV._x + v1;
+ gridEntry._position._y = tempV._y + v2;
+ }
+
+ for (uint ctr = 0; ctr < entry._data1.size(); ++ctr) {
+ Data1 &d1 = entry._data1[ctr];
+ GridEntry &grid1 = _grid[d1._index1];
+ GridEntry &grid2 = _grid[d1._index2];
+
+ if (grid2._z > val1 && grid1._z > val1) {
+ surfaceArea->fn1(FRect(grid1._position._x, grid1._position._y,
+ grid2._position._x, grid2._position._y));
+ }
+ }
+ }
}
void CStarControlSub5::proc3(CErrorCode *errorCode) {
@@ -259,40 +506,85 @@ void CStarControlSub5::fn1() {
}
bool CStarControlSub5::setupEntry(int width, int height, int index, double val) {
- /*
if (width < 2 || height < 3)
return false;
SubEntry &entry = _array[index];
entry.clear();
- int height2 = height - 2;
- int height1 = height - 1;
- entry._data1.resize((2 * height - 3) * width);
- entry._data2.resize(width * height2 + 2);
- entry._data2[0] = FVector(0.0, val, 0.0);
+ const double FACTOR = 2 * M_PI / 360.0;
+ int d1Count, d2Count, size3, height1;
+ int ctr, ctr2, idx, offset, f11;
+ double vx, vy, f5, f6, f7, f8, f9, f10;
+
+ d1Count = width * (2 * height - 3);
+ d2Count = (height - 2) * width + 2;
+ entry._data1.resize(d1Count);
+ entry._data2.resize(d2Count);
+
+ height1 = height - 1;
+ entry._data2[0]._y = val;
+
+ vy = 180.0 / (double)height1;
+ vx = 360.0 / (double)width;
+
+ for (ctr = height - 2, idx = 0; ctr > 0; --ctr, vy *= 2) {
+ f5 = 0.0;
+ f6 = cos(vy * FACTOR);
+ f7 = sin(vy * FACTOR);
- index = 1;
- double vy = 180.0 / (double)height1;
- double vx = 360.0 / (double)width;
- const double FACTOR = 3.1415927 * 0.0055555557;
+ if (width > 0) {
+ f8 = f6 * val;
- if (height1 > 1) {
- double yAmount = vy;
- int width12 = width * 12;
- for (int yCtr = height1 - 1; yCtr > 0; --yCtr, yAmount += vy) {
- double sineVal = sin(yAmount * FACTOR);
+ for (int xp = width; xp > 0; --xp, ++idx, f5 += vx) {
+ f9 = f5 * FACTOR;
+ f10 = cos(f9) * f7 * val;
+ FVector &tempV = entry._data2[idx];
+ tempV._x = sin(f9) * f7 * val;
+ tempV._y = f8;
+ tempV._z = f10;
+ }
+ }
+ }
+ entry._data2[idx] = FVector(0.0, -1.0, 0.0);
+
+ size3 = width * (height - 3) + 1;
+ offset = 0;
+ Data1 *data1P = &entry._data1[0];
+ for (ctr = 0; ctr < width; ++ctr, ++size3) {
+ data1P->_index1 = 0;
+ data1P->_index2 = size3 - width * (height - 3);
+ ++data1P;
+
+ data1P->_index1 = d2Count - 1;
+ data1P->_index2 = size3;
+ ++data1P;
+ }
- | 0.0 * FACTOR |
- | cos(yAmount * FACTOR) * val |
- | 0.0 |
- |yAmount|
+ f11 = 1;
+ for (ctr = 1; ctr < height1; ++ctr, f11 += width) {
+ data1P = &entry._data1[offset];
+
+ for (ctr2 = 0; ctr2 < width; ++ctr2) {
+ data1P->_index1 = ctr2 + f11;
+ if (ctr2 == width - 1)
+ data1P->_index2 = f11;
+ else
+ data1P->_index2 = ctr2 + f11 + 1;
+
+ ++offset;
+ ++data1P;
+
+ if (ctr < height - 2) {
+ data1P->_index1 = ctr2 + f11;
+ ++offset;
+ data1P->_index2 = width + ctr2 + f11;
+ ++data1P;
+ }
}
}
- // TODO
- */
return true;
}
diff --git a/engines/titanic/star_control/star_control_sub5.h b/engines/titanic/star_control/star_control_sub5.h
index 32094f5227..b5e5bb1b6a 100644
--- a/engines/titanic/star_control/star_control_sub5.h
+++ b/engines/titanic/star_control/star_control_sub5.h
@@ -33,8 +33,14 @@ namespace Titanic {
class CStarControlSub12;
class CStarControlSub5 {
+ struct Data1 {
+ int _index1;
+ int _index2;
+ Data1() : _index1(0), _index2(0) {}
+ };
+
struct SubEntry {
- Common::Array<FPoint> _data1;
+ Common::Array<Data1> _data1;
Common::Array<FVector> _data2;
~SubEntry() { clear(); }
@@ -46,28 +52,23 @@ class CStarControlSub5 {
struct Entry {
int _field0;
- byte _field4;
- byte _field5;
- byte _field6;
+ byte _pixel1;
+ byte _pixel2;
+ byte _pixel3;
int _field8;
int _fieldC;
double _field10;
double _field14;
- Entry() : _field0(0), _field4(0), _field5(0), _field6(0), _field8(0),
+ Entry() : _field0(0), _pixel1(0), _pixel2(0), _pixel3(0), _field8(0),
_fieldC(0), _field10(0), _field14(0) {}
};
- struct GridEntry {
- int _field0;
- int _field4;
- int _field8;
- int _fieldC;
- int _field10;
+ struct GridEntry : public FVector {
+ FPoint _position;
int _field14;
- GridEntry() : _field0(0), _field4(0), _field8(0), _fieldC(0),
- _field10(0), _field14(0) {}
+ GridEntry() : FVector(), _field14(0) {}
};
/**
diff --git a/engines/titanic/star_control/star_control_sub6.cpp b/engines/titanic/star_control/star_control_sub6.cpp
index 27e2a491f8..0ced3df9fe 100644
--- a/engines/titanic/star_control/star_control_sub6.cpp
+++ b/engines/titanic/star_control/star_control_sub6.cpp
@@ -30,14 +30,56 @@ CStarControlSub6::CStarControlSub6() {
clear();
}
-CStarControlSub6::CStarControlSub6(int mode, double val) {
- set(mode, val);
+CStarControlSub6::CStarControlSub6(Axis axis, double amount) {
+ setRotationMatrix(axis, amount);
}
CStarControlSub6::CStarControlSub6(const CStarControlSub6 *src) {
copyFrom(src);
}
+CStarControlSub6::CStarControlSub6(const CStarControlSub6 *s1, const CStarControlSub6 *s2) {
+ _row1._x = s2->_row1._x * s1->_row1._x
+ + s1->_row1._z * s2->_row3._x
+ + s1->_row1._y * s2->_row2._x;
+ _row1._y = s1->_row1._x * s2->_row1._y
+ + s2->_row3._y * s1->_row1._z
+ + s2->_row2._y * s1->_row1._y;
+ _row1._z = s1->_row1._x * s2->_row1._z
+ + s2->_row3._z * s1->_row1._z
+ + s2->_row2._z * s1->_row1._y;
+ _row2._x = s2->_row1._x * s1->_row2._x
+ + s1->_row2._y * s2->_row2._x
+ + s1->_row2._z * s2->_row3._x;
+ _row2._y = s1->_row2._y * s2->_row2._y
+ + s1->_row2._z * s2->_row3._y
+ + s2->_row1._y * s1->_row2._x;
+ _row2._z = s2->_row1._z * s1->_row2._x
+ + s1->_row2._y * s2->_row2._z
+ + s1->_row2._z * s2->_row3._z;
+ _row3._x = s2->_row1._x * s1->_row3._x
+ + s1->_row3._y * s2->_row2._x
+ + s1->_row3._z * s2->_row3._x;
+ _row3._y = s1->_row3._z * s2->_row3._y
+ + s1->_row3._y * s2->_row2._y
+ + s2->_row1._y * s1->_row3._x;
+ _row3._z = s2->_row3._z * s1->_row3._z
+ + s2->_row2._z * s1->_row3._y
+ + s2->_row1._z * s1->_row3._x;
+ _vector._x = s2->_row1._x * s1->_vector._x
+ + s1->_vector._y * s2->_row2._x
+ + s1->_vector._z * s2->_row3._x
+ + s2->_vector._x;
+ _vector._y = s1->_vector._z * s2->_row3._y
+ + s1->_vector._y * s2->_row2._y
+ + s1->_vector._x * s2->_row1._y
+ + s2->_vector._y;
+ _vector._z = s1->_vector._y * s2->_row2._z
+ + s1->_vector._z * s2->_row3._z
+ + s1->_vector._x * s2->_row1._z
+ + s2->_vector._z;
+}
+
void CStarControlSub6::init() {
_static = nullptr;
}
@@ -47,18 +89,18 @@ void CStarControlSub6::deinit() {
_static = nullptr;
}
-void CStarControlSub6::clear() {
- FMatrix::clear();
+void CStarControlSub6::identity() {
+ FMatrix::identity();
_vector.clear();
}
-void CStarControlSub6::set(int mode, double amount) {
- const double ROTATION = 3.1415927 * 0.0055555557;
+void CStarControlSub6::setRotationMatrix(Axis axis, double amount) {
+ const double ROTATION = 2 * M_PI / 360.0;
double sinVal = sin(amount * ROTATION);
double cosVal = cos(amount * ROTATION);
- switch (mode) {
- case 0:
+ switch (axis) {
+ case X_AXIS:
_row1._x = 1.0;
_row1._y = 0.0;
_row1._z = 0.0;
@@ -70,7 +112,7 @@ void CStarControlSub6::set(int mode, double amount) {
_row3._z = cosVal;
break;
- case 1:
+ case Y_AXIS:
_row1._x = cosVal;
_row1._y = 0.0;
_row1._z = sinVal;
@@ -82,7 +124,7 @@ void CStarControlSub6::set(int mode, double amount) {
_row3._z = sinVal;
break;
- case 2:
+ case Z_AXIS:
_row1._x = cosVal;
_row1._y = sinVal;
_row1._z = 0.0;
@@ -108,52 +150,73 @@ void CStarControlSub6::copyFrom(const CStarControlSub6 *src) {
_vector = src->_vector;
}
-void CStarControlSub6::setup(CStarControlSub6 *dest, const CStarControlSub6 *s2, const CStarControlSub6 *s3) {
- CStarControlSub6 &d = *dest;
-
- d._row1._x = s3->_row1._x * s2->_row1._x
- + s2->_row1._z * s3->_row3._x
- + s2->_row1._y * s3->_row2._x;
- d._row1._y = s2->_row1._x * s3->_row1._y
- + s3->_row3._y * s2->_row1._z
- + s3->_row2._y * s2->_row1._y;
- d._row1._z = s2->_row1._x * s3->_row1._z
- + s3->_row3._z * s2->_row1._z
- + s3->_row2._z * s2->_row1._y;
- d._row2._x = s3->_row1._x * s2->_row2._x
- + s2->_row2._y * s3->_row2._x
- + s2->_row2._z * s3->_row3._x;
- d._row2._y = s2->_row2._y * s3->_row2._y
- + s2->_row2._z * s3->_row3._y
- + s3->_row1._y * s2->_row2._x;
- d._row2._z = s3->_row1._z * s2->_row2._x
- + s2->_row2._y * s3->_row2._z
- + s2->_row2._z * s3->_row3._z;
- d._row3._x = s3->_row1._x * s2->_row3._x
- + s2->_row3._y * s3->_row2._x
- + s2->_row3._z * s3->_row3._x;
- d._row3._y = s2->_row3._z * s3->_row3._y
- + s2->_row3._y * s3->_row2._y
- + s3->_row1._y * s2->_row3._x;
- d._row3._z = s3->_row3._z * s2->_row3._z
- + s3->_row2._z * s2->_row3._y
- + s3->_row1._z * s2->_row3._x;
- d._vector._x = s3->_row1._x * s2->_vector._x
- + s2->_vector._y * s3->_row2._x
- + s2->_vector._z * s3->_row3._x
- + s3->_vector._x;
- d._vector._y = s2->_vector._z * s3->_row3._y
- + s2->_vector._y * s3->_row2._y
- + s2->_vector._x * s3->_row1._y
- + s3->_vector._y;
- d._vector._z = s2->_vector._y * s3->_row2._z
- + s2->_vector._z * s3->_row3._z
- + s2->_vector._x * s3->_row1._z
- + s3->_vector._z;
+void CStarControlSub6::copyFrom(const FMatrix &src) {
+ _row1 = src._row1;
+ _row2 = src._row2;
+ _row3 = src._row3;
}
-void CStarControlSub6::fn1(CStarControlSub6 *sub6) {
- // TODO
+void CStarControlSub6::fn4(CStarControlSub6 *sub6) {
+ double v2, v3, v6, v7, v8, v9, v10, v11;
+ double v12, v13, v14, v15, v16, v17, v18;
+
+ v16 = _row3._z * _row2._y;
+ v2 = _row1._x * v16;
+ v3 = 0.0;
+ v18 = v2;
+ if (v2 < 0.0) {
+ v3 = v18;
+ v2 = 0.0;
+ }
+ v6 = _row3._x * _row1._y * _row2._z;
+ if (v6 < 0.0)
+ v3 = v3 + v6;
+ else
+ v2 = v2 + v6;
+ v7 = _row3._y * _row1._z * _row2._x;
+ if (v7 < 0.0)
+ v3 = v3 + v7;
+ else
+ v2 = v2 + v7;
+ if (-(_row3._x * _row1._z * _row2._y) < 0.0)
+ v3 = v3 - _row3._x * _row1._z * _row2._y;
+ else
+ v2 = v2 - _row3._x * _row1._z * _row2._y;
+ if (-(_row1._y * _row2._x * _row3._z) < 0.0)
+ v3 = v3 - _row1._y * _row2._x * _row3._z;
+ else
+ v2 = v2 - _row1._y * _row2._x * _row3._z;
+ v17 = _row2._z * _row3._y;
+ if (-(_row1._x * v17) < 0.0)
+ v3 = v3 - _row1._x * v17;
+ else
+ v2 = v2 - _row1._x * v17;
+ v18 = v3 + v2;
+ assert(!(v18 == 0.0 || fabs(v18 / (v2 - v3)) < 1.0e-10));
+
+ v8 = 1.0 / v18;
+ v18 = v8;
+ sub6->_row1._x = (v16 - v17) * v8;
+ sub6->_row2._x = -(_row2._x * _row3._z - _row3._x * _row2._z) * v8;
+ sub6->_row3._x = (_row3._y * _row2._x - _row3._x * _row2._y) * v8;
+ sub6->_row1._y = -(_row1._y * _row3._z - _row3._y * _row1._z) * v8;
+ sub6->_row2._y = (_row1._x * _row3._z - _row3._x * _row1._z) * v8;
+ sub6->_row3._y = -(_row1._x * _row3._y - _row3._x * _row1._y) * v8;
+ sub6->_row1._z = (_row1._y * _row2._z - _row1._z * _row2._y) * v8;
+ sub6->_row2._z = -(_row1._x * _row2._z - _row1._z * _row2._x) * v8;
+ v9 = sub6->_row1._x;
+ v10 = sub6->_row2._y;
+ v11 = sub6->_row3._y;
+ v12 = sub6->_row1._z;
+ v13 = sub6->_row2._z;
+ sub6->_row3._z = (_row1._x * _row2._y - _row1._y * _row2._x) * v18;
+ v14 = v9;
+ v15 = sub6->_row3._z;
+ sub6->_vector._x = -(v14 * _vector._x
+ + _vector._y * sub6->_row2._x
+ + _vector._z * sub6->_row3._x);
+ sub6->_vector._y = -(_vector._x * sub6->_row1._y + v10 * _vector._y + v11 * _vector._z);
+ sub6->_vector._z = -(v12 * _vector._x + v13 * _vector._y + v15 * _vector._z);
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub6.h b/engines/titanic/star_control/star_control_sub6.h
index 16304b8540..91def29973 100644
--- a/engines/titanic/star_control/star_control_sub6.h
+++ b/engines/titanic/star_control/star_control_sub6.h
@@ -37,27 +37,28 @@ public:
FVector _vector;
public:
CStarControlSub6();
- CStarControlSub6(int mode, double amount);
+ CStarControlSub6(Axis axis, double amount);
CStarControlSub6(const CStarControlSub6 *src);
+ CStarControlSub6(const CStarControlSub6 *s1, const CStarControlSub6 *s2);
/**
- * Clear the item
+ * Sets an identity matrix
*/
- void clear();
+ void identity();
/**
- * Sets up a passed instance from the specified two other ones
+ * Sets a rotation matrix for the given axis for the given amount
*/
- static void setup(CStarControlSub6 *dest, const CStarControlSub6 *s2, const CStarControlSub6 *s3);
+ void setRotationMatrix(Axis axis, double val);
+
+ void copyFrom(const CStarControlSub6 *src);
/**
- * Sets the default data
+ * Copy from the specified matrix
*/
- void set(int mode, double val);
-
- void copyFrom(const CStarControlSub6 *src);
+ void copyFrom(const FMatrix &src);
- void fn1(CStarControlSub6 *sub6);
+ void fn4(CStarControlSub6 *sub6);
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub7.cpp b/engines/titanic/star_control/star_control_sub7.cpp
index 4b694810ad..8386e7305f 100644
--- a/engines/titanic/star_control/star_control_sub7.cpp
+++ b/engines/titanic/star_control/star_control_sub7.cpp
@@ -21,18 +21,62 @@
*/
#include "titanic/star_control/star_control_sub7.h"
+#include "titanic/star_control/star_control_sub12.h"
namespace Titanic {
void CStarControlSub7::draw(CSurfaceArea *surfaceArea, CStarControlSub12 *sub12, CStarControlSub5 *sub5) {
- // TODO
+ if (_data.empty())
+ return;
+
+ CStarControlSub6 sub6 = sub12->proc23();
+ double threshold = sub12->proc25();
+ FPoint center((double)surfaceArea->_width * 0.5,
+ surfaceArea->_height * 0.5);
+ FVector newV;
+
+ uint savedPixel = surfaceArea->_pixel;
+ surfaceArea->_pixel = 0xffff;
+ surfaceArea->setColorFromPixel();
+
+ for (uint idx = 0; idx < _data.size(); ++idx) {
+ const CBaseStarEntry &star = _data[idx];
+
+ newV._x = sub6._row1._x * star._position._x + sub6._row3._x * star._position._z
+ + sub6._row2._x * star._position._y + sub6._vector._x;
+ newV._y = sub6._row1._y * star._position._x + sub6._row3._y * star._position._z
+ + sub6._row2._y * star._position._x + sub6._vector._y;
+ newV._z = sub6._row1._z * star._position._x + sub6._row3._z * star._position._z
+ + sub6._row2._z * star._position._y + sub6._vector._z;
+
+ if (newV._z > threshold) {
+ FVector vTemp;
+ sub12->proc28(2, newV, vTemp);
+
+ FRect r1(center._x + vTemp._x, center._y + vTemp._y,
+ center._x + vTemp._x + 4.0, center._y + vTemp._y + 4.0);
+ surfaceArea->fn1(r1);
+
+ FRect r2(r1.right, r1.bottom, r1.right + 4.0, r1.top);
+ surfaceArea->fn1(r2);
+
+ FRect r3(r2.right, r1.top, r1.right, r1.top - 4.0);
+ surfaceArea->fn1(r3);
+
+ FRect r4(r1.right, r1.top - 4.0, r1.left, r1.top);
+ surfaceArea->fn1(r4);
+ }
+ }
+
+ surfaceArea->_pixel = savedPixel;
+ surfaceArea->setColorFromPixel();
}
bool CStarControlSub7::addStar(const CBaseStarEntry *entry) {
// iterate through the existing stars
for (uint idx = 0; idx < _data.size(); ++idx) {
CBaseStarEntry &star = _data[idx];
- if (star._position == entry->_position) {
+ if (star == *entry) {
// Found a matching star at the exact same position, so remove it instead
_data.remove_at(idx);
return true;
diff --git a/engines/titanic/star_control/star_control_sub8.cpp b/engines/titanic/star_control/star_control_sub8.cpp
index 50c90d2bc1..bf29b053c5 100644
--- a/engines/titanic/star_control/star_control_sub8.cpp
+++ b/engines/titanic/star_control/star_control_sub8.cpp
@@ -24,36 +24,102 @@
#include "titanic/star_control/star_control_sub7.h"
#include "titanic/star_control/star_control_sub12.h"
#include "titanic/star_control/star_field.h"
+#include "titanic/star_control/star_ref.h"
namespace Titanic {
-CStarControlSub8::CStarControlSub8() : _field8(-1), _fieldC(-1) {
-#if 0
- _field4(0), _field8(-1)
-#endif
-}
-
-bool MouseButtonDown(const Common::Point &pt) {
- // TODO
- return true;
-}
-
-int CStarControlSub8::findStar(const Common::Point &pt) {
- // TODO
- return -1;
+CStarControlSub8::CStarControlSub8() : _field8(-1), _entryIndex(-1) {
}
void CStarControlSub8::selectStar(int index, CVideoSurface *surface,
CStarField *starField, CStarControlSub7 *sub7) {
- // TODO
+ if (_entryIndex >= 0) {
+ if (_entryIndex == _field8) {
+ if (_field8 != 2) {
+ if (_positions[index] != _positions[_entryIndex + 1]) {
+ surface->lock();
+
+ CSurfaceArea surfaceArea(surface);
+ fn4(index, &surfaceArea);
+ surface->unlock();
+
+ ++_entryIndex;
+ CStarPosition &newP = _positions[_entryIndex + 1];
+ newP = _positions[index];
+
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+ }
+ }
+ } else if (_entryIndex == _field8 + 1) {
+ if (_positions[index] == _positions[_entryIndex + 1]) {
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn6(&surfaceArea);
+ surface->unlock();
+
+ --_entryIndex;
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+ } else {
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn6(&surfaceArea);
+ fn4(index, &surfaceArea);
+ surface->unlock();
+
+ const CBaseStarEntry *starP;
+ starP = starField->getDataPtr(_positions[_entryIndex]._index1);
+ sub7->addStar(starP);
+ starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+
+ CStarPosition &newP = _positions[_entryIndex + 1];
+ newP = _positions[index];
+ }
+ }
+ } else {
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn4(index, &surfaceArea);
+ surface->unlock();
+
+ ++_entryIndex;
+ CStarPosition &newP = _positions[_entryIndex + 1];
+ newP = _positions[index];
+
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index]._index1);
+ sub7->addStar(starP);
+ }
}
-void CStarControlSub8::fn1(CStarField *starField, CSurfaceArea *surfaceArea, CStarControlSub12 *sub12) {
- // TODO
+bool CStarControlSub8::fn1(CStarField *starField, CSurfaceArea *surfaceArea, CStarControlSub12 *sub12) {
+ int count = starField->baseFn2(surfaceArea, sub12);
+
+ if (count > 0) {
+ allocate(count);
+ CStarRef2 starRef(starField, &_positions);
+ starRef.process(surfaceArea, sub12);
+ return true;
+ } else {
+ clear();
+ return false;
+ }
}
void CStarControlSub8::fn2(CVideoSurface *surface, CStarField *starField, CStarControlSub7 *sub7) {
- // TODO
+ if (_field8 <= -1) {
+ if (_entryIndex > -1) {
+ fn5(_entryIndex, surface, starField, sub7);
+ --_entryIndex;
+ }
+ } else {
+ --_field8;
+ if (_entryIndex - _field8 > 1) {
+ fn5(_entryIndex, surface, starField, sub7);
+ --_entryIndex;
+ }
+ }
}
void CStarControlSub8::fn3() {
@@ -62,15 +128,97 @@ void CStarControlSub8::fn3() {
}
FPoint CStarControlSub8::getPosition() const {
- return (_fieldC >= 0 && _fieldC <= 2) ? _data[_fieldC]._position : FPoint();
+ return (_entryIndex >= 0 && _entryIndex <= 2) ?
+ FPoint(_entries[_entryIndex]) : FPoint();
}
void CStarControlSub8::draw(CSurfaceArea *surfaceArea) {
- // TODO
+ if (!_positions.empty()) {
+ uint savedPixel = surfaceArea->_pixel;
+ surfaceArea->_pixel = 0xff;
+ surfaceArea->setColorFromPixel();
+ SurfaceAreaMode savedMode = surfaceArea->setMode(SA_NONE);
+
+ for (int idx = 0; idx < _entryIndex; ++idx) {
+ const CStarPosition &src = _entries[idx];
+ double xp = src.x, yp = src.y;
+
+ surfaceArea->fn1(FRect(xp - 8.0, yp, xp - 4.0, yp));
+ surfaceArea->fn1(FRect(xp + 4.0, yp, xp + 8.0, yp));
+ surfaceArea->fn1(FRect(xp, yp - 8.0, xp, yp - 4.0));
+ surfaceArea->fn1(FRect(xp, yp + 4.0, xp, yp + 8.0));
+ }
+
+ surfaceArea->_pixel = savedPixel;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(savedMode);
+ }
+}
+
+void CStarControlSub8::allocate(int count) {
+ if (!_positions.empty()) {
+ if ((int)_positions.size() == count)
+ return;
+
+ clear();
+ }
+
+ _positions.resize(count);
}
void CStarControlSub8::clear() {
- // TODO
+ _positions.clear();
+ _field8 = _entryIndex = -1;
+}
+
+int CStarControlSub8::indexOf(const Common::Point &pt) const {
+ Common::Rect r(pt.x - 2, pt.y - 2, pt.x + 2, pt.y + 2);
+
+ for (int idx = 0; idx < (int)_positions.size(); ++idx) {
+ if (r.contains(_positions[idx]))
+ return idx;
+ }
+
+ return -1;
+}
+
+void CStarControlSub8::fn4(int index, CSurfaceArea *surfaceArea) {
+ if (index >= 0 && index < (int)_positions.size()) {
+ const CStarPosition &pt = _positions[index];
+ fn7(pt, surfaceArea);
+ }
+}
+
+void CStarControlSub8::fn5(int index, CVideoSurface *surface, CStarField *starField, CStarControlSub7 *sub7) {
+ surface->lock();
+ CSurfaceArea surfaceArea(surface);
+ fn7(_positions[index + 1], &surfaceArea);
+ surface->unlock();
+
+ const CBaseStarEntry *starP = starField->getDataPtr(_positions[index + 1]._index1);
+ sub7->addStar(starP);
+}
+
+void CStarControlSub8::fn6(CSurfaceArea *surfaceArea) {
+ const CStarPosition &pt = _positions[_entryIndex];
+ fn7(pt, surfaceArea);
+}
+
+void CStarControlSub8::fn7(const FPoint &pt, CSurfaceArea *surfaceArea) {
+ uint savedPixel = surfaceArea->_pixel;
+ surfaceArea->_pixel = 255;
+ surfaceArea->setColorFromPixel();
+ SurfaceAreaMode savedMode = surfaceArea->setMode(SA_MODE3);
+
+
+ surfaceArea->fn1(FRect(pt._x - 8.0, pt._y, pt._x - 4.0, pt._y));
+ surfaceArea->fn1(FRect(pt._x - -4.0, pt._y, pt._x + 8.0, pt._y));
+ surfaceArea->fn1(FRect(pt._x, pt._y - 8.0, pt._x, pt._y - 4.0));
+ surfaceArea->fn1(FRect(pt._x, pt._y + 4.0, pt._x, pt._y + 8.0));
+
+ surfaceArea->_pixel = savedPixel;
+ surfaceArea->setColorFromPixel();
+ surfaceArea->setMode(savedMode);
}
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_control_sub8.h b/engines/titanic/star_control/star_control_sub8.h
index f7f8ba4fb5..4939179481 100644
--- a/engines/titanic/star_control/star_control_sub8.h
+++ b/engines/titanic/star_control/star_control_sub8.h
@@ -23,6 +23,9 @@
#ifndef TITANIC_STAR_CONTROL_SUB8_H
#define TITANIC_STAR_CONTROL_SUB8_H
+#include "common/array.h"
+#include "common/rect.h"
+#include "titanic/star_control/base_star.h"
#include "titanic/star_control/surface_area.h"
#include "titanic/star_control/fpoint.h"
#include "titanic/support/simple_file.h"
@@ -35,19 +38,20 @@ class CStarControlSub7;
class CStarControlSub12;
class CStarControlSub8 {
- struct StructEntry {
- FPoint _position;
- int _field8;
- int _fieldC;
-
- StructEntry() : _field8(0), _fieldC(0) {}
- };
private:
-#if 0
- int _field0;
- int _field4;
-#endif
- StructEntry _data[3];
+ Common::Array<CStarPosition> _positions;
+ int _entryIndex;
+ CStarPosition _entries[3];
+private:
+ /**
+ * Allocates space in the _rects array
+ */
+ void allocate(int count);
+
+ /**
+ * Clears any current data
+ */
+ void clear();
public:
int _field8;
int _fieldC;
@@ -65,19 +69,24 @@ public:
*/
void save(SimpleFile *file, int indent) {}
- int findStar(const Common::Point &pt);
-
void selectStar(int starNum, CVideoSurface *surface, CStarField *starField,
CStarControlSub7 *sub7);
void draw(CSurfaceArea *surfaceArea);
- void fn1(CStarField *starField, CSurfaceArea *surfaceArea, CStarControlSub12 *sub12);
+ bool fn1(CStarField *starField, CSurfaceArea *surfaceArea, CStarControlSub12 *sub12);
void fn2(CVideoSurface *surface, CStarField *starField, CStarControlSub7 *sub7);
void fn3();
+ void fn4(int index, CSurfaceArea *surfaceArea);
+ void fn5(int index, CVideoSurface *surface, CStarField *starField, CStarControlSub7 *sub7);
+ void fn6(CSurfaceArea *surfaceArea);
+ void fn7(const FPoint &pt, CSurfaceArea *surfaceArea);
FPoint getPosition() const;
- void clear();
+ /**
+ * Returns the index of an entry in the rects list a given point falls within
+ */
+ int indexOf(const Common::Point &pt) const;
};
} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_field.cpp b/engines/titanic/star_control/star_field.cpp
index 3a09be3e8a..5c22e5e308 100644
--- a/engines/titanic/star_control/star_field.cpp
+++ b/engines/titanic/star_control/star_field.cpp
@@ -230,9 +230,9 @@ bool CStarField::mouseButtonDown(CVideoSurface *surface, CStarControlSub12 *sub1
int flags, const Common::Point &pt) {
if (_mode == MODE_STARFIELD) {
CSurfaceArea surfaceArea(surface);
- return selectStar(&surfaceArea, sub12, 0, pt);
+ return selectStar(&surfaceArea, sub12, pt);
} else {
- int starNum = _sub8.findStar(pt);
+ int starNum = _sub8.indexOf(pt);
if (starNum >= 0) {
_sub8.selectStar(starNum, surface, this, &_sub7);
return true;
diff --git a/engines/titanic/star_control/star_points1.cpp b/engines/titanic/star_control/star_points1.cpp
index c72795f11d..ab5da111ac 100644
--- a/engines/titanic/star_control/star_points1.cpp
+++ b/engines/titanic/star_control/star_points1.cpp
@@ -27,7 +27,7 @@
namespace Titanic {
#define ARRAY_COUNT 876
-const double FACTOR = 3.1415927 * 0.0055555557;
+const double FACTOR = 2 * M_PI / 360.0;
CStarPoints1::CStarPoints1() {
}
diff --git a/engines/titanic/star_control/star_points2.cpp b/engines/titanic/star_control/star_points2.cpp
index 9c4cfe8cf5..7a3e873e90 100644
--- a/engines/titanic/star_control/star_points2.cpp
+++ b/engines/titanic/star_control/star_points2.cpp
@@ -27,7 +27,7 @@
namespace Titanic {
#define ARRAY_COUNT 80
-const double FACTOR = 3.1415927 * 0.0055555557;
+const double FACTOR = 2 * M_PI / 360.0;
bool CStarPoints2::initialize() {
// Get a reference to the starfield points resource
@@ -47,7 +47,7 @@ bool CStarPoints2::initialize() {
v1 = stream->readSint32LE();
v2 = stream->readSint32LE();
v1 *= 0.015 * FACTOR;
- v2 *= 0.0099999998 * FACTOR;
+ v2 *= FACTOR / 100.0;
entry._x = cos(v1) * 3000000.0 * cos(v2);
entry._y = sin(v1) * 3000000.0 * cos(v2);
diff --git a/engines/titanic/star_control/star_ref.cpp b/engines/titanic/star_control/star_ref.cpp
new file mode 100644
index 0000000000..7f36ae7473
--- /dev/null
+++ b/engines/titanic/star_control/star_ref.cpp
@@ -0,0 +1,63 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "titanic/star_control/star_ref.h"
+
+namespace Titanic {
+
+void CBaseStarRef::process(CSurfaceArea *surface, CStarControlSub12 *sub12) {
+ // TODO
+}
+
+/*------------------------------------------------------------------------*/
+
+bool CStarRef1::check(const Common::Point &pt, int index) {
+ Common::Rect r(pt.x - 2, pt.y - 2, pt.x + 2, pt.y + 2);
+ if (r.contains(_position)) {
+ _index = index;
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/*------------------------------------------------------------------------*/
+
+bool CStarRef2::check(const Common::Point &pt, int index) {
+ if (_index >= (int)_positions->size())
+ return false;
+
+ CStarPosition &sp = (*_positions)[index];
+ sp.x = pt.x;
+ sp.y = pt.y;
+ sp._index1 = sp._index2 = index;
+ return true;
+}
+
+/*------------------------------------------------------------------------*/
+
+bool CStarRef3::check(const Common::Point &pt, int index) {
+ ++_index;
+ return true;
+}
+
+} // End of namespace Titanic
diff --git a/engines/titanic/star_control/star_ref.h b/engines/titanic/star_control/star_ref.h
new file mode 100644
index 0000000000..c6fec90fbc
--- /dev/null
+++ b/engines/titanic/star_control/star_ref.h
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/rect.h"
+#include "titanic/star_control/base_star.h"
+#include "titanic/star_control/star_control_sub12.h"
+#include "titanic/star_control/surface_area.h"
+
+#ifndef TITANIC_STAR_REF_H
+#define TITANIC_STAR_REF_H
+
+namespace Titanic {
+
+class CBaseStarRef {
+protected:
+ CBaseStar *_star;
+public:
+ CBaseStarRef(CBaseStar *star) : _star(star) {}
+ CBaseStarRef() : _star(nullptr) {}
+ virtual ~CBaseStarRef() {}
+
+ void process(CSurfaceArea *surface, CStarControlSub12 *sub12);
+
+ virtual bool check(const Common::Point &pt, int index) { return false; }
+};
+
+class CStarRef1 : public CBaseStarRef {
+private:
+ Common::Point _position;
+public:
+ int _index;
+public:
+ CStarRef1(CBaseStar *star, const Common::Point &pt) :
+ CBaseStarRef(star), _index(-1) {}
+ virtual ~CStarRef1() {}
+
+ virtual bool check(const Common::Point &pt, int index);
+};
+
+class CStarRef2 : public CBaseStarRef {
+private:
+ Common::Array<CStarPosition> *_positions;
+public:
+ int _index;
+public:
+ CStarRef2(CBaseStar *star, Common::Array<CStarPosition> *positions) :
+ CBaseStarRef(star), _positions(positions), _index(0) {}
+ virtual ~CStarRef2() {}
+
+ virtual bool check(const Common::Point &pt, int index);
+};
+
+class CStarRef3 : public CBaseStarRef {
+public:
+ int _index;
+public:
+ CStarRef3(CBaseStar *star) :CBaseStarRef(star), _index(0) {}
+ virtual ~CStarRef3() {}
+
+ virtual bool check(const Common::Point &pt, int index);
+};
+
+} // End of namespace Titanic
+
+#endif /* TITANIC_STAR_REF_H */
diff --git a/engines/titanic/star_control/star_view.cpp b/engines/titanic/star_control/star_view.cpp
index 23e9325a64..34fd371bac 100644
--- a/engines/titanic/star_control/star_view.cpp
+++ b/engines/titanic/star_control/star_view.cpp
@@ -30,8 +30,8 @@
namespace Titanic {
-CStarView::CStarView() : _sub12(nullptr, nullptr), _sub13((void *)nullptr),
- _owner(nullptr), _starField(nullptr), _videoSurface(nullptr), _field118(0),
+CStarView::CStarView() : _sub12((const CStar20Data *)nullptr), _owner(nullptr),
+ _starField(nullptr), _videoSurface(nullptr), _field118(0),
_videoSurface2(nullptr), _homePhotoMask(nullptr),
_field218(false), _showingPhoto(false) {
CStar20Data data = { 0, 0, 100000.0, 0, 20.0, 1.0, 1.0, 1.0 };
@@ -177,7 +177,7 @@ bool CStarView::KeyCharMsg(int key, CErrorCode *errorCode) {
case Common::KEYCODE_z:
case Common::KEYCODE_c:
if (v == -1) {
- sub6.set(key == Common::KEYCODE_z ? MODE_PHOTO : MODE_STARFIELD, 1.0);
+ sub6.setRotationMatrix(key == Common::KEYCODE_z ? Y_AXIS : X_AXIS, 1.0);
_sub12.proc22(sub6);
_sub12.proc15(errorCode);
return true;
@@ -210,7 +210,7 @@ bool CStarView::KeyCharMsg(int key, CErrorCode *errorCode) {
case Common::KEYCODE_x:
if (v == -1) {
- sub6.set(MODE_PHOTO, -1.0);
+ sub6.setRotationMatrix(Y_AXIS, -1.0);
_sub12.proc22(sub6);
_sub12.proc15(errorCode);
return true;
@@ -219,7 +219,7 @@ bool CStarView::KeyCharMsg(int key, CErrorCode *errorCode) {
case Common::KEYCODE_QUOTE:
if (v == -1) {
- sub6.set(MODE_STARFIELD, -1.0);
+ sub6.setRotationMatrix(X_AXIS, -1.0);
_sub12.proc22(sub6);
_sub12.proc15(errorCode);
return true;
@@ -450,7 +450,7 @@ void CStarView::randomizeVectors1(FVector &v1, FVector &v2) {
v2._x = vx;
v2._y = vy;
v2._z = -v1._z;
- v2.fn3();
+ v2.normalize();
}
void CStarView::randomizeVectors2(FVector &v1, FVector &v2) {
@@ -462,7 +462,7 @@ void CStarView::randomizeVectors2(FVector &v1, FVector &v2) {
v2._x = -v1._x;
v2._y = -v1._y;
v2._z = -v1._z;
- v2.fn3();
+ v2.normalize();
}
void CStarView::randomizeVectors3(FVector &v1, FVector &v2) {
@@ -474,7 +474,7 @@ void CStarView::randomizeVectors3(FVector &v1, FVector &v2) {
v2._x = -v1._x;
v2._y = -v1._y;
v2._z = -v1._z;
- v2.fn3();
+ v2.normalize();
}
void CStarView::randomizeVectors4(FVector &v1, FVector &v2) {
@@ -486,7 +486,7 @@ void CStarView::randomizeVectors4(FVector &v1, FVector &v2) {
v2._x = -v1._x;
v2._y = -v1._y;
v2._z = -v1._z;
- v2.fn3();
+ v2.normalize();
}
void CStarView::resizeSurface(CScreenManager *scrManager, int width, int height,
CVideoSurface **surface) {
diff --git a/engines/titanic/star_control/surface_area.cpp b/engines/titanic/star_control/surface_area.cpp
index 9b46cf03b7..4cfc4f84d2 100644
--- a/engines/titanic/star_control/surface_area.cpp
+++ b/engines/titanic/star_control/surface_area.cpp
@@ -28,11 +28,14 @@ CSurfaceArea::CSurfaceArea(CVideoSurface *surface) {
_width = surface->getWidth();
_height = surface->getHeight();
_pitch = surface->getPitch();
+ _field0 = 0;
+ _colorMask = _color = 0;
+ _mode = SA_NONE;
// Original supported other pixel depths
_bpp = surface->getPixelDepth();
- assert(_bpp == 2);
_pixelsPtr = surface->getPixels();
+ assert(_bpp == 2 && _pixelsPtr);
initialize();
}
diff --git a/engines/titanic/titanic.h b/engines/titanic/titanic.h
index fdc9402d89..6bc999cd40 100644
--- a/engines/titanic/titanic.h
+++ b/engines/titanic/titanic.h
@@ -166,7 +166,7 @@ public:
/**
* Returns a random floating point number between 0.0 to 65535.0
*/
- double getRandomFloat() { return getRandomNumber(0xffffffff) * 0.000015259022; }
+ double getRandomFloat() { return getRandomNumber(0xfffffffe) * 0.000015259022; }
/**
* Support method that generates a savegame name