aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorMatthew Stewart2018-05-16 18:21:34 -0400
committerEugene Sandulenko2018-08-09 08:37:30 +0200
commit2120ce106210538c9508be1e275bdba97ddda63a (patch)
treee255e695c4c0253fba4545fa935f0c450a5ef1b2 /engines
parent2731ae228795ca1a8d823f147212ef5c22261598 (diff)
downloadscummvm-rg350-2120ce106210538c9508be1e275bdba97ddda63a.tar.gz
scummvm-rg350-2120ce106210538c9508be1e275bdba97ddda63a.tar.bz2
scummvm-rg350-2120ce106210538c9508be1e275bdba97ddda63a.zip
STARTREK: Action menu
Diffstat (limited to 'engines')
-rw-r--r--engines/startrek/awaymission.cpp36
-rw-r--r--engines/startrek/awaymission.h4
-rw-r--r--engines/startrek/events.cpp13
-rw-r--r--engines/startrek/graphics.cpp63
-rw-r--r--engines/startrek/graphics.h11
-rw-r--r--engines/startrek/menu.cpp329
-rw-r--r--engines/startrek/sound.cpp5
-rw-r--r--engines/startrek/sound.h1
-rw-r--r--engines/startrek/sprite.cpp6
-rw-r--r--engines/startrek/sprite.h5
-rw-r--r--engines/startrek/startrek.cpp9
-rw-r--r--engines/startrek/startrek.h23
-rw-r--r--engines/startrek/text.cpp6
13 files changed, 488 insertions, 23 deletions
diff --git a/engines/startrek/awaymission.cpp b/engines/startrek/awaymission.cpp
index efa603d69d..aba01c075b 100644
--- a/engines/startrek/awaymission.cpp
+++ b/engines/startrek/awaymission.cpp
@@ -84,7 +84,7 @@ void StarTrekEngine::loadRoom(const Common::String &missionName, int roomIndex)
// Original sets up bytes 0-3 of rdf file as "remote function caller"
// Load map file
- _awayMission.mapFileLoaded = 1;
+ _awayMission.activeAction = ACTION_WALK;
_mapFilename = _screenName;
_mapFile = loadFile(_mapFilename + ".map");
_iwFile = SharedPtr<IWFile>(new IWFile(this, _mapFilename + ".iw"));
@@ -161,7 +161,7 @@ void StarTrekEngine::handleAwayMissionEvents() {
// doSomethingWithBanData1();
_gfx->drawAllSprites();
// doSomethingWithBanData2();
- // updateMusic(); // Is this needed?
+ _sound->checkLoopMusic();
// sub_22de0();
_frameIndex++;
_roomFrameCounter++;
@@ -172,7 +172,7 @@ void StarTrekEngine::handleAwayMissionEvents() {
case TREKEVENT_LBUTTONDOWN:
if (_awayMission.transitioningIntoRoom != 0)
break;
- switch (_awayMission.mapFileLoaded) {
+ switch (_awayMission.activeAction) {
case 1:
if (_awayMission.field1c == 0) {
_kirkObject->sprite.drawMode = 1; // Hide these objects for function call below?
@@ -205,7 +205,35 @@ void StarTrekEngine::handleAwayMissionEvents() {
break;
case TREKEVENT_MOUSEMOVE:
break;
- case TREKEVENT_RBUTTONDOWN:
+ case TREKEVENT_RBUTTONDOWN: // TODO: also triggered by key press?
+ /*
+ if (_awayMission.field1d)
+ break;
+ */
+ //sub_2394b();
+ playSoundEffectIndex(0x07);
+ _awayMission.activeAction = showActionMenu();
+ /*
+ if (awayMission.activeAction == ACTION_USE) {
+ int16 clickedObject = sub_22f08();
+ if (clickedObject == -1)
+ break;
+ else
+ _awayMission.field20 = clickedObject;
+ }
+ if (_awayMission.activeAction == ACTION_USE
+ && _awayMission.field20 == 0x47 && (_awayMission.field24 & 1) == 0) {
+ if (sub_2330c() == 0) {
+ addCommand(Command(_awayMission.activeAction, _awayMission.field20, 0, 0));
+ _sound->playVoc("communic");
+ _awayMission.activeAction = ACTION_WALK;
+ }
+ }
+ else if (_awayMission.activeAction == ACTION_LOOK)
+ sub_2383a(0);
+ else if (_awayMission.activeAction == ACTION_USE && (_awayMission.field24 & 1) == 0)
+ sub_2383a(1);
+ */
break;
case TREKEVENT_KEYDOWN:
break;
diff --git a/engines/startrek/awaymission.h b/engines/startrek/awaymission.h
index 2036b604c3..cb5dfed0f6 100644
--- a/engines/startrek/awaymission.h
+++ b/engines/startrek/awaymission.h
@@ -28,9 +28,11 @@ struct AwayMission {
int16 mouseX;
int16 mouseY;
byte field1c;
+ byte field1d;
byte transitioningIntoRoom; // Set while beaming in or walking into a room
bool redshirtDead;
- byte mapFileLoaded;
+ byte activeAction;
+ byte field20;
byte field24;
int8 field25[4];
diff --git a/engines/startrek/events.cpp b/engines/startrek/events.cpp
index f36ce6a1d2..58c2666c7b 100644
--- a/engines/startrek/events.cpp
+++ b/engines/startrek/events.cpp
@@ -40,17 +40,30 @@ void StarTrekEngine::pollSystemEvents() {
trekEvent.type = TREKEVENT_MOUSEMOVE;
addEventToQueue(trekEvent);
break;
+
case Common::EVENT_LBUTTONDOWN:
// TODO: what happens when mouse click is outside normal screen bounds?
// (apparently this can happen)
trekEvent.type = TREKEVENT_LBUTTONDOWN;
addEventToQueue(trekEvent);
break;
+
+ case Common::EVENT_RBUTTONDOWN:
+ trekEvent.type = TREKEVENT_RBUTTONDOWN;
+ addEventToQueue(trekEvent);
+ break;
+
+ case Common::EVENT_KEYDOWN:
+ trekEvent.type = TREKEVENT_KEYDOWN;
+ addEventToQueue(trekEvent);
+ break;
+
default:
break;
}
}
+ // TODO: check for events other than "tick" more often.
if (_eventQueue.empty()) {
int delay = 1000/18.206 - (_system->getMillis() - _frameStartMillis);
diff --git a/engines/startrek/graphics.cpp b/engines/startrek/graphics.cpp
index ec3c4d0d4d..cf1fa7f4ed 100644
--- a/engines/startrek/graphics.cpp
+++ b/engines/startrek/graphics.cpp
@@ -51,8 +51,9 @@ Graphics::Graphics(StarTrekEngine *vm) : _vm(vm), _egaMode(false) {
_lutData = new byte[256 * 3];
_paletteFadeLevel = 0;
+ _mouseLocked = false;
- setMouseCursor(loadBitmap("pushbtn"));
+ setMouseBitmap(loadBitmap("pushbtn"));
CursorMan.showMouse(true);
}
@@ -180,9 +181,58 @@ Common::Point Graphics::getMousePos() {
return _vm->_system->getEventManager()->getMousePos();
}
-void Graphics::setMouseCursor(SharedPtr<Bitmap> bitmap) {
+void Graphics::setMouseBitmap(SharedPtr<Bitmap> bitmap) {
_mouseBitmap = bitmap;
_vm->_system->setMouseCursor(bitmap->pixels, bitmap->width, bitmap->height, bitmap->xoffset, bitmap->yoffset, 0);
+
+ if (_mouseLocked) {
+ _lockedMouseSprite.setBitmap(_mouseBitmap);
+ drawAllSprites(false);
+ }
+}
+
+/**
+ * This function is a workaround for when the mouse position needs to be locked in a set
+ * position (used in the action menu). This only affects the position it is drawn at; the
+ * sprite's "real" position is still updated normally.
+ *
+ * This does not call updateScreen.
+ */
+void Graphics::lockMousePosition(int16 x, int16 y) {
+ if (_mouseLocked) {
+ if (x != _lockedMouseSprite.pos.x || y != _lockedMouseSprite.pos.y) {
+ _lockedMouseSprite.pos.x = x;
+ _lockedMouseSprite.pos.y = y;
+ _lockedMouseSprite.bitmapChanged = true;
+ drawAllSprites(false);
+ }
+ return;
+ }
+
+ CursorMan.showMouse(false);
+ _mouseLocked = true;
+
+ _lockedMouseSprite = Sprite();
+ _lockedMouseSprite.setBitmap(_mouseBitmap);
+ _lockedMouseSprite.drawPriority = 15;
+ _lockedMouseSprite.drawPriority2 = 16;
+ _lockedMouseSprite.pos.x = x;
+ _lockedMouseSprite.pos.y = y;
+
+ addSprite(&_lockedMouseSprite);
+ drawAllSprites(false);
+}
+
+void Graphics::unlockMousePosition() {
+ if (!_mouseLocked)
+ return;
+
+ _mouseLocked = false;
+ CursorMan.showMouse(true);
+
+ _lockedMouseSprite.dontDrawNextFrame();
+ drawAllSprites();
+ delSprite(&_lockedMouseSprite);
}
void Graphics::drawSprite(const Sprite &sprite) {
@@ -340,14 +390,14 @@ void Graphics::drawSprite(const Sprite &sprite, const Common::Rect &rect) {
bool compareSpritesByLayer(Sprite *s1, Sprite *s2) {
if (s1->drawPriority != s2->drawPriority)
return s1->drawPriority < s2->drawPriority;
- if (s1->field6 != s2->field6)
- return s1->field6 < s2->field6;
+ if (s1->drawPriority2 != s2->drawPriority2)
+ return s1->drawPriority2 < s2->drawPriority2;
if (s1->pos.y != s2->pos.y)
return s1->pos.y < s2->pos.y;
return s1->pos.x < s2->pos.x;
}
-void Graphics::drawAllSprites() {
+void Graphics::drawAllSprites(bool updateScreen) {
// TODO: different video modes?
if (_numSprites == 0)
@@ -458,7 +508,8 @@ void Graphics::drawAllSprites() {
spr->lastDrawRect = spr->drawRect;
}
- _vm->_system->updateScreen();
+ if (updateScreen)
+ _vm->_system->updateScreen();
}
void Graphics::addSprite(Sprite *sprite) {
diff --git a/engines/startrek/graphics.h b/engines/startrek/graphics.h
index 0a737f7d72..cba5ddfacd 100644
--- a/engines/startrek/graphics.h
+++ b/engines/startrek/graphics.h
@@ -67,11 +67,13 @@ public:
SharedPtr<Bitmap> loadBitmap(String basename);
Common::Point getMousePos();
- void setMouseCursor(SharedPtr<Bitmap> bitmap);
+ void setMouseBitmap(SharedPtr<Bitmap> bitmap);
+ void lockMousePosition(int16 x, int16 y);
+ void unlockMousePosition();
void drawSprite(const Sprite &sprite);
void drawSprite(const Sprite &sprite, const Common::Rect &rect);
- void drawAllSprites();
+ void drawAllSprites(bool updateScreen=true);
void addSprite(Sprite *sprite);
void delSprite(Sprite *sprite);
@@ -100,6 +102,11 @@ private:
Sprite *_sprites[MAX_SPRITES];
int _numSprites;
+ // These are used as a workaround for when the mouse position must be locked.
+ // The mouse is turned into a native game sprite when this happens.
+ bool _mouseLocked;
+ Sprite _lockedMouseSprite;
+
public:
SharedPtr<Bitmap> _mouseBitmap;
};
diff --git a/engines/startrek/menu.cpp b/engines/startrek/menu.cpp
index f10e784a35..2538c816d2 100644
--- a/engines/startrek/menu.cpp
+++ b/engines/startrek/menu.cpp
@@ -204,7 +204,7 @@ void StarTrekEngine::showOptionsMenu(int x, int y) {
Common::Point oldMousePos = _gfx->getMousePos();
SharedPtr<Bitmap> oldMouseBitmap = _gfx->_mouseBitmap;
- _gfx->setMouseCursor(_gfx->loadBitmap("options"));
+ _gfx->setMouseBitmap(_gfx->loadBitmap("options"));
loadMenuButtons("options", x, y);
uint32 disabledButtons = 0;
@@ -232,7 +232,7 @@ void StarTrekEngine::showOptionsMenu(int x, int y) {
unloadMenuButtons();
_mouseControllingShip = tmpMouseControllingShip;
- _gfx->setMouseCursor(oldMouseBitmap);
+ _gfx->setMouseBitmap(oldMouseBitmap);
if (event != MENUEVENT_LCLICK_OFFBUTTON && event != MENUEVENT_RCLICK_OFFBUTTON)
_system->warpMouse(oldMousePos.x, oldMousePos.y);
@@ -271,6 +271,262 @@ void StarTrekEngine::showOptionsMenu(int x, int y) {
}
/**
+ * Show the "action selection" menu, ie. look, talk, etc.
+ */
+int StarTrekEngine::showActionMenu() {
+ const int actionMappingUp[] = { // Actions to jump to when up is pressed
+ ACTION_TALK, // <- ACTION_WALK
+ ACTION_TALK, // <- ACTION_USE
+ ACTION_OPTIONS, // <- ACTION_GET
+ ACTION_LOOK, // <- ACTION_LOOK
+ ACTION_LOOK, // <- ACTION_TALK
+ ACTION_OPTIONS // <- ACTION_OPTIONS
+ };
+ const int actionMappingRight[] = { // Actions to jump to when right is pressed
+ ACTION_GET, // <- ACTION_WALK
+ ACTION_WALK, // <- ACTION_USE
+ ACTION_GET, // <- ACTION_GET
+ ACTION_OPTIONS, // <- ACTION_LOOK
+ ACTION_OPTIONS, // <- ACTION_TALK
+ ACTION_OPTIONS // <- ACTION_OPTIONS
+ };
+ const int actionMappingDown[] = { // Actions to jump to when down is pressed
+ ACTION_GET, // <- ACTION_WALK
+ ACTION_WALK, // <- ACTION_USE
+ ACTION_GET, // <- ACTION_GET
+ ACTION_TALK, // <- ACTION_LOOK
+ ACTION_WALK, // <- ACTION_TALK
+ ACTION_GET // <- ACTION_OPTIONS
+ };
+ const int actionMappingLeft[] = { // Actions to jump to when left is pressed
+ ACTION_USE, // <- ACTION_WALK
+ ACTION_USE, // <- ACTION_USE
+ ACTION_WALK, // <- ACTION_GET
+ ACTION_USE, // <- ACTION_LOOK
+ ACTION_USE, // <- ACTION_TALK
+ ACTION_LOOK // <- ACTION_OPTIONS
+ };
+
+ const Common::Point pos(50, 50); // Top-left position to put action menu at
+
+ // Positions to put mouse cursor at to select actions (when using arrow keys)
+ const Common::Point actionPositions[] = {
+ Common::Point(7, 21), // ACTION_USE
+ Common::Point(48, 38), // ACTION_GET
+ Common::Point(28, 5), // ACTION_LOOK
+ Common::Point(28, 14), // ACTION_TALK
+ Common::Point(45, 9) // ACTION_OPTIONS
+ };
+
+ TrekEvent event;
+ Sprite menuSprite;
+
+ bool keyboardControlledMouse = _keyboardControlsMouse;
+ Common::Point oldMousePos = _gfx->getMousePos();
+
+ bool addEventBack = false;
+ int action = ACTION_WALK;
+
+ menuSprite.bitmap = _gfx->loadBitmap("action");
+ int menuWidth = menuSprite.bitmap->width;
+ int menuHeight = menuSprite.bitmap->height;
+
+ _system->warpMouse(pos.x + menuWidth / 2, pos.y + menuHeight / 2);
+
+ _gfx->addSprite(&menuSprite);
+ menuSprite.pos = pos;
+ menuSprite.drawPriority = 15;
+
+ chooseMouseBitmapForAction(action, false);
+
+ _gfx->drawAllSprites();
+
+ menuSprite.drawPriority2 = 8;
+ bool displayMenu = true;
+
+ while (displayMenu) {
+ _sound->checkLoopMusic();
+
+ if (!popNextEvent(&event))
+ continue;
+
+ switch (event.type) {
+
+ case TREKEVENT_TICK:
+ _gfx->incPaletteFadeLevel();
+ _gfx->drawAllSprites();
+ break;
+
+ case TREKEVENT_LBUTTONDOWN:
+selectAndExit:
+ displayMenu = false;
+ addEventBack = true;
+ break;
+
+ case TREKEVENT_MOUSEMOVE:
+mousePosChanged:
+ {
+ Common::Point mouse = _gfx->getMousePos();
+ Common::Point relMouse(mouse.x - pos.x, mouse.y - pos.y);
+
+ Common::String bitmapName;
+ Common::Point lockMousePoint(-1, -1);
+
+ // Check if the mouse is hovering over one of the selectable actions
+ if (relMouse.x >= 39 && relMouse.x <= 50 && relMouse.y >= 2 && relMouse.y <= 17) {
+ action = ACTION_OPTIONS;
+ bitmapName = "options";
+ lockMousePoint = Common::Point(pos.x + 44, pos.y + 2);
+ }
+ else if (relMouse.x >= 18 && relMouse.x <= 38 && relMouse.y >= 2 && relMouse.y <= 9) {
+ action = ACTION_LOOK;
+ bitmapName = "look";
+ lockMousePoint = Common::Point(pos.x + 28, pos.y + 6);
+ }
+ else if (relMouse.x >= 18 && relMouse.x <= 38 && relMouse.y >= 11 && relMouse.y <= 17) {
+ action = ACTION_TALK;
+ bitmapName = "talk";
+ lockMousePoint = Common::Point(pos.x + 27, pos.y + 14);
+ }
+ else if (relMouse.x >= 2 && relMouse.x <= 13 && relMouse.y >= 16 && relMouse.y <= 26) {
+ action = ACTION_USE;
+ bitmapName = "use";
+ lockMousePoint = Common::Point(pos.x + 7, pos.y + 19);
+ }
+ else if (relMouse.x >= 40 && relMouse.x <= 53 && relMouse.y >= 34 && relMouse.y <= 43) {
+ action = ACTION_GET;
+ bitmapName = "get";
+ lockMousePoint = Common::Point(pos.x + 44, pos.y + 38);
+ }
+ else {
+ action = ACTION_WALK;
+ bitmapName = "walk";
+ }
+
+ _gfx->setMouseBitmap(_gfx->loadBitmap(bitmapName));
+
+ if (lockMousePoint.x != -1)
+ _gfx->lockMousePosition(lockMousePoint.x, lockMousePoint.y);
+ else
+ _gfx->unlockMousePosition();
+
+ _system->updateScreen();
+ }
+ break;
+
+ case TREKEVENT_RBUTTONDOWN:
+exitMenu:
+ displayMenu = false;
+ action = ACTION_WALK;
+ break;
+
+ case TREKEVENT_KEYDOWN: {
+ int nextAction = action;
+ const int *lookupArray;
+
+ switch (event.kbd.keycode) {
+ case Common::KEYCODE_ESCAPE:
+ case Common::KEYCODE_SPACE:
+ case Common::KEYCODE_F2: // Exit menu without selecting anything
+ goto exitMenu;
+ goto exitMenu;
+
+ case Common::KEYCODE_RETURN:
+ case Common::KEYCODE_KP_ENTER:
+ case Common::KEYCODE_F1: // Exit menu with whatever is selected
+ goto selectAndExit;
+
+ case Common::KEYCODE_PAGEUP:
+ case Common::KEYCODE_KP9:
+ nextAction = ACTION_OPTIONS;
+ break;
+
+ case Common::KEYCODE_PAGEDOWN:
+ case Common::KEYCODE_KP3:
+ nextAction = ACTION_GET;
+ break;
+
+ // Direction buttons
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_KP8:
+ lookupArray = actionMappingUp;
+ goto lookupNextAction;
+
+ case Common::KEYCODE_RIGHT:
+ case Common::KEYCODE_KP6:
+ lookupArray = actionMappingRight;
+ goto lookupNextAction;
+
+ case Common::KEYCODE_DOWN:
+ case Common::KEYCODE_KP2:
+ lookupArray = actionMappingDown;
+ goto lookupNextAction;
+
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_KP4:
+ lookupArray = actionMappingLeft;
+ goto lookupNextAction;
+
+lookupNextAction:
+ // Use a lookup table to decide which action is next after a direction
+ // button is pressed.
+ assert((action >= ACTION_WALK && action <= ACTION_TALK) || action == ACTION_OPTIONS);
+ nextAction = lookupArray[action == ACTION_OPTIONS ? 5 : action - 1];
+ break;
+
+ default:
+ break;
+ }
+
+ if (nextAction == action)
+ break;
+
+ action = nextAction;
+
+ // Warp mouse to the position of the selected action
+ if (nextAction == ACTION_WALK)
+ _system->warpMouse(pos.x + menuWidth / 2, pos.y + menuHeight / 2);
+ else {
+ assert((action >= ACTION_WALK && action <= ACTION_TALK) || action == ACTION_OPTIONS);
+ const Common::Point &p = actionPositions[action == ACTION_OPTIONS ? 4 : action - 2];
+ _system->warpMouse(pos.x + p.x, pos.y + p.y);
+ }
+
+ goto mousePosChanged;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ _gfx->unlockMousePosition();
+
+ playSoundEffectIndex(0x10);
+
+ menuSprite.dontDrawNextFrame();
+ _gfx->drawAllSprites();
+ _gfx->delSprite(&menuSprite);
+
+ if (action == ACTION_OPTIONS) {
+ showOptionsMenu(50, 50);
+ action = ACTION_WALK;
+ }
+
+ Common::Point mouse = _gfx->getMousePos();
+ if (mouse.x < pos.x || mouse.x >= pos.x + menuWidth || mouse.y < pos.y || mouse.y >= pos.y + menuHeight) {
+ if (action == ACTION_WALK && addEventBack)
+ addEventToQueue(event); // Add left-click event back to queue so Kirk can walk there
+ }
+ else
+ _system->warpMouse(oldMousePos.x, oldMousePos.y);
+
+ chooseMouseBitmapForAction(action, false);
+ _keyboardControlsMouse = keyboardControlledMouse;
+ return action;
+}
+
+/**
* Loads a .MNU file, which is a list of buttons to display.
*/
void StarTrekEngine::loadMenuButtons(String mnuFilename, int xpos, int ypos) {
@@ -305,7 +561,7 @@ void StarTrekEngine::loadMenuButtons(String mnuFilename, int xpos, int ypos) {
_activeMenu->sprites[i].pos.y = stream->readUint16() + ypos;
_activeMenu->retvals[i] = stream->readUint16();
- _activeMenu->sprites[i].field6 = 8;
+ _activeMenu->sprites[i].drawPriority2 = 8;
}
if (_activeMenu->retvals[_activeMenu->numButtons - 1] == 0) {
@@ -498,6 +754,73 @@ void StarTrekEngine::unloadMenuButtons() {
_keyboardControlsMouse = _keyboardControlsMouseOutsideMenu;
}
+/**
+ * Sets the mouse bitmap based on which action is selected.
+ */
+void StarTrekEngine::chooseMouseBitmapForAction(int action, bool withRedOutline) {
+ const char *lookActionBitmaps[] = {
+ "lookh0", // The "look" action randomly animates with these images
+ "lookh0",
+ "lookh0",
+ "lookh0",
+ "lookh0",
+ "lookh1",
+ "lookh2",
+ "lookh3"
+ };
+
+ Common::String bitmapName;
+
+ switch (action) {
+
+ case ACTION_USE:
+ if (withRedOutline)
+ bitmapName = "useh";
+ else
+ bitmapName = "usen";
+ break;
+
+ case ACTION_GET:
+ if (withRedOutline)
+ bitmapName = "geth";
+ else
+ bitmapName = "getn";
+ break;
+
+ case ACTION_LOOK:
+ if (withRedOutline) {
+ if ((getRandomWord() & 7) == 0)
+ _lookActionBitmapIndex = getRandomWord() & 7; // Choose an image randomly
+ bitmapName = lookActionBitmaps[_lookActionBitmapIndex];
+ }
+ else
+ bitmapName = "lookn";
+ break;
+
+ case ACTION_TALK:
+ if (withRedOutline) {
+ if (getRandomWord() & 3)
+ bitmapName = "talkh0";
+ else
+ bitmapName = "talkh1";
+ }
+ else
+ bitmapName = "talkn";
+ break;
+
+ case ACTION_OPTIONS:
+ bitmapName = "options";
+ break;
+
+ case ACTION_WALK:
+ default:
+ bitmapName = "walk";
+ break;
+ }
+
+ _gfx->setMouseBitmap(_gfx->loadBitmap(bitmapName));
+}
+
void StarTrekEngine::showSaveMenu() {
// TODO
}
diff --git a/engines/startrek/sound.cpp b/engines/startrek/sound.cpp
index 105b3a0b7a..45b6eb064a 100644
--- a/engines/startrek/sound.cpp
+++ b/engines/startrek/sound.cpp
@@ -278,6 +278,11 @@ void Sound::setSfxEnabled(bool enable) {
}
}
+void Sound::checkLoopMusic() {
+ // TODO
+ // It might be better to get rid of this altogether and deal with it in callbacks...
+}
+
// XMIDI or SM sound
void Sound::loadPCMusicFile(const Common::String &baseSoundName) {
diff --git a/engines/startrek/sound.h b/engines/startrek/sound.h
index 6ce4e94a7c..7030805d08 100644
--- a/engines/startrek/sound.h
+++ b/engines/startrek/sound.h
@@ -63,6 +63,7 @@ public:
void stopPlayingSpeech();
void setMusicEnabled(bool enable);
void setSfxEnabled(bool enable);
+ void checkLoopMusic();
private:
StarTrekEngine *_vm;
diff --git a/engines/startrek/sprite.cpp b/engines/startrek/sprite.cpp
index ba5fa76072..8c1c2f6b78 100644
--- a/engines/startrek/sprite.cpp
+++ b/engines/startrek/sprite.cpp
@@ -29,9 +29,13 @@ namespace StarTrek {
void Sprite::setBitmap(SharedPtr<Bitmap> b) {
bitmap = b;
- bitmapChanged = 1;
+ bitmapChanged = true;
}
+void Sprite::dontDrawNextFrame() {
+ field16 = true;
+ bitmapChanged = true;
+}
/**
* Returns a rect containing the sprite's bitmap on the screen.
*/
diff --git a/engines/startrek/sprite.h b/engines/startrek/sprite.h
index 844fb80c35..f2e3780330 100644
--- a/engines/startrek/sprite.h
+++ b/engines/startrek/sprite.h
@@ -44,7 +44,7 @@ namespace StarTrek {
struct Sprite {
Common::Point pos;
uint16 drawPriority;
- uint16 field6;
+ uint16 drawPriority2; // If two sprites' drawPriorities are equal, this is checked.
uint16 field8;
SharedPtr<Bitmap> bitmap;
uint16 drawMode;
@@ -59,7 +59,10 @@ struct Sprite {
int16 drawX,drawY;
Sprite() { memset(this, 0, sizeof(Sprite)); }
+
void setBitmap(SharedPtr<Bitmap> b);
+ void dontDrawNextFrame();
+
Common::Rect getRect();
};
diff --git a/engines/startrek/startrek.cpp b/engines/startrek/startrek.cpp
index 61c78bd989..8147ecaefc 100644
--- a/engines/startrek/startrek.cpp
+++ b/engines/startrek/startrek.cpp
@@ -43,6 +43,7 @@ namespace StarTrek {
StarTrekEngine::StarTrekEngine(OSystem *syst, const StarTrekGameDescription *gamedesc) :
Engine(syst),
_gameDescription(gamedesc),
+ _randomSource("Star Trek"),
_kirkObject(&_objectList[0]),
_spockObject(&_objectList[1]),
_mccoyObject(&_objectList[2]),
@@ -64,6 +65,8 @@ StarTrekEngine::StarTrekEngine(OSystem *syst, const StarTrekGameDescription *gam
_sfxWorking = true;
_finishedPlayingSpeech = false;
+ _lookActionBitmapIndex = 0;
+
_mouseControllingShip = false;
_keyboardControlsMouse = true;
@@ -432,7 +435,7 @@ void StarTrekEngine::updateObjectAnimations() {
case 0: // Not walking?
case 2:
if (_frameIndex >= object->frameToStartNextAnim) {
- int nextAnimIndex = 0; // TODO: "chooseNextAnimFrame" function
+ int nextAnimIndex = getRandomWord() & 3;
object->animFile->seek(18 + nextAnimIndex + object->animFrame * 22, SEEK_SET);
byte nextAnimFrame = object->animFile->readByte();
@@ -1269,4 +1272,8 @@ void StarTrekEngine::playMovieMac(Common::String filename) {
initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT);
}
+uint16 StarTrekEngine::getRandomWord() {
+ return _randomSource.getRandomNumber(0xffff);
+}
+
} // End of namespace StarTrek
diff --git a/engines/startrek/startrek.h b/engines/startrek/startrek.h
index 8031bcb557..b146df8c8f 100644
--- a/engines/startrek/startrek.h
+++ b/engines/startrek/startrek.h
@@ -26,6 +26,7 @@
#include "common/events.h"
#include "common/list.h"
#include "common/ptr.h"
+#include "common/random.h"
#include "common/rect.h"
#include "common/scummsys.h"
#include "common/str.h"
@@ -137,7 +138,7 @@ enum OptionMenuButtons {
};
enum TrekEventType {
- TREKEVENT_TICK = 0, // DOS clock changes (see updateClockTicks)
+ TREKEVENT_TICK = 0, // DOS clock changes
TREKEVENT_LBUTTONDOWN = 1,
TREKEVENT_MOUSEMOVE = 2,
TREKEVENT_LBUTTONUP = 3,
@@ -153,6 +154,8 @@ struct TrekEvent {
uint32 tick;
};
+// Commands: Signals that can be passed to "handleAwayMissionCommands" or to room-specfiic
+// code.
enum Commands {
COMMAND_TICK = 0,
COMMAND_CLICKED_ON_OBJECT = 1,
@@ -172,6 +175,16 @@ struct Command {
: type(_type), b1(_b1), b2(_b2), b3(_b3) {}
};
+// Actions that can be used on away missions.
+enum Acton {
+ ACTION_WALK = 1,
+ ACTION_USE = 2,
+ ACTION_GET = 3,
+ ACTION_LOOK = 4,
+ ACTION_TALK = 5,
+ ACTION_OPTIONS = 13 // Not really an action, but selectable from action menu
+};
+
struct StarTrekGameDescription;
class Graphics;
@@ -292,6 +305,7 @@ public:
void chooseMousePositionFromSprites(Sprite *sprites, int numSprites, int spriteIndex, int mode);
void drawMenuButtonOutline(SharedPtr<Bitmap> bitmap, byte color);
void showOptionsMenu(int x, int y);
+ int showActionMenu();
void loadMenuButtons(String mnuFilename, int xpos, int ypos);
void setVisibleMenuButtons(uint32 bits);
void disableMenuButtons(uint32 bits);
@@ -299,6 +313,7 @@ public:
int handleMenuEvents(uint32 ticksUntilClickingEnabled, bool arg4);
void unloadMenuButtons();
+ void chooseMouseBitmapForAction(int action, bool withRedOutline);
void showSaveMenu();
void showLoadMenu();
void showQuitGamePrompt(int x, int y);
@@ -333,6 +348,9 @@ public:
void playMovie(Common::String filename);
void playMovieMac(Common::String filename);
+ // Misc
+ uint16 getRandomWord();
+
public:
int _gameMode;
@@ -355,6 +373,7 @@ public:
bool _warpHotspotsActive;
int16 _activeWarpHotspot;
int16 _activeDoorWarpHotspot;
+ int16 _lookActionBitmapIndex;
Object _objectList[MAX_OBJECTS];
Object * const _kirkObject;
@@ -393,6 +412,8 @@ public:
Sound *_sound;
private:
+ Common::RandomSource _randomSource;
+
Common::MacResManager *_macResFork;
SharedPtr<Room> _room;
SharedPtr<IWFile> _iwFile;
diff --git a/engines/startrek/text.cpp b/engines/startrek/text.cpp
index fed047edcc..ed060c7624 100644
--- a/engines/startrek/text.cpp
+++ b/engines/startrek/text.cpp
@@ -250,7 +250,7 @@ int StarTrekEngine::showText(TextGetterFunc textGetter, uintptr var, int xoffset
SharedPtr<Bitmap> oldMouseBitmap = _gfx->_mouseBitmap;
_system->warpMouse(xoffset + 0xde, yoffset - 0x08);
- _gfx->setMouseCursor(_gfx->loadBitmap("pushbtn"));
+ _gfx->setMouseBitmap(_gfx->loadBitmap("pushbtn"));
bool tmpMouseControllingShip = _mouseControllingShip;
_mouseControllingShip = false;
@@ -398,7 +398,7 @@ reloadText:
}
}
- _gfx->setMouseCursor(oldMouseBitmap);
+ _gfx->setMouseBitmap(oldMouseBitmap);
_system->warpMouse(oldMousePos.x, oldMousePos.y);
_mouseControllingShip = tmpMouseControllingShip;
@@ -471,7 +471,7 @@ SharedPtr<TextBitmap> StarTrekEngine::initTextSprite(int *xoffsetPtr, int *yoffs
memset(sprite, 0, sizeof(Sprite));
sprite->drawPriority = 15;
- sprite->field6 = 8;
+ sprite->drawPriority2 = 8;
sprite->bitmap = bitmap;
sprite->textColor = textColor;