Files
scummvm/engines/startrek/startrek.h
T
Filippos Karapetis 108f3174f4 STARTREK: Implement basic functionality for the Enterprise's bridge
It's now possible to use the menu system and talk to some crewmates.
The game now starts in bridge mode, and it's possible to beam down
by using Kirk's transporter icon.
2020-11-23 01:24:51 +02:00

763 lines
23 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef STARTREK_H
#define STARTREK_H
#include "common/cosinetables.h"
#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/serializer.h"
#include "common/sinetables.h"
#include "common/str.h"
#include "common/stream.h"
#include "common/system.h"
#include "common/util.h"
#include "gui/saveload-dialog.h"
#include "engines/engine.h"
#include "startrek/action.h"
#include "startrek/awaymission.h"
#include "startrek/graphics.h"
#include "startrek/items.h"
#include "startrek/object.h"
#include "startrek/sound.h"
#include "startrek/space.h"
#include "startrek/detection.h"
using Common::SharedPtr;
using Common::String;
namespace Common {
class MacResManager;
}
namespace StarTrek {
class StarTrekEngine;
class Room;
class Console;
class Resource;
typedef String(StarTrekEngine::*TextGetterFunc)(int, uintptr, String *);
const int SAVEGAME_DESCRIPTION_LEN = 30;
struct SavegameMetadata {
uint32 version;
char description[SAVEGAME_DESCRIPTION_LEN + 1];
uint32 saveDate;
uint16 saveTime;
byte saveTimeSecs;
uint32 playTime;
::Graphics::Surface *thumbnail;
void setSaveTimeAndDate(TimeDate time) {
saveDate = ((time.tm_mday & 0xFF) << 24) | (((time.tm_mon + 1) & 0xFF) << 16) | ((time.tm_year + 1900) & 0xFFFF);
saveTime = ((time.tm_hour & 0xFF) << 8) | ((time.tm_min) & 0xFF);
saveTimeSecs = time.tm_sec & 0xFF;
}
int getDay() {
return (saveDate >> 24) & 0xFF;
}
int getMonth() {
return (saveDate >> 16) & 0xFF;
}
int getYear() {
return saveDate & 0xFFFF;
}
int getHour() {
return (saveTime >> 8) & 0xFF;
}
int getMinute() {
return saveTime & 0xFF;
}
};
const int MAX_MENUBUTTONS = 32;
const int TEXTBOX_WIDTH = 26;
const int TEXT_CHARS_PER_LINE = TEXTBOX_WIDTH - 2;
const int MAX_TEXTBOX_LINES = 12;
const int TEXT_INPUT_BUFFER_SIZE = 134;
const int MAX_TEXT_INPUT_LEN = 20;
const int MAX_BUFFERED_WALK_ACTIONS = 32;
const int MAX_BAN_FILES = 16;
enum kDebugLevels {
kDebugSound = 1 << 0,
kDebugGraphics = 1 << 1,
kDebugSavegame = 1 << 2,
kDebugSpace = 1 << 3,
kDebugGeneral = 1 << 4
};
enum GameMode {
GAMEMODE_START = 0,
GAMEMODE_BRIDGE,
GAMEMODE_AWAYMISSION,
GAMEMODE_BEAMDOWN,
GAMEMODE_BEAMUP
};
enum TextDisplayMode {
TEXTDISPLAY_WAIT = 0, // Wait for input before closing text
TEXTDISPLAY_SUBTITLES, // Automatically continue when speech is done
TEXTDISPLAY_NONE // No text displayed
};
enum TextColor {
TEXTCOLOR_GREY = 0x88,
TEXTCOLOR_RED = 0xa1,
TEXTCOLOR_YELLOW = 0xb0,
TEXTCOLOR_BLUE = 0xc0
};
// Keeps track of data for a list of buttons making up a menu
struct Menu {
Sprite sprites[MAX_MENUBUTTONS];
uint16 retvals[MAX_MENUBUTTONS];
uint32 disabledButtons;
uint16 numButtons;
int16 selectedButton;
Menu *nextMenu;
};
// Special events that can be returned by handleMenuEvents.
// (Normally it returns the "retval" of a pressed button, which is positive.)
enum MenuEvent {
MENUEVENT_RCLICK_OFFBUTTON = -4,
MENUEVENT_ENABLEINPUT, // Makes buttons selectable (occurs after a delay)
MENUEVENT_RCLICK_ONBUTTON,
MENUEVENT_LCLICK_OFFBUTTON
};
// Buttons for standard text display
enum TextButtons {
TEXTBUTTON_CONFIRM = 0,
TEXTBUTTON_SCROLLUP,
TEXTBUTTON_SCROLLDOWN,
TEXTBUTTON_PREVCHOICE,
TEXTBUTTON_NEXTCHOICE,
TEXTBUTTON_SCROLLUP_ONELINE,
TEXTBUTTON_SCROLLDOWN_ONELINE,
TEXTBUTTON_GOTO_TOP,
TEXTBUTTON_GOTO_BOTTOM,
TEXTBUTTON_SPEECH_DONE // "Virtual" button?
};
// Buttons for option menu (corresponding to button indices, not button retvals, which are
// different for some reason)
enum OptionMenuButtons {
OPTIONBUTTON_TEXT,
OPTIONBUTTON_SAVE,
OPTIONBUTTON_LOAD,
OPTIONBUTTON_ENABLEMUSIC,
OPTIONBUTTON_DISABLEMUSIC,
OPTIONBUTTON_ENABLESFX,
OPTIONBUTTON_DISABLESFX,
OPTIONBUTTON_QUIT
};
enum TrekEventType {
TREKEVENT_TICK = 0, // DOS clock changes
TREKEVENT_LBUTTONDOWN = 1,
TREKEVENT_MOUSEMOVE = 2,
TREKEVENT_LBUTTONUP = 3,
TREKEVENT_RBUTTONDOWN = 4,
TREKEVENT_RBUTTONUP = 5,
TREKEVENT_KEYDOWN = 6
};
struct TrekEvent {
TrekEventType type;
Common::KeyState kbd;
Common::Point mouse;
uint32 tick;
};
struct ComputerTopic {
Common::String fileName;
Common::String topic;
};
class Graphics;
class IWFile;
class Sound;
class StarTrekEngine : public ::Engine {
protected:
// startrek.cpp
public:
StarTrekEngine(OSystem *syst, const StarTrekGameDescription *gamedesc);
~StarTrekEngine() override;
friend class Console;
Common::Error run() override;
Common::Error runGameMode(int mode, bool resume);
// Transporter room
void runTransportSequence(const Common::String &name);
// Bridge
void initBridge(bool b);
void loadBridge();
void loadBridgeActors();
void cleanupBridge();
void runBridge();
void handleBridgeEvents();
void handleBridgeComputer();
void playMovie(Common::String filename);
void playMovieMac(Common::String filename);
uint16 getRandomWord();
// awaymission.cpp
void initAwayMission();
void runAwayMission();
void cleanupAwayMission();
void loadRoom(const Common::String &missionName, int roomIndex);
void initAwayCrewPositions(int warpEntryIndex);
void handleAwayMissionEvents();
void awayMissionLeftClick();
/**
* Called on right-click (select action), or when certain actions are otherwise
* selected (checks whether to show inventory icon, etc)
*/
void awayMissionSelectAction(bool openActionMenu);
void awayMissionUseObject(int16 clickedObject);
void awayMissionGetLookOrTalk(int16 clickedObject);
void unloadRoom();
/**
* Similar to loadActorAnim, but scale is determined by the y-position in the room. The
* further up (away) the object is, the smaller it is.
*/
int loadActorAnimWithRoomScaling(int actorIndex, const Common::String &animName, int16 x, int16 y);
Fixed8 getActorScaleAtPosition(int16 y);
void addAction(const Action &action);
void addAction(byte type, byte b1, byte b2, byte b3);
void handleAwayMissionAction();
void checkTouchedLoadingZone(int16 x, int16 y);
/**
* Updates any nonzero away mission timers, and invokes ACTION_TIMER_EXPIRED when any one
* reaches 0.
*/
void updateAwayMissionTimers();
/**
* Returns true if the given position in the room is solid (not walkable).
* Reads from a ".map" file which has a bit for each position in the room, which is true
* when that position is solid.
*/
bool isPositionSolid(int16 x, int16 y);
void loadRoomIndex(int roomIndex, int spawnIndex);
Room *getRoom();
// intro.cpp
private:
void playIntro();
void showCreditsScreen(R3 *creditsBuffer, int index, bool deletePrevious = true);
/**
* Initializes an object to spawn at one position and move toward another position.
* @param ticks The number of ticks it should take for the object to reach the destination
*/
void initIntroR3ObjectToMove(R3 *r3, int16 srcAngle, int16 srcDepth, int16 destAngle, int16 destDepth, int16 ticks);
void loadSubtitleSprite(int index, Sprite *sprite);
// space.cpp (pseudo-3d)
void initStarfieldPosition();
void initStarfield(int16 x, int16 y, int16 width, int16 height, int16 arg8);
void addR3(R3 *r3);
void delR3(R3 *r3);
void clearStarfieldPixels();
void drawStarfield();
void updateStarfieldAndShips(bool arg0);
R3 *sub_19f24(R3 *r3);
void drawR3Shape(R3 *r3);
bool sub_1c022(R3 *r3);
Point3 constructPoint3ForStarfield(int16 x, int16 y, int16 z);
Point3 matrixMult(const Matrix &weight, const Point3 &point);
Point3 matrixMult(const Point3 &point, const Matrix &weight);
int32 scaleSpacePosition(int32 x, int32 z);
/**
* Creates an identity matrix
*/
Matrix initMatrix();
Matrix initSpeedMatrixForXZMovement(Angle angle, const Matrix &matrix);
// actors.cpp (handles actors and animations)
public:
void initActors();
/**
* Set an actor's animation, position, and scale.
*/
int loadActorAnim(int actorIndex, const Common::String &animName, int16 x, int16 y, Fixed8 scale);
void loadBanFile(const Common::String &name);
/**
* Tries to make an actor walk to a position.
* Returns true if successful in initiating the walk.
*/
bool actorWalkToPosition(int actorIndex, const Common::String &animFile, int16 srcX, int16 srcY, int16 destX, int16 destY);
void updateActorAnimations();
/**
* ".BAN" files relate to drawing background animations, ie. flashing computer lights.
* "renderBanBelowSprites()" does the work of drawing it, while
* "renderBanAboveSprites()" redraws sprites above them if necessary.
*/
void renderBanBelowSprites();
void renderBan(byte *screenPixels, byte *bgPixels, int banFileIndex);
void renderBanAboveSprites();
void removeActorFromScreen(int actorIndex);
void actorFunc1();
void drawActorToScreen(Actor *actor, const Common::String &animName, int16 x, int16 y, Fixed8 scale, bool addSprite);
void releaseAnim(Actor *actor);
void initStandAnim(int actorIndex);
void updateActorPositionWhileWalking(Actor *actor, int16 x, int16 y);
/**
* Chooses a value for the actor's speed and direction, based on a source position and
* a destination position it's walking to.
*/
void chooseActorDirectionForWalking(Actor *actor, int16 srcX, int16 srcY, int16 destX, int16 destY);
/**
* Returns true if an actor can walk directly from a source position to a destination
* position without running into unwalkable terrain.
*/
bool directPathExists(int16 srcX, int16 srcY, int16 destX, int16 destY);
int findObjectAt(int x, int y);
int findObjectAt(Common::Point p) {
return findObjectAt(p.x, p.y);
}
/**
* Loads a bitmap for the animation frame with the given scale.
*/
Bitmap *loadAnimationFrame(const Common::String &filename, Fixed8 scale);
/**
* Called when the "get" action is first selected. Returns a selected object.
* This behaves like other menus in that it holds game execution, but no actual menu pops
* up; it just waits for the player to select something on the screen.
*/
int selectObjectForUseAction();
Common::String getCrewmanAnimFilename(int actorIndex, const Common::String &basename);
/**
* Checks whether to change the mouse bitmap to have the red outline.
*/
void updateMouseBitmap();
/**
* Checks whether to walk a crewman to a hotspot (the last one obtained from
* a "findObjectAt" call).
*/
bool walkActiveObjectToHotspot();
/**
* Return true if an object is unselectable with the given action?
*/
bool isObjectUnusable(int objectIndex, int action);
/**
* When a crewman is collapsed, they get once a timer reaches 0.
*/
void updateCrewmanGetupTimers();
void showInventoryIcons(bool showItem);
void hideInventoryIcons();
int showInventoryMenu(int x, int y, bool restoreMouse);
void initStarfieldSprite(Sprite *sprite, Bitmap *bitmap, const Common::Rect &rect);
Bitmap *scaleBitmap(Bitmap *bitmap, Fixed8 scale);
/**
* This takes a row of an unscaled bitmap, and copies it to a row of a scaled bitmap.
* This was heavily optimized in the original game (manually constructed an unrolled
* loop).
*/
void scaleBitmapRow(byte *src, byte *dest, uint16 origWidth, uint16 scaledWidth);
// events.cpp
public:
/**
* Checks for all events, and updates Star Trek's event queue if queueEvents is set.
* This does not account for "tick" events (getNextEvent/popNextEvent handle that).
*/
void pollEvents(bool queueEvents = true);
void waitForNextTick(bool queueEvents = true);
void initializeEventsAndMouse();
/**
* Returns false if there is no event waiting. If "poll" is true, this always returns
* something (waits until an event occurs if necessary).
*/
bool getNextEvent(TrekEvent *e, bool poll = true);
void removeNextEvent();
bool popNextEvent(TrekEvent *e, bool poll = true);
void addEventToQueue(const TrekEvent &e);
Common::EventManager *getEventMan() {
return _eventMan;
}
private:
Common::List<TrekEvent> _eventQueue;
bool _mouseMoveEventInQueue;
bool _tickEventInQueue;
uint32 _frameStartMillis;
// textbox.cpp
public:
/**
* Gets one line of text (does not include words that won't fit).
* Returns position of text to continue from, or nullptr if done.
*/
const char *getNextTextLine(const char *text, char *line, int lineWidth);
/**
* Draw a line of text to a standard bitmap (NOT a "TextBitmap", whose pixel array is
* an array of characters, but an actual standard bitmap).
*/
void drawTextLineToBitmap(const char *text, int textLen, int x, int y, Bitmap *bitmap);
String centerTextboxHeader(String headerText);
void getTextboxHeader(String *headerTextOutput, String speakerText, int choiceIndex);
/**
* Text getter for showText which reads from an rdf file.
* Not really used, since it would require hardcoding text locations in RDF files.
* "readTextFromArrayWithChoices" replaces this.
*/
String readTextFromRdf(int choiceIndex, uintptr data, String *headerTextOutput);
/**
* Shows text with the given header and main text.
*/
void showTextbox(String headerText, const String &mainText, int xoffset, int yoffset, byte textColor, int maxTextLines); // TODO: better name. (return type?)
String skipTextAudioPrompt(const String &str);
/**
* Plays an audio prompt, if it exists, and returns the string starting at the end of the
* prompt.
*/
String playTextAudio(const String &str);
/**
* @param rclickCancelsChoice If true, right-clicks return "-1" as choice instead of
* whatever was selected.
*/
int showText(TextGetterFunc textGetter, uintptr var, int xoffset, int yoffset, int textColor, bool loopChoices, int maxTextLines, bool rclickCancelsChoice);
/**
* Returns the number of lines this string will take up in a textbox.
*/
int getNumTextboxLines(const String &str);
String putTextIntoLines(const String &text);
/**
* Creates a blank textbox in a TextBitmap, and initializes a sprite to use it.
*/
TextBitmap *initTextSprite(int *xoffsetPtr, int *yoffsetPtr, byte textColor, int numTextLines, bool withHeader, Sprite *sprite);
/**
* Draws the "main" text (everything but the header at the top) to a TextBitmap.
*/
void drawMainText(TextBitmap *bitmap, int numTextLines, int numTextboxLines, const String &text, bool withHeader);
String readLineFormattedText(TextGetterFunc textGetter, uintptr var, int choiceIndex, TextBitmap *textBitmap, int numTextboxLines, int *numLines);
/**
* Text getter for showText which reads choices from an array of pointers.
* Last element in the array must be an empty string.
*/
String readTextFromArray(int choiceIndex, uintptr data, String *headerTextOutput);
/**
* Similar to above, but shows the choice index when multiple choices are present.
* Effectively replaces the "readTextFromRdf" function.
*/
String readTextFromArrayWithChoices(int choiceIndex, uintptr data, String *headerTextOutput);
Common::String readTextFromFoundComputerTopics(int choiceIndex, uintptr data, String *headerTextOutput);
Common::String showCodeInputBox();
Common::String showComputerInputBox();
void redrawTextInput();
void addCharToTextInputBuffer(char c);
/**
* Shows a textbox that the player can type a string into.
*/
Common::String showTextInputBox(int16 arg0, int16 arg2, const Common::String &headerText);
void initTextInputSprite(int16 arg0, int16 arg2, const Common::String &headerText);
void cleanupTextInputSprite();
private:
char _textInputBuffer[TEXT_INPUT_BUFFER_SIZE];
int16 _textInputCursorPos;
char _textInputCursorChar;
Sprite _textInputSprite;
// menu.cpp
public:
/**
* Returns the index of the button at the given position, or -1 if none.
*/
int getMenuButtonAt(Sprite *sprites, int numSprites, int x, int y);
/**
* This chooses a sprite from the list to place the mouse cursor at. The sprite it chooses
* may be, for example, the top-leftmost one in the list. Exact behaviour is determined by
* the "mode" parameter.
*
* If "containMouseSprite" is a valid index, it's ensured that the mouse is contained
* within it. "mode" should be -1 in this case.
*/
void chooseMousePositionFromSprites(Sprite *sprites, int numSprites, int spriteIndex, int mode);
/**
* Draws or removes the outline on menu buttons when the cursor hovers on them, or leaves
* them.
*/
void drawMenuButtonOutline(Bitmap *bitmap, byte color);
void showOptionsMenu(int x, int y);
void showBridgeMenu(Common::String menu, int x, int y);
/**
* Show the "action selection" menu, ie. look, talk, etc.
*/
int showActionMenu();
/**
* Loads a .MNU file, which is a list of buttons to display.
*/
void loadMenuButtons(String mnuFilename, int xpos, int ypos);
/**
* Sets which buttons are visible based on the given bitmask.
*/
void setVisibleMenuButtons(uint32 bits);
/**
* Disables the given bitmask of buttons.
*/
void disableMenuButtons(uint32 bits);
void enableMenuButtons(uint32 bits);
/**
* This returns either a special menu event (negative number) or the retval of the button
* clicked (usually an index, always positive).
*/
int handleMenuEvents(uint32 ticksUntilClickingEnabled, bool inTextbox);
void unloadMenuButtons();
/**
* Sets the mouse bitmap based on which action is selected.
*/
void chooseMouseBitmapForAction(int action, bool withRedOutline);
void showQuitGamePrompt(int x, int y);
void showGameOverMenu();
/**
* This can be called from startup or from the options menu.
* On startup, this tries to load the setting without user input.
*/
void showTextConfigurationMenu(bool fromOptionMenu);
int loadTextDisplayMode();
void saveTextDisplayMode(int value);
/**
* Show the republic map, only used in mission 7.
*/
void showRepublicMap(int16 arg0, int16 turbolift);
/**
* Checks the mouse position to return and index for the area selected.
*/
int getRepublicMapAreaAtMouse();
/**
* Same as above, but returns 6 or 7 as error conditions (can't reach due to radiation
* or wrong turbolift).
*/
int getRepublicMapAreaOrFailure(int16 turbolift);
private:
int16 _textDisplayMode;
uint32 _textboxVar2;
uint16 _textboxVar6;
bool _textboxHasMultipleChoices;
Menu *_activeMenu;
// Saved value of StarTrekEngine::_keyboardControlsMouse when menus are up
bool _keyboardControlsMouseOutsideMenu;
// saveload.cpp
public:
bool showSaveMenu();
bool showLoadMenu();
bool saveGame(int slot, Common::String desc);
bool loadGame(int slot);
/**
* Call this after loading "saveOrLoadMetadata" to load all the data pertaining to game
* execution.
*/
bool saveOrLoadGameData(Common::SeekableReadStream *in, Common::WriteStream *out, SavegameMetadata *meta);
Common::String getSavegameFilename(int slotId) const;
// detection.cpp
public:
const StarTrekGameDescription *_gameDescription;
uint32 getFeatures() const;
Common::Platform getPlatform() const;
uint8 getGameType() const;
Common::Language getLanguage() const;
// _screenName = _missionName + _roomIndex
Common::String getScreenName() const {
return _missionName + (char)(_roomIndex + '0');
}
// Variables
public:
int _gameMode;
int _lastGameMode;
bool _resetGameMode;
// NOTE: this has a different meaning than the original game. When non-empty, a new
// room load is triggered, as opposed to original behaviour where this was only read
// when "loadRoom" was called.
Common::String _missionToLoad;
int _roomIndexToLoad;
int _spawnIndexToLoad;
Common::String _missionName;
int _roomIndex;
Common::MemoryReadStreamEndian *_mapFile;
Fixed16 _playerActorScale;
// Queue of "actions" (ie. next frame, clicked on object) for away mission or bridge
Common::Queue<Action> _actionQueue;
AwayMission _awayMission;
bool _warpHotspotsActive;
int16 _activeWarpHotspot;
int16 _activeDoorWarpHotspot;
int16 _lookActionBitmapIndex;
Item _itemList[NUM_OBJECTS];
Actor _actorList[NUM_ACTORS];
Actor *const _kirkActor;
Actor *const _spockActor;
Actor *const _mccoyActor;
Actor *const _redshirtActor;
// ".BAN" files provide extra miscellaneous animations in the room, ie. flashing
// pixels on computer consoles, or fireflies in front of the screen.
Common::MemoryReadStreamEndian *_banFiles[MAX_BAN_FILES];
uint16 _banFileOffsets[MAX_BAN_FILES];
Sprite _inventoryIconSprite;
Sprite _itemIconSprite;
// Certain hotspots store a position value where objects must walk to before
// interacting with them. After calling "findObjectAt", these values are updated.
bool _objectHasWalkPosition;
Common::Point _objectWalkPosition;
// Actions to perform after a crewman finishes walking to a position.
// Room-specific code can specify that a specific action of type
// "ACTION_FINISHED_WALKING" occurs after moving a crewman somewhere.
Action _actionOnWalkCompletion[MAX_BUFFERED_WALK_ACTIONS];
bool _actionOnWalkCompletionInUse[MAX_BUFFERED_WALK_ACTIONS];
// _clockTicks is based on DOS interrupt 1A, AH=0; read system clock counter.
// Updates 18.206 times every second.
uint32 _clockTicks;
uint32 _frameIndex;
uint32 _roomFrameCounter; // Resets to 0 on loading a room
bool _musicEnabled;
bool _sfxEnabled;
uint16 _word_467a6;
uint16 _musicWorking;
bool _sfxWorking;
bool _finishedPlayingSpeech;
bool _mouseControllingShip;
// TODO: make this work.
// When false, the keyboard generally acts in a more specific way (ie. move mouse
// between items in a menu).
bool _keyboardControlsMouse;
bool _inQuitGameMenu;
bool _showSubtitles;
byte _byte_45b3c;
// Pseudo-3D / starfield stuff
Sprite _starfieldSprite;
Star _starList[NUM_STARS];
Point3 _starfieldPosition;
int32 _starfieldPointDivisor;
int16 _starfieldXVar1, _starfieldYVar1;
int16 _starfieldXVar2, _starfieldYVar2;
Common::Rect _starfieldRect;
R3 _enterpriseR3;
R3 *_r3List[NUM_SPACE_OBJECTS];
R3 *_orderedR3List[NUM_SPACE_OBJECTS];
Matrix _starPositionMatrix;
Matrix _someMatrix;
float _flt_50898;
Graphics *_gfx;
Sound *_sound;
IWFile *_iwFile;
Resource *_resource;
private:
int leftClickEvent();
int rightClickEvent();
int mouseMoveEvent();
int lookupNextAction(const int *lookupArray, int action);
void loadBridgeComputerTopics();
void bridgeLeftClick();
Common::RandomSource _randomSource;
Common::SineTable _sineTable;
Common::CosineTable _cosineTable;
Room *_room;
Common::List<ComputerTopic> _computerTopics;
};
// Static function
bool saveOrLoadMetadata(Common::SeekableReadStream *in, Common::WriteStream *out, SavegameMetadata *meta);
} // End of namespace StarTrek
#endif