1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef TINSEL_TINSEL_H 24 #define TINSEL_TINSEL_H 25 26 #include "common/scummsys.h" 27 #include "common/system.h" 28 #include "common/error.h" 29 #include "common/events.h" 30 #include "common/keyboard.h" 31 #include "common/random.h" 32 #include "common/util.h" 33 34 #include "engines/engine.h" 35 #include "gui/debugger.h" 36 37 #include "tinsel/debugger.h" 38 #include "tinsel/graphics.h" 39 #include "tinsel/sound.h" 40 #include "tinsel/dw.h" 41 42 /** 43 * This is the namespace of the Tinsel engine. 44 * 45 * Status of this engine: Complete 46 * 47 * Games using this engine: 48 * - Discworld 49 * - Discworld 2: Missing Presumed ...!? 50 */ 51 namespace Tinsel { 52 53 class BMVPlayer; 54 class Config; 55 class MidiDriver; 56 class MidiMusicPlayer; 57 class PCMMusicPlayer; 58 class SoundManager; 59 60 typedef Common::List<Common::Rect> RectList; 61 62 enum TinselGameID { 63 GID_DW1 = 0, 64 GID_DW2 = 1 65 }; 66 67 enum TinselGameFeatures { 68 GF_SCNFILES = 1 << 0, 69 GF_ENHANCED_AUDIO_SUPPORT = 1 << 1, 70 GF_ALT_MIDI = 1 << 2, // Alternate sequence in midi.dat file 71 72 // The GF_USE_?FLAGS values specify how many country flags are displayed 73 // in the subtitles options dialog. 74 // None of these defined -> 1 language, in ENGLISH.TXT 75 GF_USE_3FLAGS = 1 << 3, // French, German, Spanish 76 GF_USE_4FLAGS = 1 << 4, // French, German, Spanish, Italian 77 GF_USE_5FLAGS = 1 << 5 // All 5 flags 78 }; 79 80 /** 81 * The following is the ScummVM definitions of the various Tinsel versions: 82 * TINSEL_V0 - This was an early engine version that was only used in the Discworld 1 83 * demo. 84 * TINSEL_V1 - This was the engine version used by Discworld 1. Note that there were two 85 * major releases: an earlier version that used *.gra files, and a later one that 86 * used *.scn files, and contained certain script and engine bugfixes. In ScummVM, 87 * we treat both releases as 'Tinsel 1', since the engine fixes from the later 88 * version work equally well the earlier version data. 89 * TINSEL_V2 - This is the engine used for the Discworld 2 game. 90 */ 91 enum TinselEngineVersion { 92 TINSEL_V0 = 0, 93 TINSEL_V1 = 1, 94 TINSEL_V2 = 2 95 }; 96 97 enum { 98 kTinselDebugAnimations = 1 << 0, 99 kTinselDebugActions = 1 << 1, 100 kTinselDebugSound = 1 << 2, 101 kTinselDebugMusic = 2 << 3 102 }; 103 104 #define DEBUG_BASIC 1 105 #define DEBUG_INTERMEDIATE 2 106 #define DEBUG_DETAILED 3 107 108 struct TinselGameDescription; 109 110 enum TinselKeyDirection { 111 MSK_LEFT = 1, MSK_RIGHT = 2, MSK_UP = 4, MSK_DOWN = 8, 112 MSK_DIRECTION = MSK_LEFT | MSK_RIGHT | MSK_UP | MSK_DOWN 113 }; 114 115 typedef bool (*KEYFPTR)(const Common::KeyState &); 116 117 #define SCREEN_WIDTH (_vm->screen().w) // PC screen dimensions 118 #define SCREEN_HEIGHT (_vm->screen().h) 119 #define SCRN_CENTER_X ((SCREEN_WIDTH - 1) / 2) // screen center x 120 #define SCRN_CENTER_Y ((SCREEN_HEIGHT - 1) / 2) // screen center y 121 #define UNUSED_LINES 48 122 #define EXTRA_UNUSED_LINES 3 123 //#define SCREEN_BOX_HEIGHT1 (SCREEN_HEIGHT - UNUSED_LINES) 124 //#define SCREEN_BOX_HEIGHT2 (SCREEN_BOX_HEIGHT1 - EXTRA_UNUSED_LINES) 125 #define SCREEN_BOX_HEIGHT1 SCREEN_HEIGHT 126 #define SCREEN_BOX_HEIGHT2 SCREEN_HEIGHT 127 128 #define GAME_FRAME_DELAY (1000 / ONE_SECOND) 129 130 #define TinselVersion (_vm->getVersion()) 131 #define TinselV0 (TinselVersion == TINSEL_V0) 132 #define TinselV1 (TinselVersion == TINSEL_V1) 133 #define TinselV2 (TinselVersion == TINSEL_V2) 134 #define TinselV2Demo (TinselVersion == TINSEL_V2 && _vm->getIsADGFDemo()) 135 #define TinselV1PSX (TinselVersion == TINSEL_V1 && _vm->getPlatform() == Common::kPlatformPSX) 136 #define TinselV1Mac (TinselVersion == TINSEL_V1 && _vm->getPlatform() == Common::kPlatformMacintosh) 137 138 #define READ_16(v) (TinselV1Mac ? READ_BE_UINT16(v) : READ_LE_UINT16(v)) 139 #define READ_32(v) (TinselV1Mac ? READ_BE_UINT32(v) : READ_LE_UINT32(v)) 140 #define FROM_16(v) (TinselV1Mac ? FROM_BE_16(v) : FROM_LE_16(v)) 141 #define FROM_32(v) (TinselV1Mac ? FROM_BE_32(v) : FROM_LE_32(v)) 142 #define TO_32(v) (TinselV1Mac ? TO_BE_32(v) : TO_LE_32(v)) 143 144 // Global reference to the TinselEngine object 145 extern TinselEngine *_vm; 146 147 class TinselEngine : public Engine { 148 int _gameId; 149 Common::KeyState _keyPressed; 150 Common::RandomSource _random; 151 Graphics::Surface _screenSurface; 152 Common::Point _mousePos; 153 uint8 _dosPlayerDir; 154 Console *_console; getDebugger()155 GUI::Debugger *getDebugger() { return _console; } 156 157 static const char *const _sampleIndices[][3]; 158 static const char *const _sampleFiles[][3]; 159 static const char *const _textFiles[][3]; 160 161 protected: 162 163 // Engine APIs 164 virtual void initializePath(const Common::FSNode &gamePath); 165 virtual Common::Error run(); 166 virtual bool hasFeature(EngineFeature f) const; 167 Common::Error loadGameState(int slot); 168 #if 0 169 Common::Error saveGameState(int slot, const Common::String &desc); 170 #endif 171 bool canLoadGameStateCurrently(); 172 #if 0 173 bool canSaveGameStateCurrently(); 174 #endif 175 176 public: 177 TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc); 178 virtual ~TinselEngine(); getGameId()179 int getGameId() { 180 return _gameId; 181 } 182 183 const TinselGameDescription *_gameDescription; 184 uint32 getGameID() const; 185 uint32 getFeatures() const; 186 Common::Language getLanguage() const; 187 uint16 getVersion() const; 188 uint32 getFlags() const; 189 Common::Platform getPlatform() const; 190 bool getIsADGFDemo() const; 191 bool isV1CD() const; 192 193 const char *getSampleIndex(LANGUAGE lang); 194 const char *getSampleFile(LANGUAGE lang); 195 const char *getTextFile(LANGUAGE lang); 196 197 MidiDriver *_driver; 198 SoundManager *_sound; 199 MidiMusicPlayer *_midiMusic; 200 PCMMusicPlayer *_pcmMusic; 201 BMVPlayer *_bmv; 202 203 Config *_config; 204 205 KEYFPTR _keyHandler; 206 207 /** Stack of pending mouse button events. */ 208 Common::List<Common::EventType> _mouseButtons; 209 210 /** Stack of pending keypresses. */ 211 Common::List<Common::Event> _keypresses; 212 213 214 /** List of all clip rectangles. */ 215 RectList _clipRects; 216 217 private: 218 void NextGameCycle(); 219 void CreateConstProcesses(); 220 void RestartGame(); 221 void RestartDrivers(); 222 void ChopDrivers(); 223 void ProcessKeyEvent(const Common::Event &event); 224 bool pollEvent(); 225 226 public: getTargetName()227 const Common::String getTargetName() const { return _targetName; } 228 Common::String getSavegameFilename(int16 saveNum) const; getSaveFileMan()229 Common::SaveFileManager *getSaveFileMan() { return _saveFileMan; } screen()230 Graphics::Surface &screen() { return _screenSurface; } 231 getMousePosition()232 Common::Point getMousePosition() const { return _mousePos; } setMousePosition(Common::Point pt)233 void setMousePosition(Common::Point pt) { 234 // Clip mouse position to be within the screen coordinates 235 pt.x = CLIP<int16>(pt.x, 0, SCREEN_WIDTH - 1); 236 pt.y = CLIP<int16>(pt.y, 0, SCREEN_HEIGHT - 1); 237 238 int yOffset = TinselV2 ? (g_system->getHeight() - _screenSurface.h) / 2 : 0; 239 g_system->warpMouse(pt.x, pt.y + yOffset); 240 _mousePos = pt; 241 } divertKeyInput(KEYFPTR fptr)242 void divertKeyInput(KEYFPTR fptr) { _keyHandler = fptr; } getRandomNumber(int maxNumber)243 int getRandomNumber(int maxNumber) { return _random.getRandomNumber(maxNumber); } getKeyDirection()244 uint8 getKeyDirection() const { return _dosPlayerDir; } 245 }; 246 247 // Externally available methods 248 void CuttingScene(bool bCutting); 249 void CDChangeForRestore(int cdNumber); 250 void CdHasChanged(); 251 252 } // End of namespace Tinsel 253 254 #endif /* TINSEL_TINSEL_H */ 255