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 GLK_LEVEL9_DETECTION 24 #define GLK_LEVEL9_DETECTION 25 26 #include "common/fs.h" 27 #include "common/hash-str.h" 28 #include "engines/game.h" 29 #include "glk/detection.h" 30 31 namespace Glk { 32 namespace Level9 { 33 34 enum L9GameTypes { L9_V1, L9_V2, L9_V3, L9_V4 }; 35 36 struct gln_game_table_t { 37 const size_t length; ///< Datafile length in bytes 38 const byte checksum; ///< 8-bit checksum, last datafile byte 39 const uint16 crc; ///< 16-bit CRC, L9cut-internal 40 const char *const gameId; ///< Game Id 41 const char *const name; ///< Game title 42 const char *const extra; ///< Disk number, platform, etc. 43 }; 44 typedef const gln_game_table_t *gln_game_tableref_t; 45 46 struct gln_patch_table_t { 47 const size_t length; ///< Datafile length in bytes 48 const byte orig_checksum; ///< 8-bit checksum, last datafile byte 49 const uint16 orig_crc; ///< 16-bit CRC, L9cut-internal 50 const byte patch_checksum; ///< 8-bit checksum, last datafile byte 51 const uint16 patch_crc; ///< 16-bit CRC, L9cut-internal 52 }; 53 typedef const gln_patch_table_t *gln_patch_tableref_t; 54 55 struct L9V1GameInfo { 56 byte dictVal1, dictVal2; 57 int dictStart, L9Ptrs[5], absData, msgStart, msgLen; 58 }; 59 60 /** 61 * Scanner for game data 62 */ 63 class Scanner { 64 private: 65 long scan(byte *StartFile, uint32 size); 66 long ScanV2(byte *StartFile, uint32 size); 67 long ScanV1(byte *StartFile, uint32 size); 68 69 bool ValidateSequence(byte *Base, byte *Image, uint32 iPos, uint32 acode, uint32 *Size, uint32 size, uint32 *Min, uint32 *Max, bool Rts, bool *JumpKill, bool *DriverV4); 70 uint16 scanmovewa5d0(byte *Base, uint32 *Pos); 71 uint32 scangetaddr(int Code, byte *Base, uint32 *Pos, uint32 acode, int *Mask); 72 void scangetcon(int Code, uint32 *Pos, int *Mask); 73 bool CheckCallDriverV4(byte *Base, uint32 Pos); 74 #ifdef FULLSCAN 75 void Scanner::fullScan(byte *StartFile, uint32 size); 76 #endif 77 private: 78 byte **_dictData; 79 byte **_aCodePtr; 80 public: 81 L9GameTypes _gameType; 82 int _l9V1Game; 83 public: Scanner()84 Scanner() : _dictData(nullptr), _aCodePtr(nullptr), _gameType(L9_V1), _l9V1Game(-1) {} 85 86 /** 87 * Scan passed file for a valid game, and if found return it's offset 88 */ 89 long scanner(byte *StartFile, uint32 size, byte **dictData = nullptr, 90 byte **aCodePtr = nullptr); 91 92 /** 93 * Returns the info for a V1 game 94 */ 95 const L9V1GameInfo &v1Game() const; 96 }; 97 98 /** 99 * Detection manager for specific games 100 */ 101 class GameDetection : public Scanner { 102 private: 103 byte *&_startData; 104 uint32 &_fileSize; 105 bool _crcInitialized; 106 uint16 _crcTable[256]; 107 public: 108 const char *_gameName; 109 public: 110 /** 111 * Constructor 112 */ 113 GameDetection(byte *&startData, uint32 &fileSize); 114 115 /** 116 * Identify a game from its data length, checksum, and CRC. Returns the 117 * entry of the game in the game table, or nullptr if not found. 118 * 119 * This function uses startdata and FileSize from the core interpreter. 120 * These aren't advertised symbols, so be warned. 121 */ 122 gln_game_tableref_t gln_gameid_identify_game(); 123 124 /** 125 * Return the CRC of the bytes buffer[0..length-1]. 126 * 127 * This algorithm is selected to match the CRCs used in L9cut. Because of 128 * the odd way CRCs are padded when L9cut calculates the CRC, this function 129 * allows a count of NUL padding bytes to be included within the return CRC. 130 */ 131 uint16 gln_get_buffer_crc(const void *void_buffer, size_t length, size_t padding = 0); 132 133 /* 134 * Look up and return game table and patch table entries given a game's 135 * length, checksum, and CRC. Returns the entry, or nullptr if not found. 136 */ 137 gln_game_tableref_t gln_gameid_lookup_game(uint16 length, byte checksum, uint16 crc, int ignore_crc) const; 138 139 /** 140 * Look up and return patch table entries given a game's length, checksum, and CRC. 141 * Returns the entry, or nullptr if not found 142 */ 143 gln_patch_tableref_t gln_gameid_lookup_patch(uint16 length, byte checksum, uint16 crc) const; 144 145 /** 146 * Return the name of the game, or nullptr if not identifiable. 147 * 148 * This function uses startdata from the core interpreter. This isn't an 149 * advertised symbol, so be warned. 150 */ 151 const char *gln_gameid_get_game_name(); 152 153 /** 154 * Clear the saved game name, forcing a new lookup when next queried. This 155 * function should be called by actions that may cause the interpreter to 156 * change game file, for example os_set_filenumber(). 157 */ 158 void gln_gameid_game_name_reset(); 159 }; 160 161 /** 162 * Meta engine for Level 9 interpreter 163 */ 164 class Level9MetaEngine { 165 public: 166 /** 167 * Get a list of supported games 168 */ 169 static void getSupportedGames(PlainGameList &games); 170 171 /** 172 * Returns a game description for the given game Id, if it's supported 173 */ 174 static GameDescriptor findGame(const char *gameId); 175 176 /** 177 * Detect supported games 178 */ 179 static bool detectGames(const Common::FSList &fslist, DetectedGames &gameList); 180 181 /** 182 * Check for game Id clashes with other sub-engines 183 */ 184 static void detectClashes(Common::StringMap &map); 185 }; 186 187 } // End of namespace Level9 188 } // End of namespace Glk 189 190 #endif 191