/* 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 3 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, see . * */ /* * Based on ScottFree interpreter version 1.14 developed by Swansea * University Computer Society without disassembly of any other game * drivers, only of game databases as permitted by EEC law (for purposes * of compatibility). * * Licensed under GPLv2 * * https://github.com/angstsmurf/spatterlight/tree/master/terps/scott */ #ifndef GLK_SCOTT_H #define GLK_SCOTT_H /* * Controlling block */ #include "common/scummsys.h" #include "glk/glk_api.h" #include "glk/scott/definitions.h" #include "glk/scott/globals.h" #include "glk/scott/types.h" namespace Glk { namespace Scott { struct Command; #define LIGHT_SOURCE 9 // Always 9 how odd #define CARRIED 255 // Carried #define DESTROYED 0 // Destroyed #define DARKBIT 15 #define LIGHTOUTBIT 16 // Light gone out enum GameOption { YOUARE = 1, ///< You are not I am SCOTTLIGHT = 2, ///< Authentic Scott Adams light messages DEBUGGING = 4, ///< Info from database load TRS80_STYLE = 8, ///< Display in style used on TRS-80 PREHISTORIC_LAMP = 16, ///< Destroy the lamp (very old databases) SPECTRUM_STYLE = 32, ///< Display in style used on ZX Spectrum TI994A_STYLE = 64, ///< Display in style used on TI-99/4A NO_DELAYS = 128, ///< Skip all pauses FORCE_PALETTE_ZX = 256, ///< Force ZX Spectrum image palette FORCE_PALETTE_C64 = 512, ///< Force CBM 64 image palette FORCE_INVENTORY = 1024, ///< Inventory in upper window always on FORCE_INVENTORY_OFF = 2048 ///< Inventory in upper window always off }; #define GLK_BUFFER_ROCK 1 #define GLK_STATUS_ROCK 1010 #define GLK_GRAPHICS_ROCK 1020 #define TRS80_LINE "\n<------------------------------------------------------------>\n" #define MY_LOC (_G(_gameHeader)->_playerRoom) #define CURRENT_GAME (_G(_game->_gameID)) struct Header { int _unknown; int _numItems; int _numActions; int _numWords; ///< Smaller of verb/noun is padded to same size int _numRooms; int _maxCarry; int _playerRoom; int _treasures; int _wordLength; int _lightTime; int _numMessages; int _treasureRoom; Header() : _unknown(0), _numItems(0), _numActions(0), _numWords(0), _numRooms(0), _maxCarry(0), _playerRoom(0), _treasures(0), _wordLength(0), _lightTime(0), _numMessages(0), _treasureRoom(0) {} }; struct Action { int _vocab; int _condition[5]; int _action[2]; Action() : _vocab(0) { Common::fill(&_condition[0], &_condition[5], 0); Common::fill(&_action[0], &_action[2], 0); } }; struct Room { Common::String _text; int _exits[6]; byte _image; Room() : _image(255) { Common::fill(&_exits[0], &_exits[6], 0); } }; struct Item { Common::String _text; byte _location; byte _initialLoc; Common::String _autoGet; byte _flag; byte _image; Item() : _location(0), _initialLoc(0), _flag(0), _image(0) {} }; struct Tail { int _version; int _adventureNumber; int _unknown; Tail() : _version(0), _adventureNumber(0), _unknown(0) {} }; /** * Scott Adams game interpreter */ class Scott : public GlkAPI { private: Globals _globals; char _nounText[16]; //int _width = 0; ///< Terminal width int _topHeight = 0; ///< Height of top window int _topWidth = 0; bool _splitScreen = true; int _saveSlot = -1; ///< Save slot when loading savegame from launcher int _printLookToTranscript = 0; int _pauseNextRoomDescription = 0; strid_t _roomDescriptionStream = nullptr; private: /** * Initialization code */ void initialize(); void clearScreen(void); int matchUpItem(int noun, int loc); Common::String readString(Common::SeekableReadStream *f); void loadDatabase(Common::SeekableReadStream *f, bool loud); int whichWord(const char *word, const Common::StringArray &list); ActionResultType performLine(int ct); ExplicitResultType performActions(int vb, int no); void readInts(Common::SeekableReadStream *f, size_t count, ...); void writeToRoomDescriptionStream(const char *fmt, ...); void flushRoomDescription(char *buf); void printWindowDelimiter(); void listExits(); void listExitsSpectrumStyle(); void listInventoryInUpperWindow(); int itemEndsWithPeriod(int item); winid_t findGlkWindowWithRock(glui32 rock); glui32 optimalPictureSize(uint *width, uint *height); void openTopWindow(); void cleanupAndExit(); void drawBlack(); void drawRoomImage(); void restartGame(); void transcriptOn(); void transcriptOff(); int yesOrNo(); void lookWithPause(); void printTakenOrDropped(int index); void printTitleScreenBuffer(); void printTitleScreenGrid(); public: void drawImage(int image); void output(const Common::String &a); void output(const Common::U32String &a); void outputNumber(int a); void display(winid_t w, const char *fmt, ...); template void display(winid_t w, const Common::U32String &fmt, TParam... param); void fatal(const char *x); void hitEnter(); void updates(event_t ev); const char *mapSynonym(int noun); int performExtraCommand(int extraStopTime); void look(void); void openGraphicsWindow(); void closeGraphicsWindow(); void listInventory(); void updateSettings(); uint getRandomNumber(uint max); bool randomPercent(uint n); int countCarried(void); void playerIsDead(); void doneIt(); void putItemAInRoomB(int itemA, int roomB); int printScore(); void swapItemLocations(int itemA, int itemB); void moveItemAToLocOfItemB(int itemA, int itemB); void goToStoredLoc(); void swapLocAndRoomFlag(int index); void swapCounters(int index); void printNoun(); void delay(double seconds); void printMessage(int index); public: /** * Constructor */ Scott(OSystem *syst, const GlkGameDescription &gameDesc); /** * Returns the running interpreter type */ InterpreterType getInterpreterType() const override { return INTERPRETER_SCOTT; } /** * Execute the game */ void runGame() override; /** * Load a savegame from the passed Quetzal file chunk stream */ Common::Error readSaveData(Common::SeekableReadStream *rs) override; /** * Save the game. The passed write stream represents access to the UMem chunk * in the Quetzal save file that will be created */ Common::Error writeGameData(Common::WriteStream *ws) override; private: void display_u32_internal(winid_t w, const Common::U32String *fmt, ...); }; template inline void Scott::display(winid_t w, const Common::U32String &fmt, TParam... param) { display_u32_internal(w, &fmt, Common::forward(param)...); } extern Scott *g_scott; } // End of namespace Scott } // End of namespace Glk #endif