scummvm/scumm/scumm.h
Eugene Sandulenko a9ceee26d8 Turned HE Mac resource filename generator into generall, whole SCUMM-purpose
method. Right now it is used to eliminate those Windows HE titles which
have different target base names.

If you want to use it, then define another entry in substDataFileNameTable[].
If your version with different base name has other features then you need
to define GF_MULTIPLE_VERSIONS for main entry and add any additional
entries to multiple_versions_md5_settings based on MD5 of the entry.

svn-id: r16764
2005-02-11 03:45:10 +00:00

1317 lines
34 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2005 The ScummVM project
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header$
*
*/
#ifndef SCUMM_H
#define SCUMM_H
#include "base/engine.h"
#include "common/file.h"
#include "common/map.h"
#include "common/rect.h"
#include "common/str.h"
#include "scumm/gfx.h"
#include "scumm/script.h"
#include "scumm/util.h"
namespace GUI {
class Dialog;
}
using GUI::Dialog;
class GameDetector;
namespace Scumm {
class Actor;
class BaseCostumeRenderer;
class CharsetRenderer;
class IMuse;
class IMuseDigital;
class Insane;
class MusicEngine;
class ScummEngine;
class ScummDebugger;
class Serializer;
class Sound;
struct Box;
struct BoxCoords;
struct FindObjectInRoom;
struct ScummGameSettings;
typedef Common::Map<Common::String, int> ObjectIDMap;
// Use g_scumm from error() ONLY
extern ScummEngine *g_scumm;
/* System Wide Constants */
enum {
NUM_SENTENCE = 6,
NUM_SHADOW_PALETTE = 8,
KEY_ALL_SKIP = 3457 // WinCE
};
/** SCUMM feature flags. */
enum GameFeatures {
GF_NEW_OPCODES = 1 << 0,
GF_NEW_CAMERA = 1 << 1,
GF_NEW_COSTUMES = 1 << 2,
GF_DIGI_IMUSE = 1 << 3,
GF_USE_KEY = 1 << 4,
GF_DRAWOBJ_OTHER_ORDER = 1 << 5,
GF_SMALL_HEADER = 1 << 6,
GF_SMALL_NAMES = 1 << 7,
GF_OLD_BUNDLE = 1 << 8,
GF_16COLOR = 1 << 9,
GF_OLD256 = 1 << 10,
GF_AUDIOTRACKS = 1 << 11,
GF_NO_SCALING = 1 << 12,
GF_FEW_LOCALS = 1 << 13,
GF_HUMONGOUS = 1 << 14,
GF_MULTIPLE_VERSIONS = 1 << 15,
GF_FMTOWNS = 1 << 17,
GF_AMIGA = 1 << 18,
GF_NES = 1 << 19,
GF_ATARI_ST = 1 << 20,
GF_MACINTOSH = 1 << 21,
GF_PC = 1 << 22,
GF_WINDOWS = 1 << 23,
GF_DEMO = 1 << 24,
GF_EXTERNAL_CHARSET = GF_SMALL_HEADER
};
enum ObjectClass {
kObjectClassNeverClip = 20,
kObjectClassAlwaysClip = 21,
kObjectClassIgnoreBoxes = 22,
kObjectClassYFlip = 29,
kObjectClassXFlip = 30,
kObjectClassPlayer = 31, // Actor is controlled by the player
kObjectClassUntouchable = 32
};
/* SCUMM Debug Channels */
void CDECL debugC(int level, const char *s, ...);
struct dbgChannelDesc {
const char *channel, *desc;
uint32 flag;
};
enum {
DEBUG_GENERAL = 1 << 0, // General debug
DEBUG_SCRIPTS = 1 << 2, // Track script execution (start/stop/pause)
DEBUG_OPCODES = 1 << 3, // Track opcode invocations
DEBUG_VARS = 1 << 4, // Track variable changes
DEBUG_RESOURCE = 1 << 5, // Track resource loading / allocation
DEBUG_IMUSE = 1 << 6, // Track iMUSE events
DEBUG_SOUND = 1 << 7, // General Sound Debug
DEBUG_ACTORS = 1 << 8, // General Actor Debug
DEBUG_INSANE = 1 << 9, // Track INSANE
DEBUG_SMUSH = 1 << 10 // Track SMUSH
};
// Debug channel lookup table for Debugger console
static const dbgChannelDesc debugChannels[] = {
{"SCRIPTS", "Track script execution", DEBUG_SCRIPTS},
{"OPCODES", "Track opcode execution", DEBUG_OPCODES},
{"IMUSE", "Track iMUSE events", DEBUG_IMUSE},
{"RESOURCE", "Track resource loading/management", DEBUG_RESOURCE},
{"VARS", "Track variable changes", DEBUG_VARS},
{"ACTORS", "Actor-related debug", DEBUG_ACTORS},
{"SOUND", "Sound related debug", DEBUG_SOUND},
{"INSANE", "Track INSANE", DEBUG_INSANE},
{"SMUSH", "Track SMUSH", DEBUG_SMUSH}
};
struct MemBlkHeader {
uint32 size;
};
struct VerbSlot;
struct ObjectData;
struct BlastText {
int16 xpos, ypos;
Common::Rect rect;
byte color;
byte charset;
bool center;
byte text[256];
};
struct V2MouseoverBox {
Common::Rect rect;
byte color;
byte hicolor;
};
enum ResTypes {
rtFirst = 1,
rtRoom = 1,
rtScript = 2,
rtCostume = 3,
rtSound = 4,
rtInventory = 5,
rtCharset = 6,
rtString = 7,
rtVerb = 8,
rtActorName = 9,
rtBuffer = 10,
rtScaleTable = 11,
rtTemp = 12,
rtFlObject = 13,
rtMatrix = 14,
rtBox = 15,
rtObjectName = 16,
rtRoomScripts = 17,
rtRoomImage = 18,
rtImage = 19,
rtTalkie = 20,
rtLast = 20,
rtNumTypes = 21
};
enum {
LIGHTMODE_dark = 0,
LIGHTMODE_actor_base = 1,
LIGHTMODE_screen = 2,
LIGHTMODE_flashlight = 4,
LIGHTMODE_actor_color = 8
};
enum {
MBS_LEFT_CLICK = 0x8000,
MBS_RIGHT_CLICK = 0x4000,
MBS_MOUSE_MASK = (MBS_LEFT_CLICK | MBS_RIGHT_CLICK),
MBS_MAX_KEY = 0x0200
};
enum ScummGameId {
GID_TENTACLE,
GID_MONKEY2,
GID_INDY4,
GID_MONKEY,
GID_SAMNMAX,
GID_MONKEY_EGA,
GID_PASS,
GID_LOOM256,
GID_ZAK256,
GID_INDY3,
GID_LOOM,
GID_FT,
GID_DIG,
GID_MONKEY_VGA,
GID_CMI,
GID_MANIAC,
GID_ZAK,
GID_MONKEY_SEGA,
GID_HEGAME, // Generic name for all HE games with default behaviour
GID_PUTTDEMO,
GID_PUTTMOON,
GID_FBEAR,
GID_FUNPACK,
GID_FREDDI4
};
struct SentenceTab {
byte verb;
byte preposition;
uint16 objectA;
uint16 objectB;
uint8 freezeCount;
};
struct StringSlot {
int16 xpos;
int16 ypos;
int16 right;
byte color;
byte charset;
bool center;
bool overhead;
bool no_talk_anim;
};
struct StringTab : StringSlot {
// The 'default' values for this string slot. This is used so that the
// string slot can temporarily be set to different values, and then be
// easily reset to a previously set default.
StringSlot _default;
void saveDefault() {
StringSlot &s = *this;
_default = s;
}
void loadDefault() {
StringSlot &s = *this;
s = _default;
}
};
enum WhereIsObject {
WIO_NOT_FOUND = -1,
WIO_INVENTORY = 0,
WIO_ROOM = 1,
WIO_GLOBAL = 2,
WIO_LOCAL = 3,
WIO_FLOBJECT = 4
};
struct LangIndexNode {
char tag[12+1];
int32 offset;
};
struct AuxBlock {
bool visible;
Common::Rect r;
};
struct AuxEntry {
int actorNum;
int subIndex;
};
class ScummEngine : public Engine {
friend class ScummDebugger;
friend class SmushPlayer;
friend class Insane;
friend class CharsetRenderer;
void errorString(const char *buf_input, char *buf_output);
public:
/* Put often used variables at the top.
* That results in a shorter form of the opcode
* on some architectures. */
IMuse *_imuse;
IMuseDigital *_imuseDigital;
MusicEngine *_musicEngine;
Sound *_sound;
VerbSlot *_verbs;
ObjectData *_objs;
ScummDebugger *_debugger;
// Core variables
byte _gameId;
byte _version;
byte _heversion;
byte _numActors;
uint32 _features; // Should only be accessed for reading (TODO enforce it compiler-wise with making it private and creating an accessor)
uint8 _gameMD5[16];
/** Random number generator */
Common::RandomSource _rnd;
/** Graphics manager */
Gdi gdi;
protected:
/** Central resource data. */
struct {
byte mode[rtNumTypes];
uint16 num[rtNumTypes];
uint32 tags[rtNumTypes];
const char *name[rtNumTypes];
byte **address[rtNumTypes];
byte *flags[rtNumTypes];
byte *roomno[rtNumTypes];
uint32 *roomoffs[rtNumTypes];
uint32 *globsize[rtNumTypes];
} res;
VirtualMachineState vm;
public:
// Constructor / Destructor
ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]);
virtual ~ScummEngine();
/** Startup function: Calls mainInit and then mainRun. */
int go();
// Init functions
int init(GameDetector &detector);
virtual void setupScummVars();
void initScummVars();
virtual void scummInit();
void loadCJKFont();
void setupMusic(int midi);
void setupVolumes();
// Scumm main loop
int scummLoop(int delta);
// Event handling
void parseEvents();
void waitForTimer(int msec_delay);
void processKbd(bool smushMode);
void clearClickedStatus();
// Misc utility functions
uint32 _debugFlags;
const char *getGameName() const { return _gameName.c_str(); }
// Cursor/palette
void updateCursor();
virtual void animateCursor() {}
void updatePalette();
virtual void saveOrLoadCursorImages(Serializer *s) {}
/**
* Flag which signals that the SMUSH video playback should end now
* (e.g. because it was aborted by the user or it's simply finished).
*/
bool _smushVideoShouldFinish;
/** This flag is a hack to allow the pause dialog to pause SMUSH playback, too. */
bool _smushPaused;
/** This flag tells IMuseDigital that INSANE is running. */
bool _insaneRunning;
protected:
Insane *_insane;
public:
void pauseGame();
void restart();
void shutDown();
/** We keep running until this is set to true. */
bool _quit;
protected:
Dialog *_pauseDialog;
Dialog *_versionDialog;
Dialog *_optionsDialog;
Dialog *_mainMenuDialog;
protected:
int runDialog(Dialog &dialog);
void confirmexitDialog();
void confirmrestartDialog();
void pauseDialog();
void versionDialog();
void mainMenuDialog();
public:
void optionsDialog(); // Used by MainMenuDialog::handleCommand()
protected:
char displayMessage(const char *altButton, const char *message, ...);
protected:
byte _fastMode;
Actor *_actors; // Has _numActors elements
byte *_arraySlot;
uint16 *_inventory;
uint16 *_newNames;
public:
// VAR is a wrapper around scummVar, which attempts to include additional
// useful information should an illegal var access be detected.
#define VAR(x) scummVar(x, #x, __FILE__, __LINE__)
int32& scummVar(byte var, const char *varName, const char *file, int line)
{
if (var == 0xFF) {
error("Illegal access to variable %s in file %s, line %d", varName, file, line);
}
return _scummVars[var];
}
int32 scummVar(byte var, const char *varName, const char *file, int line) const
{
if (var == 0xFF) {
error("Illegal access to variable %s in file %s, line %d", varName, file, line);
}
return _scummVars[var];
}
protected:
int16 _varwatch;
int32 *_roomVars;
int32 *_scummVars;
byte *_bitVars;
/* Global resource tables */
int _numVariables, _numBitVariables, _numLocalObjects;
int _numGlobalObjects, _numArray, _numVerbs, _numFlObject;
int _numInventory;
int _numNewNames, _numGlobalScripts;
int _numRoomVariables;
int _numPalettes, _numSprites, _numTalkies, _numUnk;
public:
int _numLocalScripts, _numImages, _numRooms, _numScripts, _numSounds; // Used by HE games
int _numCostumes; // FIXME - should be protected, used by Actor::remapActorPalette
int _numCharsets; // FIXME - should be protected, used by CharsetRenderer
BaseCostumeRenderer* _costumeRenderer;
char *_audioNames;
int32 _numAudioNames;
protected:
/* Current objects - can go in their respective classes */
byte _curActor;
int _curVerb;
int _curVerbSlot;
int _curPalIndex;
public:
byte _currentRoom; // FIXME - should be protected but Actor::isInCurrentRoom uses it
int _roomResource; // FIXME - should be protected but Sound::pauseSounds uses it
bool _egoPositioned; // Used by Actor::putActor, hence public
int generateSubstResFileName(const char *filename, char *buf, int bufsize, int cont = 0, int index = 0);
int _substResFileNameIndex;
protected:
int _keyPressed;
uint16 _lastKeyHit;
bool _keyDownMap[512]; // FIXME - 512 is a guess. it's max(kbd.ascii)
Common::Point _mouse;
Common::Point _virtualMouse;
uint16 _mouseButStat;
byte _leftBtnPressed, _rightBtnPressed;
/** The bootparam, to be passed to the script 1, the bootscript. */
int _bootParam;
// Various options useful for debugging
bool _dumpScripts;
bool _hexdumpScripts;
bool _showStack;
uint16 _debugMode;
// Save/Load class - some of this may be GUI
byte _saveLoadFlag, _saveLoadSlot;
uint32 _lastSaveTime;
bool _saveTemporaryState;
char _saveLoadName[32];
bool saveState(int slot, bool compat);
bool loadState(int slot, bool compat);
void saveOrLoad(Serializer *s, uint32 savegameVersion);
void saveLoadResource(Serializer *ser, int type, int index); // "Obsolete"
void saveResource(Serializer *ser, int type, int index);
void loadResource(Serializer *ser, int type, int index);
void makeSavegameName(char *out, int slot, bool compatible);
int getKeyState(int key);
public:
bool getSavegameName(int slot, char *desc);
void listSavegames(bool *marks, int num);
void requestSave(int slot, const char *name, bool compatible = false);
void requestLoad(int slot);
void lock(int type, int i);
void unlock(int type, int i);
protected:
/* Heap and memory management */
uint32 _maxHeapThreshold, _minHeapThreshold;
/* Script VM - should be in Script class */
uint32 _localScriptOffsets[256];
const byte *_scriptPointer, *_scriptOrgPointer;
byte _opcode, _currentScript;
uint16 _curExecScript;
const byte * const *_lastCodePtr;
int _resultVarNumber, _scummStackPos;
int _vmStack[150];
int _keyScriptKey, _keyScriptNo;
virtual void setupOpcodes() = 0;
virtual void executeOpcode(byte i) = 0;
virtual const char *getOpcodeDesc(byte i) = 0;
void initializeLocals(int slot, int *vars);
int getScriptSlot();
void startScene(int room, Actor *a, int b);
void startManiac();
public:
void runScript(int script, bool freezeResistant, bool recursive, int *lvarptr);
void stopScript(int script);
void nukeArrays(byte script);
protected:
void runObjectScript(int script, int entry, bool freezeResistant, bool recursive, int *vars, int slot = -1);
void runScriptNested(int script);
void executeScript();
void updateScriptPtr();
void runInventoryScript(int i);
void checkAndRunSentenceScript();
void runExitScript();
void runEntryScript();
void runAllScripts();
void freezeScripts(int scr);
void unfreezeScripts();
bool isScriptInUse(int script) const;
bool isRoomScriptRunning(int script) const;
bool isScriptRunning(int script) const;
void killAllScriptsExceptCurrent();
void killScriptsAndResources();
void decreaseScriptDelay(int amount);
void stopObjectCode();
void stopObjectScript(int script);
void getScriptBaseAddress();
void getScriptEntryPoint();
int getVerbEntrypoint(int obj, int entry);
byte fetchScriptByte();
virtual uint fetchScriptWord();
virtual int fetchScriptWordSigned();
void ignoreScriptWord() { fetchScriptWord(); }
void ignoreScriptByte() { fetchScriptByte(); }
virtual void getResultPos();
void setResult(int result);
void push(int a);
int pop();
virtual int readVar(uint var);
virtual void writeVar(uint var, int value);
void beginCutscene(int *args);
void endCutscene();
void abortCutscene();
void beginOverride();
void endOverride();
void copyScriptString(byte *dst);
int resStrLen(const byte *src) const;
void doSentence(int c, int b, int a);
/* Should be in Resource class */
ScummFile _fileHandle;
uint32 _fileOffset;
public:
/** The name of the (macintosh/rescumm style) container file, if any. */
Common::String _containerFile;
bool openFile(ScummFile &file, const char *filename);
protected:
int _resourceHeaderSize;
Common::String _gameName; // This is the name we use for opening resource files
Common::String _targetName; // This is the game the user calls it, so use for saving
bool _dynamicRoomOffsets;
byte _resourceMapper[128];
uint32 _allocatedSize;
byte _expire_counter;
byte *_heV7RoomOffsets;
uint32 *_heV7RoomIntOffsets;
const byte *_resourceLastSearchBuf; // FIXME: need to put it to savefile?
uint32 _resourceLastSearchSize; // FIXME: need to put it to savefile?
void allocateArrays();
void openRoom(int room);
void closeRoom();
void deleteRoomOffsets();
void readRoomsOffsets();
void askForDisk(const char *filename, int disknum);
bool openResourceFile(const char *filename, byte encByte);
void loadPtrToResource(int type, int i, const byte *ptr);
void readResTypeList(int id, uint32 tag, const char *name);
void allocResTypeData(int id, uint32 tag, int num, const char *name, int mode);
byte *createResource(int type, int index, uint32 size);
int loadResource(int type, int i);
void nukeResource(int type, int i);
int getResourceSize(int type, int idx);
public:
bool isResourceLoaded(int type, int index) const;
byte *getResourceAddress(int type, int i);
byte *getStringAddress(int i);
byte *getStringAddressVar(int i);
void ensureResourceLoaded(int type, int i);
int getResourceRoomNr(int type, int index);
protected:
int readSoundResource(int type, int index);
int convert_extraflags(byte *ptr, byte * src_ptr);
void convertMac0Resource(int type, int index, byte *ptr, int size);
void convertADResource(int type, int index, byte *ptr, int size);
int readSoundResourceSmallHeader(int type, int index);
void setResourceCounter(int type, int index, byte flag);
bool validateResource(const char *str, int type, int index) const;
void increaseResourceCounter();
bool isResourceInUse(int type, int i) const;
void initRoomSubBlocks();
void clearRoomObjects();
void loadRoomObjects();
void loadRoomObjectsSmall();
void loadRoomObjectsOldBundle();
virtual void readArrayFromIndexFile();
virtual void readMAXS(int blockSize);
virtual void readIndexFile();
virtual void loadCharset(int i);
void nukeCharset(int i);
int _lastLoadedRoom;
public:
const byte *findResourceData(uint32 tag, const byte *ptr);
const byte *findResource(uint32 tag, const byte *ptr);
int getResourceDataSize(const byte *ptr) const;
void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
protected:
void resourceStats();
void expireResources(uint32 size);
void freeResources();
public:
/* Should be in Object class */
byte OF_OWNER_ROOM;
int getInventorySlot();
int findInventory(int owner, int index);
int getInventoryCount(int owner);
protected:
byte *_objectOwnerTable, *_objectRoomTable, *_objectStateTable;
ObjectIDMap _objectIDMap;
int _numObjectsInRoom;
void setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
void markObjectRectAsDirty(int obj);
void loadFlObject(uint object, uint room);
void nukeFlObjects(int min, int max);
int findFlObjectSlot();
int findLocalObjectSlot();
void addObjectToInventory(uint obj, uint room);
void fixObjectFlags();
public:
bool getClass(int obj, int cls) const; // Used in actor.cpp, hence public
protected:
void putClass(int obj, int cls, bool set);
int getState(int obj);
void putState(int obj, int state);
void setObjectState(int obj, int state, int x, int y);
int getOwner(int obj) const;
void putOwner(int obj, int owner);
void setOwnerOf(int obj, int owner);
void clearOwnerOf(int obj);
int getObjectRoom(int obj) const;
int getObjX(int obj);
int getObjY(int obj);
void getObjectXYPos(int object, int &x, int &y) { int dir; getObjectXYPos(object, x, y, dir); }
void getObjectXYPos(int object, int &x, int &y, int &dir);
int getObjOldDir(int obj);
int getObjNewDir(int obj);
int getObjectIndex(int object) const;
int getObjectImageCount(int object);
int whereIsObject(int object) const;
int findObject(int x, int y);
void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
public:
int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public
protected:
int getObjActToObjActDist(int a, int b); // Not sure how to handle
const byte *getObjOrActorName(int obj); // these three..
void setObjectName(int obj);
void addObjectToDrawQue(int object);
void removeObjectFromDrawQue(int object);
void clearDrawObjectQueue();
void processDrawQue();
uint32 getOBCDOffs(int object) const;
byte *getOBCDFromObject(int obj);
const byte *getOBIMFromObject(const ObjectData &od);
const byte *getObjectImage(const byte *ptr, int state);
int getDistanceBetween(bool is_obj_1, int b, int c, bool is_obj_2, int e, int f);
protected:
/* Should be in Verb class */
uint16 _verbMouseOver;
int _inventoryOffset;
int8 _userPut;
uint16 _userState;
void redrawVerbs();
void checkExecVerbs();
void verbMouseOver(int verb);
int findVerbAtPos(int x, int y) const;
void drawVerb(int verb, int mode);
void runInputScript(int a, int cmd, int mode);
void restoreVerbBG(int verb);
void drawVerbBitmap(int verb, int x, int y);
int getVerbSlot(int id, int mode) const;
void killVerb(int slot);
void setVerbObject(uint room, uint object, uint verb);
// TODO: This should be moved into ScummEngine_v2 if possible
V2MouseoverBox v2_mouseover_boxes[7];
int8 v2_mouseover_box;
void checkV2MouseOver(Common::Point pos);
void checkV2Inventory(int x, int y);
void redrawV2Inventory();
public:
/* Should be in Actor class */
Actor *derefActor(int id, const char *errmsg = 0) const;
Actor *derefActorSafe(int id, const char *errmsg) const;
uint32 *_classData;
int getAngleFromPos(int x, int y) const;
protected:
void walkActors();
void playActorSounds();
void setActorRedrawFlags();
void putActors();
void showActors();
void setupV1ActorTalkColor();
void resetActorBgs();
void processActors();
void processUpperActors();
int getActorFromPos(int x, int y);
bool isCostumeInUse(int i) const;
public:
/* Actor AuxQueue stuff (HE) */
AuxBlock _auxBlocks[16];
uint16 _auxBlocksNum;
AuxEntry _auxEntries[16];
uint16 _auxEntriesNum;
void preProcessAuxQueue();
void postProcessAuxQueue();
void queueAuxBlock(Actor *a);
void queueAuxEntry(int actorNum, int subIndex);
public:
/* Actor talking stuff */
byte _actorToPrintStrFor, _V1TalkingActor;
int _sentenceNum;
SentenceTab _sentence[NUM_SENTENCE];
StringTab _string[6];
int16 _talkDelay;
void actorTalk(const byte *msg);
void stopTalk();
int getTalkingActor(); // Wrapper around VAR_TALK_ACTOR for V1 Maniac
void setTalkingActor(int variable);
// Costume class
void cost_decodeData(Actor *a, int frame, uint usemask);
int cost_frameToAnim(Actor *a, int frame);
// Akos Class
struct {
int16 cmd;
int16 actor;
int16 param1;
int16 param2;
} _akosQueue[32];
int16 _akosQueuePos;
Common::Rect _actorClipOverride;
bool akos_increaseAnims(const byte *akos, Actor *a);
bool akos_increaseAnim(Actor *a, int i, const byte *aksq, const uint16 *akfo, int numakfo);
void akos_queCommand(byte cmd, Actor *a, int param_1, int param_2);
void akos_processQueue();
void akos_decodeData(Actor *a, int frame, uint usemask);
int akos_frameToAnim(Actor *a, int frame);
bool akos_hasManyDirections(int costume);
protected:
/* Should be in Graphics class? */
uint16 _screenB, _screenH;
public:
int _roomHeight, _roomWidth;
int _screenHeight, _screenWidth;
VirtScreen virtscr[4]; // Virtual screen areas
CameraData camera; // 'Camera' - viewport
int _screenStartStrip, _screenEndStrip;
int _screenTop;
protected:
ColorCycle _colorCycle[16]; // Palette cycles
uint32 _ENCD_offs, _EXCD_offs;
uint32 _CLUT_offs, _EPAL_offs;
uint32 _IM00_offs, _PALS_offs;
StripTable *_roomStrips;
//ender: fullscreen
bool _fullRedraw, _bgNeedsRedraw;
bool _screenEffectFlag, _completeScreenRedraw;
struct {
int hotspotX, hotspotY, width, height;
byte animate, animateIndex;
int8 state;
} _cursor;
byte _grabbedCursor[8192];
byte _currentCursor;
byte _newEffect, _switchRoomEffect2, _switchRoomEffect;
bool _doEffect;
byte *_scrollBuffer;
struct {
int x, y, w, h;
byte *buffer;
uint16 xStrips, yStrips;
bool isDrawn;
} _flashlight;
public:
bool isLightOn() const;
protected:
void initScreens(int b, int h);
void initVirtScreen(VirtScreenNumber slot, int number, int top, int width, int height, bool twobufs, bool scrollable);
void initBGBuffers(int height);
void initCycl(const byte *ptr); // Color cycle
void drawObject(int obj, int arg);
void drawRoomObjects(int arg);
void drawRoomObject(int i, int arg);
void drawBox(int x, int y, int x2, int y2, int color);
void restoreBG(Common::Rect rect, byte backColor = 0);
void redrawBGStrip(int start, int num);
virtual void redrawBGAreas();
void cameraMoved();
void setCameraAtEx(int at);
virtual void setCameraAt(int pos_x, int pos_y);
virtual void setCameraFollows(Actor *a);
virtual void moveCamera();
virtual void panCameraTo(int x, int y);
void clampCameraPos(Common::Point *pt);
void actorFollowCamera(int act);
const byte *getPalettePtr(int palindex, int room);
void setupAmigaPalette();
void setupEGAPalette();
void setupV1ManiacPalette();
void setupV1ZakPalette();
void setPalette(int pal, int room);
void setPaletteFromPtr(const byte *ptr, int numcolor = -1);
void setPalColor(int index, int r, int g, int b);
void setDirtyColors(int min, int max);
const byte *findPalInPals(const byte *pal, int index);
void swapPalColors(int a, int b);
void copyPalColor(int dst, int src);
void cyclePalette();
void stopCycle(int i);
virtual void palManipulateInit(int resID, int start, int end, int time);
void palManipulate();
public:
int remapPaletteColor(int r, int g, int b, int threshold); // Used by Actor::remapActorPalette
protected:
void moveMemInPalRes(int start, int end, byte direction);
void setupShadowPalette(int slot, int redScale, int greenScale, int blueScale, int startColor, int endColor);
void setupShadowPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor, int start, int end);
void darkenPalette(int redScale, int greenScale, int blueScale, int startColor, int endColor);
void desaturatePalette(int hueScale, int satScale, int lightScale, int startColor, int endColor);
void setupCursor();
void setCursorFromBuffer(byte *ptr, int width, int height, int pitch);
public:
void markRectAsDirty(VirtScreenNumber virt, int left, int right, int top, int bottom, int dirtybit = 0);
void markRectAsDirty(VirtScreenNumber virt, const Common::Rect& rect, int dirtybit = 0) {
markRectAsDirty(virt, rect.left, rect.right, rect.top, rect.bottom, dirtybit);
}
protected:
void drawDirtyScreenParts();
void updateDirtyScreen(VirtScreenNumber slot);
public:
VirtScreen *findVirtScreen(int y);
byte *getMaskBuffer(int x, int y, int z);
protected:
void drawFlashlight();
void fadeIn(int effect);
void fadeOut(int effect);
void unkScreenEffect5(int a);
void unkScreenEffect6();
void transitionEffect(int a);
void dissolveEffect(int width, int height);
void scrollEffect(int dir);
// bomp
public:
byte *_bompActorPalettePtr;
void drawBomp(const BompDrawData &bd, bool mirror);
protected:
bool _shakeEnabled;
uint _shakeFrame;
void setShake(int mode);
int _blastObjectQueuePos;
BlastObject _blastObjectQueue[128];
int _blastTextQueuePos;
BlastText _blastTextQueue[50];
void enqueueText(const byte *text, int x, int y, byte color, byte charset, bool center);
void drawBlastTexts();
void removeBlastTexts();
void enqueueObject(int objectNumber, int objectX, int objectY, int objectWidth,
int objectHeight, int scaleX, int scaleY, int image, int mode);
void clearEnqueue() { _blastObjectQueuePos = 0; }
void drawBlastObjects();
void drawBlastObject(BlastObject *eo);
void removeBlastObjects();
void removeBlastObject(BlastObject *eo);
int _drawObjectQueNr;
byte _drawObjectQue[200];
/* For each of the 410 screen strips, gfxUsageBits contains a
* bitmask. The lower 80 bits each correspond to one actor and
* signify if any part of that actor is currently contained in
* that strip.
*
* If the leftmost bit is set, the strip (background) is dirty
* needs to be redrawn.
*
* The second leftmost bit is set by removeBlastObject() and
* restoreBG(), but I'm not yet sure why.
*/
uint32 gfxUsageBits[410 * 3];
void upgradeGfxUsageBits();
void setGfxUsageBit(int strip, int bit);
void clearGfxUsageBit(int strip, int bit);
bool testGfxUsageBit(int strip, int bit);
bool testGfxAnyUsageBits(int strip);
bool testGfxOtherUsageBits(int strip, int bit);
public:
byte _HEV7ActorPalette[256];
byte _roomPalette[256];
byte *_shadowPalette;
bool _skipDrawObject, _skipProcessActors;
int _timers[4];
protected:
int _shadowPaletteSize;
byte _currentPalette[3 * 256];
int _palDirtyMin, _palDirtyMax;
byte _palManipStart, _palManipEnd;
uint16 _palManipCounter;
byte *_palManipPalette;
byte *_palManipIntermediatePal;
byte _haveMsg;
bool _useTalkAnims;
uint16 _defaultTalkDelay;
int _tempMusic;
int _saveSound;
bool _native_mt32;
int _midi;
int _midiDriver; // Use the MD_ values from mididrv.h
bool _copyProtection;
bool _demoMode;
bool _confirmExit;
public:
uint16 _extraBoxFlags[65];
byte getNumBoxes();
byte *getBoxMatrixBaseAddr();
int getPathToDestBox(byte from, byte to);
void getGates(int trap1, int trap2, Common::Point gateA[2], Common::Point gateB[2]);
bool inBoxQuickReject(int box, int x, int y, int threshold);
int getClosestPtOnBox(int box, int x, int y, int16& outX, int16& outY);
int getSpecialBox(int param1, int param2);
void setBoxFlags(int box, int val);
void setBoxScale(int box, int b);
bool checkXYInBoxBounds(int box, int x, int y);
uint distanceFromPt(int x, int y, int ptx, int pty);
void getBoxCoordinates(int boxnum, BoxCoords *bc);
byte getMaskFromBox(int box);
Box *getBoxBaseAddr(int box);
byte getBoxFlags(int box);
int getBoxScale(int box);
int getScale(int box, int x, int y);
int getScaleFromSlot(int slot, int x, int y);
protected:
// Scaling slots/items
struct ScaleSlot {
int x1, y1, scale1;
int x2, y2, scale2;
};
ScaleSlot _scaleSlots[20];
void setScaleSlot(int slot, int x1, int y1, int scale1, int x2, int y2, int scale2);
void setBoxScaleSlot(int box, int slot);
void convertScaleTableToScaleSlot(int slot);
void createBoxMatrix();
bool areBoxesNeighbours(int i, int j);
/* String class */
public:
CharsetRenderer *_charset;
byte _charsetColorMap[16];
protected:
byte _charsetColor;
byte _charsetData[15][16];
int _charsetBufPos;
byte _charsetBuffer[512];
int _stringLength;
byte _stringBuffer[4096];
bool _keepText;
void initCharset(int charset);
void printString(int m, const byte *msg);
void CHARSET_1();
void drawString(int a, const byte *msg);
void unkMessage1(const byte *msg);
void showMessageDialog(const byte *msg);
int addMessageToStack(const byte *msg, byte *dst, int dstSize);
int addIntToStack(byte *dst, int dstSize, int var);
int addVerbToStack(byte *dst, int dstSize, int var);
int addNameToStack(byte *dst, int dstSize, int var);
int addStringToStack(byte *dst, int dstSize, int var);
public:
Common::Language _language;
protected:
bool _existLanguageFile;
char *_languageBuffer;
LangIndexNode *_languageIndex;
int _languageIndexSize;
char _lastStringTag[12+1];
void loadLanguageBundle();
void playSpeech(const byte *ptr);
public:
void translateText(const byte *text, byte *trans_buff); // Used by class ScummDialog
// Somewhat hackish stuff for 2 byte support (Chinese/Japanese/Korean)
bool _useCJKMode;
int _2byteHeight;
int _2byteWidth;
byte *get2byteCharPtr(int idx);
protected:
byte *_2byteFontPtr;
#if defined(SCUMM_LITTLE_ENDIAN)
uint32 fileReadDword() { return _fileHandle.readUint32LE(); }
#elif defined(SCUMM_BIG_ENDIAN)
uint32 fileReadDword() { return _fileHandle.readUint32BE(); }
#endif
public:
/* Scumm Vars */
byte VAR_LANGUAGE;
byte VAR_KEYPRESS;
byte VAR_SYNC;
byte VAR_EGO;
byte VAR_CAMERA_POS_X;
byte VAR_HAVE_MSG;
byte VAR_ROOM;
byte VAR_OVERRIDE;
byte VAR_MACHINE_SPEED;
byte VAR_ME;
byte VAR_NUM_ACTOR;
byte VAR_CURRENT_LIGHTS;
byte VAR_CURRENTDRIVE; // How about merging this with VAR_CURRENTDISK?
byte VAR_CURRENTDISK;
byte VAR_TMR_1;
byte VAR_TMR_2;
byte VAR_TMR_3;
byte VAR_MUSIC_TIMER;
byte VAR_ACTOR_RANGE_MIN;
byte VAR_ACTOR_RANGE_MAX;
byte VAR_CAMERA_MIN_X;
byte VAR_CAMERA_MAX_X;
byte VAR_TIMER_NEXT;
byte VAR_VIRT_MOUSE_X;
byte VAR_VIRT_MOUSE_Y;
byte VAR_ROOM_RESOURCE;
byte VAR_LAST_SOUND;
byte VAR_CUTSCENEEXIT_KEY;
byte VAR_OPTIONS_KEY;
byte VAR_TALK_ACTOR;
byte VAR_CAMERA_FAST_X;
byte VAR_SCROLL_SCRIPT;
byte VAR_ENTRY_SCRIPT;
byte VAR_ENTRY_SCRIPT2;
byte VAR_EXIT_SCRIPT;
byte VAR_EXIT_SCRIPT2;
byte VAR_VERB_SCRIPT;
byte VAR_SENTENCE_SCRIPT;
byte VAR_INVENTORY_SCRIPT;
byte VAR_CUTSCENE_START_SCRIPT;
byte VAR_CUTSCENE_END_SCRIPT;
byte VAR_CHARINC;
byte VAR_WALKTO_OBJ;
byte VAR_DEBUGMODE;
byte VAR_HEAPSPACE;
byte VAR_RESTART_KEY;
byte VAR_PAUSE_KEY;
byte VAR_MOUSE_X;
byte VAR_MOUSE_Y;
byte VAR_TIMER;
byte VAR_TMR_4;
byte VAR_SOUNDCARD;
byte VAR_VIDEOMODE;
byte VAR_MAINMENU_KEY;
byte VAR_FIXEDDISK;
byte VAR_CURSORSTATE;
byte VAR_USERPUT;
byte VAR_SOUNDRESULT;
byte VAR_TALKSTOP_KEY;
byte VAR_FADE_DELAY;
byte VAR_NOSUBTITLES;
byte VAR_SOUNDPARAM;
byte VAR_SOUNDPARAM2;
byte VAR_SOUNDPARAM3;
byte VAR_MOUSEPRESENT;
byte VAR_MEMORY_PERFORMANCE;
byte VAR_VIDEO_PERFORMANCE;
byte VAR_ROOM_FLAG;
byte VAR_GAME_LOADED;
byte VAR_NEW_ROOM;
byte VAR_VERSION_KEY;
byte VAR_V5_TALK_STRING_Y;
byte VAR_ROOM_WIDTH;
byte VAR_ROOM_HEIGHT;
byte VAR_V6_EMSSPACE;
byte VAR_CAMERA_POS_Y;
byte VAR_CAMERA_MIN_Y;
byte VAR_CAMERA_MAX_Y;
byte VAR_CAMERA_THRESHOLD_X;
byte VAR_CAMERA_THRESHOLD_Y;
byte VAR_CAMERA_SPEED_X;
byte VAR_CAMERA_SPEED_Y;
byte VAR_CAMERA_ACCEL_X;
byte VAR_CAMERA_ACCEL_Y;
byte VAR_CAMERA_DEST_X;
byte VAR_CAMERA_DEST_Y;
byte VAR_CAMERA_FOLLOWED_ACTOR;
byte VAR_LEFTBTN_DOWN;
byte VAR_RIGHTBTN_DOWN;
byte VAR_LEFTBTN_HOLD;
byte VAR_RIGHTBTN_HOLD;
byte VAR_MOUSE_BUTTONS;
byte VAR_MOUSE_HOLD;
byte VAR_SAVELOAD_SCRIPT;
byte VAR_SAVELOAD_SCRIPT2;
byte VAR_DEFAULT_TALK_DELAY;
byte VAR_CHARSET_MASK;
byte VAR_CUSTOMSCALETABLE;
byte VAR_V6_SOUNDMODE;
byte VAR_CHARCOUNT;
byte VAR_VERB_ALLOWED;
byte VAR_ACTIVE_VERB;
byte VAR_ACTIVE_OBJECT1;
byte VAR_ACTIVE_OBJECT2;
byte VAR_CLICK_AREA;
byte VAR_BLAST_ABOVE_TEXT;
byte VAR_VOICE_MODE;
byte VAR_MUSIC_BUNDLE_LOADED;
byte VAR_VOICE_BUNDLE_LOADED;
byte VAR_NUM_SOUND_CHANNELS;
byte VAR_MUSIC_CHANNEL;
byte VAR_SOUND_CHANNEL;
byte VAR_NUM_ROOMS;
byte VAR_NUM_SCRIPTS;
byte VAR_NUM_SOUNDS;
byte VAR_NUM_COSTUMES;
byte VAR_NUM_IMAGES;
byte VAR_NUM_CHARSETS;
byte VAR_NUM_GLOBAL_OBJS;
byte VAR_NUM_SPRITES;
byte VAR_NUM_PALETTES;
byte VAR_NUM_UNK;
byte VAR_POLYGONS_ONLY;
byte VAR_WINDOWS_VERSION;
byte VAR_KEY_STATE;
byte VAR_WIZ_TCOLOR;
};
} // End of namespace Scumm
#endif