mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-05 09:10:29 +00:00
b4c330ce07
svn-id: r22040
2094 lines
80 KiB
C++
2094 lines
80 KiB
C++
/* ScummVM - Scumm Interpreter
|
|
* Copyright (C) 2001 Ludvig Strigeus
|
|
* Copyright (C) 2001-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "common/stdafx.h"
|
|
|
|
#include "backends/fs/fs.h"
|
|
|
|
#include "base/plugins.h"
|
|
|
|
#include "common/config-manager.h"
|
|
#include "common/list.h"
|
|
#include "common/md5.h"
|
|
#include "common/system.h" // Only needed for g_system
|
|
|
|
#include "scumm/plugin.h"
|
|
#include "scumm/scumm.h"
|
|
#include "scumm/intern.h"
|
|
#include "scumm/he/intern_he.h"
|
|
|
|
#ifdef PALMOS_68K
|
|
#include "extras/palm-scumm-md5.h"
|
|
#else
|
|
#include "scumm/scumm-md5.h"
|
|
#endif
|
|
|
|
|
|
namespace Scumm {
|
|
|
|
#pragma mark -
|
|
#pragma mark --- Data types & constants ---
|
|
#pragma mark -
|
|
|
|
enum {
|
|
// We only compute the MD5 of the first megabyte of our data files.
|
|
kMD5FileSizeLimit = 1024 * 1024
|
|
};
|
|
|
|
struct ObsoleteGameID {
|
|
const char *from;
|
|
const char *to;
|
|
Common::Platform platform;
|
|
};
|
|
|
|
#define UNK Common::kPlatformUnknown
|
|
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark --- Tables ---
|
|
#pragma mark -
|
|
|
|
|
|
/**
|
|
* This table contains all game IDs supported by the SCUMM engine, and maps
|
|
* them to the full humand readable game name.
|
|
*/
|
|
static const PlainGameDescriptor gameDescriptions[] = {
|
|
{ "atlantis", "Indiana Jones and the Fate of Atlantis" },
|
|
{ "indy3", "Indiana Jones and the Last Crusade" },
|
|
{ "loom", "Loom" },
|
|
{ "maniac", "Maniac Mansion" },
|
|
{ "monkey", "The Secret of Monkey Island" },
|
|
{ "monkey2", "Monkey Island 2: LeChuck's Revenge" },
|
|
{ "pass", "Passport to Adventure" },
|
|
{ "samnmax", "Sam & Max Hit the Road" },
|
|
{ "tentacle", "Day of the Tentacle" },
|
|
{ "zak", "Zak McKracken and the Alien Mindbenders" },
|
|
|
|
#ifndef DISABLE_SCUMM_7_8
|
|
{ "ft", "Full Throttle" },
|
|
{ "dig", "The Dig" },
|
|
{ "comi", "The Curse of Monkey Island" },
|
|
#endif
|
|
|
|
{ "fbear", "Fatty Bear's Birthday Surprise" },
|
|
{ "fbpack", "Fatty Bear's Fun Pack" },
|
|
{ "funpack", "Putt-Putt's Fun Pack" },
|
|
{ "puttmoon", "Putt-Putt Goes to the Moon" },
|
|
{ "puttputt", "Putt-Putt Joins the Parade" },
|
|
|
|
#ifndef DISABLE_HE
|
|
{ "activity", "Putt-Putt & Fatty Bear's Activity Pack" },
|
|
{ "airport", "Let's Explore the Airport with Buzzy" },
|
|
{ "artdemo", "Blue's Art Time Activities (Demo)" },
|
|
{ "balloon", "Putt-Putt and Pep's Balloon-O-Rama" },
|
|
{ "baseball", "Backyard Baseball" },
|
|
{ "baseball2001", "Backyard Baseball 2001" },
|
|
{ "Baseball2003", "Backyard Baseball 2003" },
|
|
{ "basketball", "Backyard Basketball" },
|
|
{ "BluesABCTime", "Blue's ABC Time" },
|
|
{ "BluesBirthdayDemo", "Blue's Birthday Adventure (Demo)" },
|
|
{ "catalog", "Humongous Interactive Catalog" },
|
|
{ "chase", "SPY Fox in Cheese Chase" },
|
|
{ "dog", "Putt-Putt and Pep's Dog on a Stick" },
|
|
{ "farm", "Let's Explore the Farm with Buzzy" },
|
|
{ "football", "Backyard Football" },
|
|
{ "freddi", "Freddi Fish 1: The Case of the Missing Kelp Seeds" },
|
|
{ "freddi2", "Freddi Fish 2: The Case of the Haunted Schoolhouse" },
|
|
{ "freddi3", "Freddi Fish 3: The Case of the Stolen Conch Shell" },
|
|
{ "freddi4", "Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch" },
|
|
{ "freddicove", "Freddi Fish 5: The Case of the Creature of Coral Cave" },
|
|
{ "FreddisFunShop", "Freddi Fish's One-Stop Fun Shop" },
|
|
{ "jungle", "Let's Explore the Jungle with Buzzy" },
|
|
{ "lost", "Pajama Sam's Lost & Found" },
|
|
{ "maze", "Freddi Fish and Luther's Maze Madness" },
|
|
{ "mustard", "SPY Fox in Hold the Mustard" },
|
|
{ "pajama", "Pajama Sam 1: No Need to Hide When It's Dark Outside" },
|
|
{ "pajama2", "Pajama Sam 2: Thunder and Lightning Aren't so Frightening" },
|
|
{ "pajama3", "Pajama Sam 3: You Are What You Eat From Your Head to Your Feet" },
|
|
{ "pjgames", "Pajama Sam: Games to Play On Any Day" },
|
|
{ "puttcircus", "Putt-Putt Joins the Circus" },
|
|
{ "puttrace", "Putt-Putt Enters the Race" },
|
|
{ "PuttsFunShop", "Putt-Putt's One-Stop Fun Shop" },
|
|
{ "putttime", "Putt-Putt Travels Through Time" },
|
|
{ "puttzoo", "Putt-Putt Saves the Zoo" },
|
|
{ "readdemo", "Blue's Reading Time Activities (Demo)" },
|
|
{ "SamsFunShop", "Pajama Sam's One-Stop Fun Shop" },
|
|
{ "soccer", "Backyard Soccer" },
|
|
{ "Soccer2004", "Backyard Soccer 2004" },
|
|
{ "SoccerMLS", "Backyard Soccer MLS Edition" },
|
|
{ "socks", "Pajama Sam's Sock Works" },
|
|
{ "spyfox", "SPY Fox 1: Dry Cereal" },
|
|
{ "spyfox2", "SPY Fox 2: Some Assembly Required" },
|
|
{ "spyozon", "SPY Fox 3: Operation Ozone" },
|
|
{ "thinker1", "Big Thinkers First Grade" },
|
|
{ "thinkerk", "Big Thinkers Kindergarten" },
|
|
{ "water", "Freddi Fish and Luther's Water Worries" },
|
|
#endif
|
|
{ 0, 0 }
|
|
};
|
|
|
|
/**
|
|
* Conversion table mapping old obsolete game IDs to the
|
|
* corresponding new game ID and platform combination.
|
|
*/
|
|
static const ObsoleteGameID obsoleteGameIDsTable[] = {
|
|
{"bluesabctimedemo", "bluesabctime", UNK},
|
|
{"comidemo", "comi", UNK},
|
|
{"digdemo", "dig", UNK},
|
|
{"digdemoMac", "dig", Common::kPlatformMacintosh},
|
|
{"dottdemo", "tentacle", UNK},
|
|
{"fate", "atlantis", UNK},
|
|
{"ftMac", "ft", Common::kPlatformMacintosh},
|
|
{"ftpcdemo", "ft", UNK},
|
|
{"ftdemo", "ft", Common::kPlatformMacintosh},
|
|
{"game", "monkey", UNK},
|
|
{"indy3ega", "indy3", UNK},
|
|
{"indy3towns", "indy3", Common::kPlatformFMTowns},
|
|
{"indy4", "atlantis", Common::kPlatformFMTowns},
|
|
{"indydemo", "atlantis", Common::kPlatformFMTowns},
|
|
{"loomcd", "loom", UNK},
|
|
{"loomTowns", "loom", Common::kPlatformFMTowns},
|
|
{"mi2demo", "monkey2", UNK},
|
|
{"monkey1", "monkey", UNK},
|
|
{"monkeyEGA", "monkey", UNK},
|
|
{"monkeyVGA", "monkey", UNK},
|
|
{"playfate", "atlantis", UNK},
|
|
{"samnmax-alt", "samnmax", UNK},
|
|
{"samnmaxMac", "samnmax", Common::kPlatformMacintosh},
|
|
{"samdemo", "samnmax", UNK},
|
|
{"samdemoMac", "samnmax", Common::kPlatformMacintosh},
|
|
{"snmdemo", "samnmax", UNK},
|
|
{"snmidemo", "samnmax", UNK},
|
|
{"tentacleMac", "tentacle", Common::kPlatformMacintosh},
|
|
{"zakTowns", "zak", Common::kPlatformFMTowns},
|
|
{NULL, NULL, UNK}
|
|
};
|
|
|
|
// The following table contains information about variants of our various games.
|
|
// We index into it with help of md5table (from scumm-md5.h), to find the correct
|
|
// GameSettings for a given game variant.
|
|
//
|
|
// The first listed variant is assumed to be the 'default' variant -- i.e. the
|
|
// variant that gets used when no explicit variant code has been specified.
|
|
//
|
|
// Note: Only set 'platform' to a value different from UNK if that game variant
|
|
// really *only* exists for that given platform. In all other cases, the correct
|
|
// platform will be determined via the MD5 table or derived from the filename.
|
|
static const GameSettings gameVariantsTable[] = {
|
|
// The C64 version of MM is detected via the platform field and hence has no seperate entry in this list
|
|
{"maniac", "V2", GID_MANIAC, 2, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, UNK},
|
|
{"maniac", "NES", GID_MANIAC, 1, 0, MDT_NONE, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformNES},
|
|
{"maniac", "V1", GID_MANIAC, 1, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
|
|
|
|
// The C64 version of Zak is detected via the platform field and hence has no seperate entry in this list
|
|
{"zak", "V2", GID_ZAK, 2, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, UNK},
|
|
{"zak", "V1", GID_ZAK, 1, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, Common::kPlatformPC},
|
|
{"zak", "FM-TOWNS", GID_ZAK, 3, 0, MDT_TOWNS, GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
|
|
|
|
{"indy3", "EGA", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, UNK},
|
|
{"indy3", "No Adlib", GID_INDY3, 3, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, UNK},
|
|
{"indy3", "VGA", GID_INDY3, 3, 0, MDT_PCSPK | MDT_ADLIB, GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC},
|
|
{"indy3", "FM-TOWNS", GID_INDY3, 3, 0, MDT_TOWNS, GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
|
|
|
|
{"loom", "EGA", GID_LOOM, 3, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, UNK},
|
|
{"loom", "No Adlib", GID_LOOM, 3, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_NO_SCALING | GF_16COLOR | GF_USE_KEY | GF_OLD_BUNDLE, UNK},
|
|
{"loom", "FM-TOWNS", GID_LOOM, 3, 0, MDT_TOWNS, GF_SMALL_HEADER | GF_NO_SCALING | GF_OLD256 | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
|
|
{"loom", "VGA", GID_LOOM, 4, 0, MDT_NONE, GF_SMALL_HEADER | GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformPC},
|
|
|
|
{"pass", 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_ADLIB, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
|
|
|
|
{"monkey", "VGA", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI, GF_SMALL_HEADER | GF_USE_KEY, Common::kPlatformPC},
|
|
{"monkey", "EGA", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB | MDT_MIDI, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
|
|
{"monkey", "No Adlib", GID_MONKEY_EGA, 4, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformAtariST},
|
|
{"monkey", "Demo", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_ADLIB, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR, Common::kPlatformPC},
|
|
{"monkey", "CD", GID_MONKEY, 5, 0, MDT_ADLIB, GF_USE_KEY | GF_AUDIOTRACKS, UNK},
|
|
{"monkey", "FM-TOWNS", GID_MONKEY, 5, 0, MDT_ADLIB, GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformFMTowns},
|
|
{"monkey", "SEGA", GID_MONKEY, 5, 0, MDT_NONE, GF_USE_KEY | GF_AUDIOTRACKS, Common::kPlatformSegaCD},
|
|
|
|
{"monkey2", 0, GID_MONKEY2, 5, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
|
|
|
|
{"atlantis", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
|
|
|
|
{"tentacle", 0, GID_TENTACLE, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
|
|
|
|
{"samnmax", 0, GID_SAMNMAX, 6, 0, /*MDT_PCSPK |*/ MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
|
|
|
|
#ifndef DISABLE_SCUMM_7_8
|
|
{"ft", "", GID_FT, 7, 0, MDT_NONE, GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE, UNK},
|
|
{"ft", "Demo", GID_FT, 7, 0, MDT_NONE, GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEMO, UNK},
|
|
|
|
{"dig", "", GID_DIG, 7, 0, MDT_NONE, GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE, UNK},
|
|
{"dig", "Demo", GID_DIG, 7, 0, MDT_NONE, GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEMO, UNK},
|
|
|
|
{"comi", "", GID_CMI, 8, 0, MDT_NONE, GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE, Common::kPlatformWindows},
|
|
{"comi", "Demo", GID_CMI, 8, 0, MDT_NONE, GF_NEW_COSTUMES | GF_NEW_CAMERA | GF_DIGI_IMUSE | GF_DEMO, Common::kPlatformWindows},
|
|
#endif
|
|
|
|
// Humongous Entertainment Scumm Version 6
|
|
{"puttmoon", 0, GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"funpack", 0, GID_FUNPACK, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"fbpack", 0, GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
{"puttputt", "HE 61", GID_HEGAME, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"puttputt", "HE 60", GID_HEGAME, 6, 60, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, Common::kPlatformPC},
|
|
{"puttputt", "Demo", GID_PUTTDEMO, 6, 60, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK},
|
|
|
|
{"fbear", "HE 61", GID_FBEAR, 6, 61, MDT_ADLIB | MDT_MIDI, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"fbear", "HE 70", GID_FBEAR, 6, 70, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformWindows},
|
|
|
|
#ifndef DISABLE_HE
|
|
{"activity", "", GID_HEGAME, 6, 70, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Humongous Entertainment Scumm Version 7.1
|
|
// The first version to use 640x480 resolution
|
|
// There are also 7.1 versions of freddemo, airdemo and farmdemo
|
|
{"catalog", "", GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"freddi", "", GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Humongous Entertainment Scumm Version 7.2
|
|
{"airport", "", GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"puttzoo", "", GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Changed o_getResourceSize to cover all resource types
|
|
{"farm", "", GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"jungle", "", GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Humongous Entertainment Scumm Version 8.0 ? Scummsrc.80
|
|
{"freddi2", "", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"pajama", "", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"putttime", "", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
{"balloon", "", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"dog", "", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"maze", "", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"socks", "", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
{"water", "", GID_WATER, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"water", "HE 80", GID_WATER, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"water", "HE 99", GID_WATER, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Humongous Entertainment Scumm Version 9.0 ? Scummsys.90
|
|
{"baseball", "", GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"thinkerk", "", GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"thinker1", "", GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"freddi3", "", GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"spyfox", "", GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Humongous Entertainment Scumm Version 9.5 ? Scummsys.95
|
|
{"pajama2", "", GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"chase", "", GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Humongous Entertainment Scumm Version 9.8 ? Scummsys.98
|
|
// these and later games can easily be identified by the .(a) file instead of a .he1
|
|
// and INIB chunk in the .he0
|
|
{"lost", "", GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
{"puttrace", "HE 98", GID_PUTTRACE, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"puttrace", "HE 98.5", GID_PUTTRACE, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, UNK},
|
|
{"puttrace", "HE 99", GID_PUTTRACE, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
{"bluesabctime", "", GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"soccer", "", GID_SOCCER, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
|
|
// Global scripts increased to 2048
|
|
{"freddi4", "", GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, UNK},
|
|
{"freddi4", "unenc", GID_HEGAME, 6, 98, MDT_NONE, GF_NEW_COSTUMES | GF_HE_985, UNK},
|
|
|
|
// Humongous Entertainment Scumm Version 9.9 ? Scummsys.99
|
|
{"football", 0, GID_FOOTBALL, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"pajama3", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, UNK},
|
|
{"puttcircus", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, UNK},
|
|
{"spyfox2", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, UNK},
|
|
{"mustard", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, UNK},
|
|
|
|
// Added the use of fonts
|
|
{"FreddisFunShop", 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, UNK},
|
|
{"SamsFunShop", 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, UNK},
|
|
{"PuttsFunShop", 0, GID_FUNSHOP, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED, UNK},
|
|
|
|
// Added 16bit color
|
|
{"baseball2001", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, UNK},
|
|
{"SoccerMLS", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK},
|
|
{"spyozon", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK},
|
|
|
|
{"freddicove", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK},
|
|
{"freddicove", "unenc", GID_HEGAME, 6, 99, MDT_NONE, GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK},
|
|
{"freddicove", "HE 100", GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK},
|
|
|
|
// Restructured the Scumm engine
|
|
{"pjgames", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_NOSUBTITLES | GF_HE_LOCALIZED | GF_16BIT_COLOR, UNK},
|
|
|
|
// Uses bink in external files for logos
|
|
{"Baseball2003", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, UNK},
|
|
{"basketball", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"Soccer2004", 0, GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, UNK},
|
|
|
|
// Uses smacker in external files, for testing only
|
|
{"BluesBirthdayDemo", 0, GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"artdemo", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, UNK},
|
|
{"readdemo", 0, GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_16BIT_COLOR, UNK},
|
|
|
|
|
|
// The following are meant to be generic HE game variants and as such do
|
|
// not specify a game ID. Make sure that these are last in the table, else
|
|
// they'll override more specific entries that follow later on.
|
|
{"", "HE 70", GID_HEGAME, 6, 70, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 71", GID_HEGAME, 6, 71, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 72", GID_HEGAME, 6, 72, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 73", GID_HEGAME, 6, 73, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 80", GID_HEGAME, 6, 80, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 90", GID_HEGAME, 6, 90, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 95", GID_HEGAME, 6, 95, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 98", GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 98.5", GID_HEGAME, 6, 98, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES | GF_HE_985, UNK},
|
|
{"", "HE 99", GID_HEGAME, 6, 99, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
{"", "HE 100", GID_HEGAME, 6, 100, MDT_NONE, GF_USE_KEY | GF_NEW_COSTUMES, UNK},
|
|
#endif
|
|
{NULL, NULL, 0, 0, MDT_NONE, 0, 0, UNK}
|
|
};
|
|
|
|
static const SubstResFileNames substResFileNameTable[] = {
|
|
// The first few entries for 00.LFL/01.LFL files are here for two reasons:
|
|
// 1) For the detector to detect these games
|
|
// 2) Because the ScummEngine constructor distinguishes between extracted
|
|
// and non-extracted variants of these C64/NES games by the presence
|
|
// or absence of a SubstResFileNames record.
|
|
// Use 1 will go away with the new detector code. Use 2 needs some more
|
|
// attention, but most likely should be solved by passing the name of the
|
|
// "detect file" to the contructor.
|
|
{ "00.LFL", "Maniac Mansion (E).prg", kGenAsIs },
|
|
{ "00.LFL", "Maniac Mansion (F).prg", kGenAsIs },
|
|
{ "00.LFL", "Maniac Mansion (SW).prg", kGenAsIs },
|
|
{ "00.LFL", "Maniac Mansion (U).prg", kGenAsIs },
|
|
{ "00.LFL", "Maniac Mansion (G).prg", kGenAsIs },
|
|
{ "00.LFL", "maniac1.d64", kGenAsIs }, // Do not
|
|
{ "01.LFL", "maniac2.d64", kGenAsIs }, // swap
|
|
{ "00.LFL", "zak1.d64", kGenAsIs }, // these
|
|
{ "01.LFL", "zak2.d64", kGenAsIs }, // lines
|
|
|
|
{ "atlantis", "Fate of Atlantis Data", kGenAsIs },
|
|
{ "atlantis", "fate", kGenPC },
|
|
{ "atlantis", "playfate", kGenPC },
|
|
{ "atlantis", "indy4", kGenPC },
|
|
{ "atlantis", "indydemo", kGenPC },
|
|
{ "tentacle", "Day of the Tentacle Data", kGenAsIs },
|
|
{ "tentacle", "dottdemo", kGenPC },
|
|
{ "tentacle", "Day of the Tentacle Demo Data", kGenAsIs },
|
|
{ "monkey", "monkey1", kGenPC },
|
|
{ "monkey", "monkeyk", kGenPC }, // FM-TOWNS Jap
|
|
{ "monkey", "game", kGenPC }, // SegaCD
|
|
{ "monkey2", "mi2demo", kGenPC },
|
|
{ "samnmax", "Sam & Max Data", kGenAsIs },
|
|
{ "samnmax", "Sam & Max Demo Data", kGenAsIs },
|
|
{ "samnmax", "ramnmax", kGenPC }, // Used in some releases of Russian Sam'n'Max
|
|
{ "samnmax", "samdemo", kGenPC },
|
|
{ "samnmax", "snmdemo", kGenPC },
|
|
{ "samnmax", "snmidemo", kGenPC },
|
|
{ "samnmax", "sdemo", kGenPC },
|
|
#ifndef DISABLE_SCUMM_7_8
|
|
{ "dig", "The Dig Data", kGenAsIs },
|
|
{ "dig", "The Dig Demo Data", kGenAsIs },
|
|
{ "ft", "Full Throttle Data", kGenAsIs },
|
|
{ "ft", "Full Throttle Demo Data", kGenAsIs },
|
|
{ "ft", "Vollgas Data", kGenAsIs },
|
|
{ "ft", "Vollgas Demo Data", kGenAsIs },
|
|
{ "ft", "ftdemo", kGenPC },
|
|
#endif
|
|
{ "fbear", "fbdemo", kGenPC },
|
|
{ "fbear", "Fatty Bear Demo", kGenMacNoParens },
|
|
{ "fbear", "Fatty Bear", kGenMacNoParens },
|
|
{ "puttmoon", "moondemo", kGenPC },
|
|
{ "puttmoon", "Putt-Putt Moon Demo", kGenMacNoParens },
|
|
{ "puttmoon", "Putt-Putt Moon", kGenMacNoParens },
|
|
{ "puttputt", "puttdemo", kGenPC },
|
|
{ "puttputt", "Putt-Putt's Demo", kGenMacNoParens },
|
|
{ "puttputt", "Putt-Putt Parade", kGenMacNoParens },
|
|
#ifndef DISABLE_HE
|
|
{ "airport", "airdemo", kGenPC },
|
|
{ "airport", "Airport Demo", kGenMac },
|
|
{ "airport", "The AirPort", kGenMac },
|
|
{ "balloon", "Balloon-O-Rama", kGenMac },
|
|
{ "baseball", "BaseBall", kGenMac },
|
|
{ "baseball2001", "bb2demo", kGenPC },
|
|
{ "baseball2001", "Baseball 2001 Demo", kGenMac },
|
|
{ "baseball2001", "Baseball 2001", kGenMac },
|
|
{ "baseball2001", "baseball 2001", kGenPC },
|
|
{ "Baseball2003", "Baseball 2003", kGenMac },
|
|
{ "basketball", "Basketball", kGenMac },
|
|
{ "bluesabctime", "BluesABCTimeDemo", kGenPC },
|
|
{ "bluesabctime", "BluesABCTimeDemo", kGenMac },
|
|
{ "catalog", "catalog2", kGenPC },
|
|
{ "chase", "Cheese Chase", kGenMac },
|
|
{ "dog", "Dog on a Stick", kGenMac },
|
|
{ "farm", "farmdemo", kGenPC },
|
|
{ "farm", "Farm Demo", kGenMac },
|
|
{ "football", "FootBall", kGenMac },
|
|
{ "football", "FootBall Demo", kGenMac },
|
|
{ "football", "FootBall2002", kGenPC },
|
|
{ "football", "footdemo", kGenPC },
|
|
{ "freddi", "freddemo", kGenPC },
|
|
{ "freddi", "Freddi Demo", kGenMac },
|
|
{ "freddi", "Freddi Fish", kGenMac },
|
|
{ "freddi", "FreddiD", kGenPC },
|
|
{ "freddi2", "ff2-demo", kGenPC },
|
|
{ "freddi2", "FFHSDemo", kGenMac },
|
|
{ "freddi2", "FFHSDemo", kGenPC },
|
|
{ "freddi2", "Freddi Fish 2 Demo", kGenMac },
|
|
{ "freddi2", "Freddi Fish 2", kGenMac },
|
|
{ "freddi2", "FreddiCHSH", kGenPC },
|
|
{ "freddi2", "Fritzi Fisch 2", kGenMac },
|
|
{ "freddi3", "F3-mdemo", kGenMac },
|
|
{ "freddi3", "F3-Mdemo", kGenMac },
|
|
{ "freddi3", "f3-mdemo", kGenPC },
|
|
{ "freddi3", "FF3-DEMO", kGenPC },
|
|
{ "freddi3", "Freddi Fish 3", kGenMac },
|
|
{ "freddi3", "FreddiFGT", kGenPC },
|
|
{ "freddi3", "FreddiFGT", kGenMac },
|
|
{ "freddi3", "FreddiSCS", kGenPC },
|
|
{ "freddi3", "Fritzi3demo", kGenMac },
|
|
{ "freddi3", "Fritzi3demo", kGenPC },
|
|
{ "freddi3", "MM3-DEMO", kGenPC },
|
|
{ "freddi3", "MM3-Demo", kGenMac }, // FR Mac demo
|
|
{ "freddi4", "f4-demo", kGenPC },
|
|
{ "freddi4", "ff4demo", kGenPC },
|
|
{ "freddi4", "Ff4demo", kGenMac },
|
|
{ "freddi4", "Freddi 4", kGenMac },
|
|
{ "freddi4", "Freddi 4 Demo", kGenMac },
|
|
{ "freddi4", "FreddiGS", kGenPC },
|
|
{ "freddi4", "FreddiGS", kGenMac },
|
|
{ "freddi4", "FreddiHRBG", kGenPC },
|
|
{ "freddicove", "FreddiCCC", kGenPC },
|
|
{ "freddicove", "FreddiCove", kGenMac },
|
|
{ "freddicove", "FreddiDZZ", kGenPC },
|
|
{ "freddicove", "ff5demo", kGenPC },
|
|
{ "freddicove", "FFCoveDemo", kGenPC },
|
|
{ "freddicove", "FreddiCoveDemo", kGenMac },
|
|
{ "freddicove", "FF5Demo", kGenMac }, // NL Mac demo
|
|
{ "FreddisFunShop", "Freddi's FunShop", kGenMac },
|
|
{ "jungle", "The Jungle", kGenMac },
|
|
{ "lost", "Lost and Found", kGenMac },
|
|
{ "lost", "smaller", kGenPC },
|
|
{ "maze", "Maze Madness", kGenMac},
|
|
{ "mustard", "Mustard", kGenMac },
|
|
{ "pajama", "Pyjama Pit", kGenMac },
|
|
{ "pajama", "Pajama Sam", kGenMac },
|
|
{ "pajama", "PajamaNHD", kGenPC },
|
|
{ "pajama", "PJS-DEMO", kGenPC },
|
|
{ "pajama", "PYJAMA", kGenPC },
|
|
{ "pajama", "SAMDEMO", kGenPC },
|
|
{ "pajama", "SAMDEMO", kGenMac }, // FR Mac demo
|
|
{ "pajama2", "Pajama Sam 2", kGenMac },
|
|
{ "pajama2", "PajamaTAL", kGenPC },
|
|
{ "pajama2", "PyjamaDBMN", kGenPC },
|
|
{ "pajama2", "PyjamaDBMN", kGenMac },
|
|
{ "pajama2", "Pyjama Pit 2 Demo", kGenMac },
|
|
{ "pajama2", "PJP2DEMO", kGenPC },
|
|
{ "pajama2", "PJ2Demo", kGenMac },
|
|
{ "pajama2", "pj2demo", kGenPC },
|
|
{ "pajama2", "Pjs2demo", kGenPC },
|
|
{ "pajama2", "PJ2 Demo", kGenMac }, // NL Mac demo
|
|
{ "pajama3", "GPJ3Demo", kGenPC },
|
|
{ "pajama3", "Pajama Sam 3", kGenMac },
|
|
{ "pajama3", "Pajama Sam 3-Demo", kGenMac },
|
|
{ "pajama3", "pj3-demo", kGenPC },
|
|
{ "pajama3", "pj3demo", kGenPC },
|
|
{ "pajama3", "PJ3Demo", kGenMac },
|
|
{ "pajama3", "Pajama Sam Demo", kGenMac },
|
|
{ "pajama3", "PjSamDemo", kGenMac },
|
|
{ "pajama3", "PjSamDemo", kGenPC },
|
|
{ "pajama3", "PyjamaSKS", kGenPC },
|
|
{ "pajama3", "PyjamaSKS", kGenMac },
|
|
{ "pajama3", "UKPajamaEAT", kGenPC }, // Russian
|
|
{ "pjgames", "PJGames", kGenMac },
|
|
{ "puttcircus", "circdemo", kGenPC },
|
|
{ "puttcircus", "Putt Circus Demo", kGenMac },
|
|
{ "puttcircus", "Putt Circus", kGenMac },
|
|
{ "puttrace", "500demo", kGenPC },
|
|
{ "puttrace", "racedemo", kGenPC },
|
|
{ "puttrace", "RaceDemo", kGenMac },
|
|
{ "puttrace", "Rennen", kGenPC },
|
|
{ "puttrace", "Putt500 demo", kGenMac }, // NL Mac demo
|
|
{ "puttrace", "Putt Race", kGenMac },
|
|
{ "puttrace", "ToffRennen", kGenPC },
|
|
{ "puttrace", "ToffRennen", kGenMac },
|
|
{ "puttrace", "UKPuttRace", kGenPC }, // Russian
|
|
{ "PuttsFunShop", "Putt's FunShop", kGenMac },
|
|
{ "putttime", "PuttPuttTTT", kGenPC },
|
|
{ "putttime", "PuttPuttTTT", kGenMac },
|
|
{ "putttime", "PuttTijd", kGenPC },
|
|
{ "putttime", "Putt Time", kGenMac },
|
|
{ "putttime", "PuttTTT", kGenMac },
|
|
{ "putttime", "PuttTTT", kGenPC },
|
|
{ "putttime", "TIJDDEMO", kGenPC },
|
|
{ "putttime", "timedemo", kGenPC },
|
|
{ "putttime", "TimeDemo", kGenMac },
|
|
{ "putttime", "TEMPDEMO", kGenPC },
|
|
{ "putttime", "Tempdemo", kGenMac }, // FR Mac demo
|
|
{ "putttime", "toffzeit", kGenPC }, // German Toeff-Toeff: Reist durch die Zeit
|
|
{ "putttime", "toffzeit", kGenMac }, // German Toeff-Toeff: Reist durch die Zeit
|
|
{ "putttime", "ZeitDemo", kGenMac },
|
|
{ "putttime", "ZEITDEMO", kGenPC },
|
|
{ "puttzoo", "Puttzoo Demo", kGenMac },
|
|
{ "puttzoo", "PuttZoo", kGenMac },
|
|
|
|
{ "puttzoo", "T\xC3\xB6""ff-T\xC3\xB6""ff\xE2\x84\xA2 Zoo Demo", kGenMac }, // German Toeff-Toeff, UTF-8 encoding
|
|
{ "puttzoo", "T\xF6""ff-T""\xF6""ff\x99 Zoo Demo", kGenMac }, // German Toeff-Toeff, Windows encoding
|
|
|
|
{ "puttzoo", "zoodemo", kGenPC },
|
|
{ "puttzoo", "Zoo Demo", kGenMac },
|
|
{ "SamsFunShop", "Sam's FunShop", kGenMac },
|
|
{ "soccer", "Soccer", kGenMac },
|
|
{ "Soccer2004", "Soccer 2004", kGenMac },
|
|
{ "socks", "SockWorks", kGenMac },
|
|
{ "spyfox", "Fuchsdem", kGenMac },
|
|
{ "spyfox", "FUCHSDEM", kGenPC},
|
|
{ "spyfox", "FoxDemo", kGenMac },
|
|
{ "spyfox", "foxdemo", kGenPC},
|
|
{ "spyfox", "JAMESDEM", kGenPC },
|
|
{ "spyfox", "Spydemo", kGenMac},
|
|
{ "spyfox", "Spydemo", kGenPC},
|
|
{ "spyfox", "SPYFox", kGenMac },
|
|
{ "spyfox", "SPYFoxDC", kGenPC },
|
|
{ "spyfox", "SPYFoxDC", kGenMac },
|
|
{ "spyfox", "SpyFoxDMK", kGenPC },
|
|
{ "spyfox", "SpyFoxDMK", kGenMac },
|
|
{ "spyfox", "Spy Fox Demo", kGenMac }, // NL Mac demo
|
|
{ "spyfox", "JR-Demo", kGenMac }, // FR Mac demo
|
|
{ "spyfox2", "sf2-demo", kGenPC },
|
|
{ "spyfox2", "sf2demo", kGenPC },
|
|
{ "spyfox2", "Sf2demo", kGenMac },
|
|
{ "spyfox2", "Spy Fox 2 - Demo", kGenMac },
|
|
{ "spyfox2", "Spy Fox 2", kGenMac },
|
|
{ "spyfox2", "SpyFoxOR", kGenPC },
|
|
{ "spyfox2", "SpyFoxOR", kGenMac },
|
|
{ "spyfox2", "spyfoxsr", kGenPC },
|
|
{ "spyozon", "sf3-demo", kGenPC },
|
|
{ "spyozon", "Spy Ozone Demo", kGenMac },
|
|
{ "spyozon", "SPYFoxOZU", kGenPC },
|
|
{ "spyozon", "SpyOzon", kGenMac },
|
|
{ "thinker1", "1grademo", kGenPC },
|
|
{ "thinker1", "Thinker1", kGenMac },
|
|
{ "thinkerk", "kinddemo", kGenPC },
|
|
{ "thinkerk", "KindDemo", kGenMac },
|
|
{ "thinkerk", "ThinkerK", kGenMac },
|
|
{ "water", "Water Worries", kGenMac },
|
|
#endif
|
|
{ NULL, NULL, kGenAsIs }
|
|
};
|
|
|
|
|
|
#if 0
|
|
|
|
enum FilenameGenMethod {
|
|
kGenDiskNum,
|
|
kGenRoomNum,
|
|
kGenHEMac,
|
|
kGenHEMacNoParens,
|
|
kGenHEPC,
|
|
kGenUnchanged
|
|
};
|
|
|
|
struct GameFilenamePattern {
|
|
const char *gameid;
|
|
const char *pattern;
|
|
FilenameGenMethod genMethod;
|
|
Common::Language language;
|
|
Common::Platform platform;
|
|
const char *variant;
|
|
};
|
|
|
|
using Common::UNK_LANG;
|
|
|
|
// The following describes how Fingolfin thinks this table might be used one day;
|
|
// this is work in progress, so read this with a salt of grain...
|
|
//
|
|
// The following table maps gameids to possible filename variants for that game.
|
|
// This information is used by the detector to determin possible "detect files".
|
|
// It is also later used by the engine creation code to verify the game to be
|
|
// launched is present. Finally, the correct GameFilenamePattern entry is passed on
|
|
// to the engine which uses it to locate the files for the game.
|
|
//
|
|
// The table is augmented by platform/language/variant information where applicable.
|
|
//
|
|
// Note: Setting variant to 0 means "don't care", while setting it to ""
|
|
// (i.e. an empty string) means "use the default variant".
|
|
static const GameFilenamePattern gameFilenamesTable[] = {
|
|
{ "maniac", "%.2d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "maniac", "%.2d.MAN", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "maniac", "maniac1.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, 0 }, // ... and maniac2.d64
|
|
{ "maniac", "Maniac Mansion (E).prg", kGenUnchanged, Common::EN_GRB, Common::kPlatformNES, "NES" },
|
|
{ "maniac", "Maniac Mansion (F).prg", kGenUnchanged, Common::FR_FRA, Common::kPlatformNES, "NES" },
|
|
{ "maniac", "Maniac Mansion (SW).prg", kGenUnchanged, Common::SE_SWE, Common::kPlatformNES, "NES" },
|
|
{ "maniac", "Maniac Mansion (U).prg", kGenUnchanged, Common::EN_USA, Common::kPlatformNES, "NES" },
|
|
{ "maniac", "Maniac Mansion (G).prg", kGenUnchanged, Common::DE_DEU, Common::kPlatformNES, "NES" },
|
|
|
|
{ "zak", "%.2d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "zak", "zak1.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, 0 }, // ... and zak2.d64
|
|
|
|
{ "indy3", "%.2d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
|
|
{ "loom", "%.2d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "loom", "%.3d.LFL", kGenRoomNum, UNK_LANG, UNK, "VGA" }, // Loom CD
|
|
|
|
{ "pass", "%.3d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
|
|
{ "monkey", "%.3d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 }, // EGA & VGA versions
|
|
{ "monkey", "monkey.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "monkey", "monkey1.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "monkey", "monkeyk.%.3d", kGenRoomNum, Common::JA_JPN, Common::kPlatformFMTowns, "FM-TOWNS" }, // FM-TOWNS Jap
|
|
{ "monkey", "game.%.3d", kGenRoomNum, UNK_LANG, Common::kPlatformSegaCD, "SEGA" }, // SegaCD
|
|
|
|
{ "monkey2", "monkey2.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "monkey2", "mi2demo.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
|
|
{ "atlantis", "atlantis.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "atlantis", "fate.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "atlantis", "playfate.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "atlantis", "indy4.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "atlantis", "indydemo.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "atlantis", "Fate of Atlantis Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "tentacle", "tentacle.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "tentacle", "dottdemo.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "tentacle", "Day of the Tentacle Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "tentacle", "Day of the Tentacle Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "samnmax", "samnmax.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "samnmax", "samnmax.sm%d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "samnmax", "Sam & Max Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "samnmax", "Sam & Max Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "samnmax", "ramnmax.%.3d", kGenRoomNum, Common::RU_RUS, UNK, 0 }, // Used in some releases of Russian Sam'n'Max
|
|
{ "samnmax", "samdemo.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "samnmax", "snmdemo.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "samnmax", "snmidemo.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
{ "samnmax", "sdemo.%.3d", kGenRoomNum, UNK_LANG, UNK, 0 },
|
|
|
|
#ifndef DISABLE_SCUMM_7_8
|
|
{ "dig", "dig.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
|
|
{ "dig", "The Dig Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "dig", "The Dig Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "ft", "ft.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
|
|
{ "ft", "ft.%.3d", kGenDiskNum, UNK_LANG, UNK, 0 }, // Used by PC version of Full Throttle demo
|
|
{ "ft", "ftdemo.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
|
|
{ "ft", "Full Throttle Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "ft", "Full Throttle Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "ft", "Vollgas Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "ft", "Vollgas Demo Data", kGenUnchanged, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "comi", "comi.la%d", kGenDiskNum, UNK_LANG, UNK, 0 },
|
|
#endif
|
|
|
|
{ "fbear", "fbear", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "fbear", "fbdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "fbear", "Fatty Bear Demo", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "fbear", "Fatty Bear", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "puttmoon", "puttmoon", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttmoon", "moondemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttmoon", "Putt-Putt Moon Demo", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "puttmoon", "Putt-Putt Moon", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "puttputt", "puttputt", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttputt", "puttdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttputt", "Putt-Putt's Demo", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "puttputt", "Putt-Putt Parade", kGenHEMacNoParens, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
#ifndef DISABLE_HE
|
|
{ "airport", "airport", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "airport", "airdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "airport", "Airport Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "airport", "The AirPort", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "balloon", "balloon", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "balloon", "Balloon-O-Rama", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "baseball", "baseball", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "baseball", "BaseBall", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "baseball2001", "baseball2001", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "baseball2001", "bb2demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "baseball2001", "Baseball 2001 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "baseball2001", "Baseball 2001", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "baseball2001", "baseball 2001", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
|
|
{ "Baseball2003", "Baseball2003", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "Baseball2003", "Baseball 2003", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "basketball", "basketball", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "basketball", "Basketball", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "bluesabctime", "bluesabctime", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "bluesabctime", "BluesABCTimeDemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "bluesabctime", "BluesABCTimeDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "catalog", "catalog", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "catalog", "catalog2", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
|
|
{ "chase", "chase", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "chase", "Cheese Chase", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "dog", "dog", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "dog", "Dog on a Stick", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "farm", "farm", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "farm", "farmdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "farm", "Farm Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "football", "football", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "football", "FootBall", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "football", "FootBall Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "football", "FootBall2002", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "football", "footdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
|
|
{ "freddi", "freddi", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi", "freddemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi", "Freddi Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi", "Freddi Fish", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi", "FreddiD", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
|
|
{ "freddi2", "freddi2", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi2", "ff2-demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi2", "FFHSDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi2", "FFHSDemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi2", "Freddi Fish 2 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi2", "Freddi Fish 2", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi2", "FreddiCHSH", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi2", "Fritzi Fisch 2", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, // FIXME: Is this a german version?
|
|
|
|
{ "freddi3", "freddi3", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi3", "F3-mdemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi3", "F3-Mdemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi3", "f3-mdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi3", "FF3-DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi3", "Freddi Fish 3", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi3", "FreddiFGT", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi3", "FreddiFGT", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi3", "FreddiSCS", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi3", "Fritzi3demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, // FIXME: Is this a german version?
|
|
{ "freddi3", "Fritzi3demo", kGenHEPC, UNK_LANG, UNK, 0 }, // FIXME: Is this a german version?
|
|
{ "freddi3", "MM3-DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi3", "MM3-Demo", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, // FR Mac demo
|
|
|
|
{ "freddi4", "freddi4", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi4", "f4-demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi4", "ff4demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi4", "Ff4demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi4", "Freddi 4", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi4", "Freddi 4 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi4", "FreddiGS", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddi4", "FreddiGS", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddi4", "FreddiHRBG", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
|
|
{ "freddicove", "freddicove", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddicove", "FreddiCCC", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddicove", "FreddiCove", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddicove", "FreddiDZZ", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddicove", "ff5demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddicove", "FFCoveDemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "freddicove", "FreddiCoveDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "freddicove", "FF5Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, // NL Mac demo
|
|
|
|
{ "FreddisFunShop", "FreddisFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "FreddisFunShop", "Freddi's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "jungle", "jungle", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "jungle", "The Jungle", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "lost", "lost", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "lost", "Lost and Found", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "lost", "smaller", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
|
|
{ "maze", "maze", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "maze", "Maze Madness", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "mustard", "mustard", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "mustard", "Mustard", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "pajama", "pajama", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama", "Pyjama Pit", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama", "Pajama Sam", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama", "PajamaNHD", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama", "PJS-DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama", "PYJAMA", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama", "SAMDEMO", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama", "SAMDEMO", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, // FR Mac demo
|
|
|
|
{ "pajama2", "pajama2", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama2", "Pajama Sam 2", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama2", "PajamaTAL", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama2", "PyjamaDBMN", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama2", "PyjamaDBMN", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama2", "Pyjama Pit 2 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama2", "PJP2DEMO", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama2", "PJ2Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama2", "pj2demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama2", "Pjs2demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama2", "PJ2 Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, // NL Mac demo
|
|
|
|
{ "pajama3", "pajama3", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama3", "GPJ3Demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama3", "Pajama Sam 3", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama3", "Pajama Sam 3-Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama3", "pj3-demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama3", "pj3demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama3", "PJ3Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama3", "Pajama Sam Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama3", "PjSamDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama3", "PjSamDemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama3", "PyjamaSKS", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pajama3", "PyjamaSKS", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "pajama3", "UKPajamaEAT", kGenHEPC, Common::RU_RUS, UNK, 0 }, // Russian
|
|
|
|
{ "pjgames", "pjgames", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "pjgames", "PJGames", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "puttcircus", "puttcircus", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttcircus", "circdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttcircus", "Putt Circus Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "puttcircus", "Putt Circus", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "puttrace", "puttrace", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttrace", "500demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttrace", "racedemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttrace", "RaceDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "puttrace", "Rennen", kGenHEPC, UNK_LANG, UNK, 0 }, // FIXME: Is this a german version?
|
|
{ "puttrace", "Putt500 demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, // NL Mac demo
|
|
{ "puttrace", "Putt Race", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "puttrace", "ToffRennen", kGenHEPC, UNK_LANG, UNK, 0 }, // FIXME: Is this a german version?
|
|
{ "puttrace", "ToffRennen", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, // FIXME: Is this a german version?
|
|
{ "puttrace", "UKPuttRace", kGenHEPC, Common::RU_RUS, UNK, 0 }, // Russian
|
|
|
|
{ "PuttsFunShop", "PuttsFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "PuttsFunShop", "Putt's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "putttime", "putttime", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "putttime", "PuttPuttTTT", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "putttime", "PuttPuttTTT", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "putttime", "PuttTijd", kGenHEPC, UNK_LANG, UNK, 0 }, // FIXME: Is this a dutch version?
|
|
{ "putttime", "Putt Time", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "putttime", "PuttTTT", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "putttime", "PuttTTT", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "putttime", "TIJDDEMO", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "putttime", "timedemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "putttime", "TimeDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "putttime", "TEMPDEMO", kGenHEPC, UNK_LANG, UNK, 0 }, // FIXME: Is this a french version?
|
|
{ "putttime", "Tempdemo", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, // FR Mac demo
|
|
{ "putttime", "toffzeit", kGenHEPC, Common::DE_DEU, UNK, 0 }, // German Toeff-Toeff: Reist durch die Zeit
|
|
{ "putttime", "toffzeit", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, // German Toeff-Toeff: Reist durch die Zeit
|
|
{ "putttime", "ZeitDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, // FIXME: Is this a german version?
|
|
{ "putttime", "ZEITDEMO", kGenHEPC, UNK_LANG, UNK, 0 }, // FIXME: Is this a german version?
|
|
|
|
{ "puttzoo", "puttzoo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttzoo", "Puttzoo Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "puttzoo", "PuttZoo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "puttzoo", "T\xC3\xB6""ff-T\xC3\xB6""ff\xE2\x84\xA2 Zoo Demo", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, // UTF-8 encoding
|
|
{ "puttzoo", "T\xF6""ff-T""\xF6""ff\x99 Zoo Demo", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, // Windows encoding
|
|
{ "puttzoo", "zoodemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "puttzoo", "Zoo Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "SamsFunShop", "SamsFunShop", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "SamsFunShop", "Sam's FunShop", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "soccer", "soccer", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "soccer", "Soccer", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "Soccer2004", "Soccer2004", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "Soccer2004", "Soccer 2004", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "socks", "socks", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "socks", "SockWorks", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "spyfox", "spyfox", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox", "Fuchsdem", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, // FIXME: Is this a german version?
|
|
{ "spyfox", "FUCHSDEM", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox", "FoxDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox", "foxdemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox", "JAMESDEM", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox", "Spydemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox", "Spydemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox", "SPYFox", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox", "SPYFoxDC", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox", "SPYFoxDC", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox", "SpyFoxDMK", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox", "SpyFoxDMK", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox", "Spy Fox Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, // NL Mac demo
|
|
{ "spyfox", "JR-Demo", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, // FR Mac demo
|
|
|
|
{ "spyfox2", "spyfox2", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox2", "sf2-demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox2", "sf2demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox2", "Sf2demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox2", "Spy Fox 2 - Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox2", "Spy Fox 2", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox2", "SpyFoxOR", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyfox2", "SpyFoxOR", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyfox2", "spyfoxsr", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
|
|
{ "spyozon", "spyozon", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyozon", "sf3-demo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyozon", "Spy Ozone Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "spyozon", "SPYFoxOZU", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "spyozon", "SpyOzon", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "thinker1", "thinker1", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "thinker1", "1grademo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "thinker1", "Thinker1", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "thinkerk", "thinkerk", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "thinkerk", "kinddemo", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "thinkerk", "KindDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
{ "thinkerk", "ThinkerK", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
|
|
{ "water", "water", kGenHEPC, UNK_LANG, UNK, 0 },
|
|
{ "water", "Water Worries", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 },
|
|
#endif
|
|
{ NULL, NULL, kGenUnchanged, UNK_LANG, UNK, 0 }
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark --- Miscellaneous ---
|
|
#pragma mark -
|
|
|
|
|
|
static const char *findDescriptionFromGameID(const char *gameid) {
|
|
const PlainGameDescriptor *g = gameDescriptions;
|
|
while (g->gameid) {
|
|
if (!scumm_stricmp(g->gameid, gameid)) {
|
|
return g->description;
|
|
}
|
|
g++;
|
|
}
|
|
error("Unknown gameid '%s' encountered in findDescriptionFromGameID", gameid);
|
|
}
|
|
|
|
static int compareMD5Table(const void *a, const void *b) {
|
|
const char *key = (const char *)a;
|
|
const MD5Table *elem = (const MD5Table *)b;
|
|
return strcmp(key, elem->md5);
|
|
}
|
|
|
|
const MD5Table *findInMD5Table(const char *md5) {
|
|
#ifdef PALMOS_68K
|
|
uint32 arraySize = MemPtrSize((void *)md5table) / sizeof(MD5Table) - 1;
|
|
#else
|
|
uint32 arraySize = ARRAYSIZE(md5table) - 1;
|
|
#endif
|
|
return (const MD5Table *)bsearch(md5, md5table, arraySize, sizeof(MD5Table), compareMD5Table);
|
|
}
|
|
|
|
#if 0
|
|
Common::String ScummEngine::generateFilename(const int room) const {
|
|
// HACK to drive test compiles; of course _substEntry would be a member var of ScummEngine
|
|
const GameFilenamePattern _substEntry = { "maniac", "%.2d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 };
|
|
const int diskNumber = room ? res.roomno[rtRoom][room] : 0;
|
|
char buf[128];
|
|
|
|
if (_game.version == 4) {
|
|
if (room == 0 || room >= 900) {
|
|
snprintf(buf, sizeof(buf), "%.3d.lfl", room);
|
|
} else {
|
|
snprintf(buf, sizeof(buf), "disk%.2d.lec", diskNumber);
|
|
}
|
|
} else {
|
|
char id = 0;
|
|
|
|
switch (_substEntry.genMethod) {
|
|
case kGenDiskNum:
|
|
snprintf(buf, sizeof(buf), _substEntry.pattern, diskNumber);
|
|
break;
|
|
|
|
case kGenRoomNum:
|
|
snprintf(buf, sizeof(buf), _substEntry.pattern, room);
|
|
break;
|
|
|
|
case kGenHEMac:
|
|
case kGenHEMacNoParens:
|
|
case kGenHEPC:
|
|
// FIXME: Not sure if the following HE section is quite correct...
|
|
if (_game.heversion >= 98) {
|
|
int disk = 0;
|
|
if (_heV7DiskOffsets)
|
|
disk = _heV7DiskOffsets[room];
|
|
|
|
switch(disk) {
|
|
case 2:
|
|
id = 'b';
|
|
snprintf(buf, sizeof(buf), "%s.(b)", _substEntry.pattern);
|
|
break;
|
|
case 1:
|
|
id = 'a';
|
|
snprintf(buf, sizeof(buf), "%s.(a)", _substEntry.pattern);
|
|
break;
|
|
default:
|
|
id = '0';
|
|
snprintf(buf, sizeof(buf), "%s.he0", _substEntry.pattern);
|
|
}
|
|
} else if (_game.heversion >= 70) {
|
|
id = (room == 0) ? '0' : '1';
|
|
} else {
|
|
id = diskNumber + '0';
|
|
}
|
|
|
|
if (_substEntry.genMethod == kGenHEPC) {
|
|
// For HE >= 98, we already called snprintf above.
|
|
if (_game.heversion < 98)
|
|
snprintf(buf, sizeof(buf), "%s.he%c", _substEntry.pattern, id);
|
|
} else {
|
|
if (id == '3') { // special case for cursors
|
|
// For mac they're stored in game binary
|
|
strncpy(buf, _substEntry.pattern, sizeof(buf));
|
|
} else {
|
|
if (_substEntry.genMethod == kGenHEMac)
|
|
snprintf(buf, sizeof(buf), "%s (%c)", _substEntry.pattern, id);
|
|
else
|
|
snprintf(buf, sizeof(buf), "%s %c", _substEntry.pattern, id);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
error("generateFilename: Unsupported genMethod");
|
|
}
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
Common::String generateFilenameForDetection(const GameFilenamePattern &gfp) {
|
|
char buf[128];
|
|
|
|
switch (gfp.genMethod) {
|
|
case kGenDiskNum:
|
|
case kGenRoomNum:
|
|
snprintf(buf, sizeof(buf), gfp.pattern, 0);
|
|
break;
|
|
|
|
case kGenHEPC:
|
|
snprintf(buf, sizeof(buf), "%s.he0", gfp.pattern);
|
|
break;
|
|
|
|
case kGenHEMac:
|
|
snprintf(buf, sizeof(buf), "%s (0)", gfp.pattern);
|
|
break;
|
|
|
|
case kGenHEMacNoParens:
|
|
snprintf(buf, sizeof(buf), "%s 0", gfp.pattern);
|
|
break;
|
|
|
|
default:
|
|
error("generateFilenameForDetection: Unsupported genMethod");
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
struct DetectorDesc {
|
|
Common::String path;
|
|
Common::String md5;
|
|
const MD5Table *md5Entry; // Entry of the md5 table corresponding to this file, if any.
|
|
};
|
|
|
|
|
|
struct DetectorResult {
|
|
const GameFilenamePattern *gfp;
|
|
GameSettings game;
|
|
};
|
|
|
|
void detectGames(const char *gameid_XXX, const FSList &fslist, Common::List<DetectorResult> &results) {
|
|
typedef Common::HashMap<Common::String, DetectorDesc> DescMap;
|
|
DescMap fileMD5Map;
|
|
const GameSettings *g;
|
|
|
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
|
if (!file->isDirectory()) {
|
|
DetectorDesc d;
|
|
d.path = file->path();
|
|
d.md5Entry = 0;
|
|
fileMD5Map[file->displayName()] = d;
|
|
}
|
|
}
|
|
|
|
// Iterate over all filename patterns.
|
|
for (const GameFilenamePattern *gfp = gameFilenamesTable; gfp->gameid; ++gfp) {
|
|
// If gameid_XXX was specified, we only try to detect that specific game,
|
|
// so we can just skip over everything with a differing gameid.
|
|
if (gameid_XXX && scumm_stricmp(gameid_XXX, gfp->gameid))
|
|
continue;
|
|
|
|
// Generate the detectname corresponding to the gfp. If the file doesn't
|
|
// exist in the directory we are looking at, we can skip to the next
|
|
// one immediately.
|
|
Common::String file(generateFilenameForDetection(*gfp));
|
|
if (!fileMD5Map.contains(file))
|
|
continue;
|
|
|
|
// OK, the file is present. Compute the MD5, if it hasn't been done yet.
|
|
DetectorDesc &d = fileMD5Map[file];
|
|
if (d.md5.empty()) {
|
|
uint8 md5sum[16];
|
|
if (Common::md5_file(d.path.c_str(), md5sum, kMD5FileSizeLimit)) {
|
|
char md5str[32+1];
|
|
for (int j = 0; j < 16; j++) {
|
|
sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
|
|
}
|
|
|
|
d.md5 = md5str;
|
|
d.md5Entry = findInMD5Table(md5str);
|
|
|
|
if (d.md5Entry) {
|
|
// Exact match found
|
|
|
|
// Sanity check: Make sure the gameids match!
|
|
if (scumm_stricmp(d.md5Entry->gameid, gfp->gameid)) {
|
|
error("SCUMM detectGames: MD5 %s implies gameid '%s', but gameid '%s' was expected",
|
|
md5str, d.md5Entry->gameid, gfp->gameid);
|
|
}
|
|
|
|
DetectorResult dr;
|
|
dr.game.gameid = 0;
|
|
dr.gfp = gfp;
|
|
|
|
// Compute the precise game settings using gameVariantsTable.
|
|
for (g = gameVariantsTable; g->gameid; ++g) {
|
|
if (g->gameid[0] == 0 || !scumm_stricmp(d.md5Entry->gameid, g->gameid)) {
|
|
// The gameid either matches, or is empty (the latter indicates
|
|
// a generic entry, used currently for generic HE specifies.
|
|
|
|
if (g->variant == 0 || !scumm_stricmp(d.md5Entry->variant, g->variant)) {
|
|
// Perfect match found, use it and stop the loop
|
|
dr.game = *g;
|
|
dr.game.gameid = gfp->gameid;
|
|
if (d.md5Entry->platform != Common::kPlatformUnknown) {
|
|
if (dr.game.platform != Common::kPlatformUnknown && dr.game.platform != d.md5Entry->platform)
|
|
warning("SCUMM detectGames: Platform values differ for MD5 '%s': %d vs %d (please report to Fingolfin)",
|
|
md5str, dr.game.platform, d.md5Entry->platform);
|
|
dr.game.platform = d.md5Entry->platform;
|
|
}
|
|
results.push_back(dr);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sanity check: We *should* have found a matching gameid / variant at this point.
|
|
// If not, then there's a bug in our data tables...
|
|
assert(dr.game.gameid != 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// If an exact match for this file has already been found, don't bother
|
|
// looking at it anymore.
|
|
if (d.md5Entry != 0)
|
|
continue;
|
|
|
|
// At this point, the MD5 sum has been computed but is not known. We
|
|
// still do our best to identify the game & variant correctly.
|
|
|
|
// First step is to determine the correct gameid. Luckily, in most
|
|
// cases the filename alone implies the gameid. Currently the only
|
|
// exceptions are 00.LFL and 000.LFL, for which we add special cases
|
|
// below.
|
|
|
|
// After that, we may take a peek at the file contents to further
|
|
// narrow down the list of variants.
|
|
|
|
// TODO: Should we do some sort of caching on the data we read? Like,
|
|
// keep a copy of the first N bytes ?
|
|
|
|
Common::File tmp;
|
|
if (!tmp.open(d.path.c_str())) {
|
|
warning("SCUMM detectGames: failed to open '%s' for read access", d.path.c_str());
|
|
continue;
|
|
}
|
|
byte buf[6];
|
|
tmp.read(buf, 6);
|
|
|
|
if (file == "00.LFL") {
|
|
// Used in V1, V2, V3 games.
|
|
|
|
if (buf[0] == 0xbc && buf[1] == 0xb9) {
|
|
// The NES version of MM
|
|
// TODO
|
|
} else if (buf[0] == 0xCE && buf[1] == 0xF5) {
|
|
// Looks like V1.
|
|
|
|
// Candidates: maniac classic, zak classic
|
|
|
|
// TODO: Maybe we can use the filesize to distinguish these two?
|
|
// English V1 Zak: 1896 bytes
|
|
// English V1 MM: 1972 bytes
|
|
|
|
// Since it seems unlikely that there are other (official)
|
|
// variants of these two games around, it should be safe to use
|
|
// the filesize for detection. In case of an unknown size,
|
|
// we just generate a warning and skip the file.
|
|
} else if (buf[0] == 0xFF && buf[1] == 0xFE) {
|
|
// GF_OLD_BUNDLE: could be V2 or old V3.
|
|
// Candidates: maniac enhanced, zak enhanced, indy3ega, loom
|
|
/*
|
|
TODO: Might be possible to distinguish those by the script count.
|
|
Specifically, my versions of these games have this in their headers:
|
|
|
|
Loom (en; de; en demo; en MAC):
|
|
_numGlobalObjects 1000
|
|
_numRooms 100
|
|
_numCostumes 200
|
|
_numScripts 200
|
|
_numSounds 80
|
|
|
|
Indy3EGA (en PC; en Mac; en demo):
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 129
|
|
_numScripts 139
|
|
_numSounds 84
|
|
|
|
MM (en; de):
|
|
_numGlobalObjects 780
|
|
_numRooms 61
|
|
_numCostumes 40
|
|
_numScripts 179
|
|
_numSounds 120
|
|
|
|
Zak (de; en demo):
|
|
_numGlobalObjects 780
|
|
_numRooms 61
|
|
_numCostumes 40
|
|
_numScripts 155
|
|
_numSounds 120
|
|
|
|
So, they all have a different number of scripts.
|
|
*/
|
|
} else if (buf[4] == '0' && buf[5] == 'R') {
|
|
// newer V3 game
|
|
// Candidates: indy3, indy3Towns, zakTowns, loomTowns
|
|
/*
|
|
Considering that we know about *all* TOWNS versions,
|
|
and know their MD5s, we could simply rely on this and
|
|
if we find something which has an unknown MD5, assume
|
|
that it is an (so far unknown) version of Indy3.
|
|
|
|
We can combine this with a look at the resource headers:
|
|
|
|
Indy3:
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 129
|
|
_numScripts 139
|
|
_numSounds 84
|
|
|
|
Indy3Towns, ZakTowns, ZakLoom demo:
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 199
|
|
_numScripts 199
|
|
_numSounds 199
|
|
|
|
Assuming that all the town variants look like the latter, we can
|
|
do the check like this:
|
|
if (numScripts == 139)
|
|
assume Indy3
|
|
else if (numScripts == 199)
|
|
assume towns game
|
|
else
|
|
unknown, do not accept it
|
|
*/
|
|
} else {
|
|
// TODO: Unknown file header, deal with it. Maybe an unencrypted
|
|
// variant...
|
|
// Anyway, we don't know to deal with the file, so we
|
|
// just skip it.
|
|
}
|
|
} else if (file == "000.LFL") {
|
|
// Used in V4
|
|
// Candidates: monkeyEGA, pass, monkeyVGA, loomcd
|
|
/*
|
|
For all of them, we have:
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 199
|
|
_numScripts 199
|
|
_numSounds 199
|
|
|
|
Any good ideas to distinguish those? Maybe by the presence / absence
|
|
of some files?
|
|
At least PASS and the monkeyEGA demo differ by 903.LFL missing...
|
|
And the count of DISK??.LEC files differs depending on what version
|
|
you have (4 or 8 floppy versions).
|
|
loomcd of course shipped on only one "disc".
|
|
|
|
pass: 000.LFL, 901.LFL, 902.LFL, 904.LFL, disk01.lec
|
|
monkeyEGA: 000.LFL, 901-904.LFL, DISK01-09.LEC
|
|
monkeyEGA DEMO: 000.LFL, 901.LFL, 902.LFL, 904.LFL, disk01.lec
|
|
monkeyVGA: 000.LFL, 901-904.LFL, DISK01-04.LEC
|
|
loomcd: 000.LFL, 901-904.LFL, DISK01.LEC
|
|
*/
|
|
} else {
|
|
// So at this point the gameid is determined, but not necessarily
|
|
// the variant!
|
|
|
|
// TODO: Add code that does this, at least for the non-HE games.
|
|
// Note sure how realistic it is to correctly detect HE-game
|
|
// variants, would require me to look at a sufficiently large
|
|
// sample collection of HE games (assuming I had the time :).
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark --- Filename substitution ---
|
|
#pragma mark -
|
|
|
|
|
|
static void applySubstResFileName(const SubstResFileNames &subst, char *buf, int bufsize, const char *ext, char num) {
|
|
switch (subst.genMethod) {
|
|
case kGenMac:
|
|
case kGenMacNoParens:
|
|
if (num == '3') { // special case for cursors
|
|
// For mac they're stored in game binary
|
|
strncpy(buf, subst.expandedName, bufsize);
|
|
} else {
|
|
if (subst.genMethod == kGenMac)
|
|
snprintf(buf, bufsize, "%s (%c)", subst.expandedName, num);
|
|
else
|
|
snprintf(buf, bufsize, "%s %c", subst.expandedName, num);
|
|
}
|
|
break;
|
|
|
|
case kGenPC:
|
|
if (ext)
|
|
snprintf(buf, bufsize, "%s%s", subst.expandedName, ext);
|
|
else
|
|
strncpy(buf, subst.expandedName, bufsize);
|
|
break;
|
|
|
|
case kGenAsIs:
|
|
strncpy(buf, subst.expandedName, bufsize);
|
|
break;
|
|
|
|
default:
|
|
*buf = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool applySubstResFileName(const SubstResFileNames &subst, const char *filename, char *buf, int bufsize) {
|
|
if (subst.almostGameID == 0)
|
|
return false;
|
|
|
|
size_t len = strlen(filename);
|
|
assert(len > 0);
|
|
|
|
char num = filename[len - 1];
|
|
|
|
// In some cases we have .(a) and .(b) extensions
|
|
if (num == ')')
|
|
num = filename[len - 2];
|
|
|
|
const char *ext = strrchr(filename, '.');
|
|
if (ext)
|
|
len = ext - filename;
|
|
|
|
if (!scumm_strnicmp(filename, subst.almostGameID, len)) {
|
|
applySubstResFileName(subst, buf, bufsize, ext, num);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int findSubstResFileName(SubstResFileNames &subst, const char *filename, int index) {
|
|
if (index < 0)
|
|
return -1;
|
|
|
|
size_t len = strlen(filename);
|
|
assert(len > 0);
|
|
|
|
char num = filename[len - 1];
|
|
|
|
// In some cases we have .(a) and .(b) extensions
|
|
if (num == ')')
|
|
num = filename[len - 2];
|
|
|
|
const char *ext = strrchr(filename, '.');
|
|
if (ext)
|
|
len = ext - filename;
|
|
|
|
int i;
|
|
for (i = index; substResFileNameTable[i].almostGameID; i++) {
|
|
if (!scumm_strnicmp(filename, substResFileNameTable[i].almostGameID, len)) {
|
|
subst = substResFileNameTable[i];
|
|
return i+1;
|
|
}
|
|
}
|
|
subst = substResFileNameTable[i];
|
|
return -1;
|
|
}
|
|
|
|
} // End of namespace Scumm
|
|
|
|
#pragma mark -
|
|
#pragma mark --- Plugin code ---
|
|
#pragma mark -
|
|
|
|
|
|
using namespace Scumm;
|
|
|
|
|
|
GameList Engine_SCUMM_gameIDList() {
|
|
const PlainGameDescriptor *g = gameDescriptions;
|
|
GameList games;
|
|
while (g->gameid) {
|
|
games.push_back(GameDescriptor(g->gameid, g->description));
|
|
g++;
|
|
}
|
|
return games;
|
|
}
|
|
|
|
GameDescriptor Engine_SCUMM_findGameID(const char *gameid) {
|
|
// First search the list of supported game IDs.
|
|
const PlainGameDescriptor *g = gameDescriptions;
|
|
while (g->gameid) {
|
|
if (0 == scumm_stricmp(gameid, g->gameid))
|
|
return GameDescriptor(g->gameid, g->description);
|
|
g++;
|
|
}
|
|
|
|
// If we didn't find the gameid in the main list, check if it
|
|
// is an obsolete game id.
|
|
GameDescriptor gs;
|
|
const ObsoleteGameID *o = obsoleteGameIDsTable;
|
|
while (o->from) {
|
|
if (0 == scumm_stricmp(gameid, o->from)) {
|
|
gs.gameid = gameid;
|
|
gs.description = "Obsolete game ID";
|
|
return gs;
|
|
}
|
|
o++;
|
|
}
|
|
return gs;
|
|
}
|
|
|
|
|
|
enum {
|
|
kDetectNameMethodsCount = 8
|
|
};
|
|
|
|
static bool generateDetectName(const GameSettings &g, int method, char *detectName) {
|
|
detectName[0] = '\0';
|
|
|
|
switch (method) {
|
|
case 0:
|
|
if (g.version <= 3)
|
|
strcpy(detectName, "00.LFL");
|
|
break;
|
|
case 1:
|
|
// FIXME: The following would normally only allow for V4 games. But
|
|
// for loom, there is both a v3 and a v4 version, but due to the way
|
|
// the detector works at this time, we'll only ever see the v3 variant
|
|
// here.
|
|
if (g.version == 3 || g.version == 4)
|
|
strcpy(detectName, "000.LFL");
|
|
break;
|
|
case 2:
|
|
if (g.version < 4 || g.version > 7)
|
|
return false;
|
|
strcpy(detectName, g.gameid);
|
|
strcat(detectName, ".000");
|
|
break;
|
|
case 3:
|
|
if (g.version >= 7) {
|
|
strcpy(detectName, g.gameid);
|
|
strcat(detectName, ".la0");
|
|
}
|
|
break;
|
|
case 4:
|
|
if (g.heversion != 0) {
|
|
strcpy(detectName, g.gameid);
|
|
strcat(detectName, ".he0");
|
|
}
|
|
break;
|
|
case 5:
|
|
// FIXME: Fingolfin asks: For which games is this case used?
|
|
// Please document this. Also: Why was this case missing in
|
|
// Engine_SCUMM_create ?
|
|
strcpy(detectName, g.gameid);
|
|
break;
|
|
case 6:
|
|
if (g.id == GID_SAMNMAX) {
|
|
strcpy(detectName, g.gameid);
|
|
strcat(detectName, ".sm0");
|
|
}
|
|
break;
|
|
case 7:
|
|
if (g.id == GID_MANIAC)
|
|
strcpy(detectName, "00.MAN");
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
if (!detectName[0])
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
DetectedGameList Engine_SCUMM_detectGames(const FSList &fslist) {
|
|
DetectedGameList detectedGames;
|
|
const GameSettings *g;
|
|
char detectName[128];
|
|
char tempName[128];
|
|
SubstResFileNames subst = { 0, 0, kGenAsIs };
|
|
|
|
typedef Common::HashMap<Common::String, bool> StringSet;
|
|
StringSet fileSet;
|
|
|
|
const char *lastGameid = "";
|
|
|
|
for (g = gameVariantsTable; g->gameid; ++g) {
|
|
// HACK: For now we only consider the first ("default") variant for
|
|
// gameids that have multiple variants. In a future version of the
|
|
// detector code, this may change.
|
|
if (0 == strcmp(lastGameid, g->gameid) || *(g->gameid) == 0)
|
|
continue;
|
|
lastGameid = g->gameid;
|
|
|
|
// Determine the 'detectname' for this game, that is, the name of a
|
|
// file that *must* be presented if the directory contains the data
|
|
// for this game. For example, FOA requires atlantis.000
|
|
|
|
// TODO: we need to add cache here
|
|
for (int method = 0; method < kDetectNameMethodsCount; method++) {
|
|
if (!generateDetectName(*g, method, detectName))
|
|
continue;
|
|
|
|
strcpy(tempName, detectName);
|
|
|
|
int substLastIndex = 0;
|
|
|
|
do {
|
|
// Iterate over all files in the given directory
|
|
for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
|
|
if (!file->isDirectory()) {
|
|
const char *name = file->displayName().c_str();
|
|
|
|
if (0 == scumm_stricmp(detectName, name)) {
|
|
byte buf[6];
|
|
|
|
if (g->version < 4) {
|
|
// We take a look at the file now, to narrow
|
|
// down the list of possible candidates a bit further.
|
|
// E.g. it's trivial to distinguish V1 from V3 games.
|
|
Common::File tmp;
|
|
if (!tmp.open(file->path().c_str()))
|
|
break;
|
|
tmp.read(buf, 6);
|
|
|
|
if (buf[0] == 0xCE && buf[1] == 0xF5) {
|
|
// Looks like V1. However, we currently do not distinguish between V1 and V2
|
|
// in the scumm_settings list.
|
|
if (g->version != 1 && g->version != 2)
|
|
break;
|
|
|
|
// Candidates: maniac clasic, zak classic
|
|
|
|
// TODO: Maybe we can use the filesize to distinguish these two?
|
|
// English V1 Zak: 1896 bytes
|
|
// English V1 MM: 1972 bytes
|
|
// It would be interesting if those sizes are the same for other language
|
|
// variants of these games, or for demos?
|
|
} else if (buf[0] == 0xFF && buf[1] == 0xFE) {
|
|
// GF_OLD_BUNDLE: could be V2 or old V3.
|
|
if (!(g->features & GF_OLD_BUNDLE) || (g->version != 2 && g->version != 3))
|
|
break;
|
|
// Candidates: maniac enhanced, zak enhanced, indy3ega, loom
|
|
/*
|
|
TODO: Might be possible to distinguish those by the script count.
|
|
Specifically, my versions of these games have this in their headers:
|
|
|
|
Loom (en; de; en demo; en MAC):
|
|
_numGlobalObjects 1000
|
|
_numRooms 100
|
|
_numCostumes 200
|
|
_numScripts 200
|
|
_numSounds 80
|
|
|
|
Indy3EGA (en PC; en Mac; en demo):
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 129
|
|
_numScripts 139
|
|
_numSounds 84
|
|
|
|
MM (en; de):
|
|
_numGlobalObjects 780
|
|
_numRooms 61
|
|
_numCostumes 40
|
|
_numScripts 179
|
|
_numSounds 120
|
|
|
|
Zak (de; en demo):
|
|
_numGlobalObjects 780
|
|
_numRooms 61
|
|
_numCostumes 40
|
|
_numScripts 155
|
|
_numSounds 120
|
|
|
|
So, they all have a different number of scripts.
|
|
*/
|
|
} else if (buf[4] == '0' && buf[5] == 'R') {
|
|
// newer V3 game
|
|
if (g->version != 3)
|
|
break;
|
|
// Candidates: indy3, indy3Towns, zakTowns, loomTowns
|
|
/*
|
|
Considering that we know about *all* TOWNS versions,
|
|
and know their MD5s, we could simply rely on this and
|
|
if we find something which has an unknown MD5, assume
|
|
that it is an (so far unknown) version of Indy3.
|
|
|
|
We can combine this with a look at the resource headers:
|
|
|
|
Indy3:
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 129
|
|
_numScripts 139
|
|
_numSounds 84
|
|
|
|
Indy3Towns, ZakTowns, ZakLoom demo:
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 199
|
|
_numScripts 199
|
|
_numSounds 199
|
|
|
|
Assuming that all the town variants look like the latter, we can
|
|
do the check like this:
|
|
if (numScripts == 139)
|
|
assume Indy3
|
|
else if (numScripts == 199)
|
|
assume towns game
|
|
else
|
|
unknown, do not accept it
|
|
*/
|
|
} else if (buf[4] == 'R' && buf[5] == 'N') {
|
|
// V4 game
|
|
if (g->version != 4)
|
|
break;
|
|
// Candidates: monkeyEGA, pass, monkeyVGA, loomcd
|
|
/*
|
|
For all of them, we have:
|
|
_numGlobalObjects 1000
|
|
_numRooms 99
|
|
_numCostumes 199
|
|
_numScripts 199
|
|
_numSounds 199
|
|
*/
|
|
} else if (buf[0] == 0xa0 && buf[1] == 0x07 && buf[2] == 0xa5 &&
|
|
buf[3] == 0xbc) {
|
|
// MM NES .prg
|
|
if (g->id != GID_MANIAC)
|
|
break;
|
|
} else if (buf[0] == 0xbc && buf[1] == 0xb9) {
|
|
// MM NES 00.LFL
|
|
if (g->id != GID_MANIAC)
|
|
break;
|
|
} else if (buf[0] == 0x31 && buf[1] == 0x0a) {
|
|
// C64 MM & Zak disk1
|
|
if (g->version != 2)
|
|
break;
|
|
} else if (buf[0] == 0xcd && buf[1] == 0xfe) {
|
|
// C64 MM & Zak 00.LFL
|
|
if (g->version != 2)
|
|
break;
|
|
} else {
|
|
// This is not a V1-V4 game
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Match found, add to list of candidates, then abort inner loop.
|
|
DetectedGame dg(g->gameid, findDescriptionFromGameID(g->gameid));
|
|
if (substLastIndex > 0 && // HE Mac versions.
|
|
(subst.genMethod == kGenMac ||
|
|
subst.genMethod == kGenMacNoParens)) {
|
|
dg.platform = Common::kPlatformMacintosh;
|
|
fileSet[file->path()] = true;
|
|
} else if (substLastIndex == 0 && g->id == GID_MANIAC &&
|
|
(buf[0] == 0xbc || buf[0] == 0xa0)) {
|
|
dg.platform = Common::kPlatformNES;
|
|
} else if ((g->id == GID_MANIAC || g->id == GID_ZAK) &&
|
|
((buf[0] == 0x31 && buf[1] == 0x0a) ||
|
|
(buf[0] == 0xcd && buf[1] == 0xfe))) {
|
|
dg.platform = Common::kPlatformC64;
|
|
} else {
|
|
fileSet[file->path()] = false;
|
|
}
|
|
|
|
dg.updateDesc(); // Append the platform, if set, to the description.
|
|
|
|
detectedGames.push_back(dg);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
substLastIndex = findSubstResFileName(subst, tempName, substLastIndex);
|
|
applySubstResFileName(subst, tempName, detectName, sizeof(detectName));
|
|
} while (subst.almostGameID != 0);
|
|
}
|
|
}
|
|
|
|
// Now, we check the MD5 sums of the 'candidate' files. If we have an exact match,
|
|
// only return that.
|
|
bool exactMatch = false;
|
|
for (StringSet::const_iterator iter = fileSet.begin(); iter != fileSet.end(); ++iter) {
|
|
uint8 md5sum[16];
|
|
const char *name = iter->_key.c_str();
|
|
|
|
if (Common::md5_file(name, md5sum, kMD5FileSizeLimit)) {
|
|
char md5str[32+1];
|
|
for (int j = 0; j < 16; j++) {
|
|
sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
|
|
}
|
|
|
|
const MD5Table *elem = findInMD5Table(md5str);
|
|
if (elem) {
|
|
if (!exactMatch)
|
|
detectedGames.clear(); // Clear all the non-exact candidates
|
|
|
|
DetectedGame dg(elem->gameid, findDescriptionFromGameID(elem->gameid), elem->language);
|
|
if (iter->_value == true) // This was HE Mac game
|
|
dg.platform = Common::kPlatformMacintosh;
|
|
else
|
|
dg.platform = elem->platform;
|
|
dg.updateDesc(elem->extra); // Append extra information to the description.
|
|
|
|
// Insert the 'enhanced' game data into the candidate list
|
|
detectedGames.push_back(dg);
|
|
|
|
exactMatch = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return detectedGames;
|
|
}
|
|
|
|
/**
|
|
* Create a ScummEngine instance, based on the given detector data.
|
|
*
|
|
* This is heavily based on our MD5 detection scheme.
|
|
*/
|
|
Engine *Engine_SCUMM_create(OSystem *syst) {
|
|
Engine *engine;
|
|
const char *gameid = ConfMan.get("gameid").c_str();
|
|
|
|
// We start by checking whether the specified game ID is obsolete.
|
|
// If that is the case, we automatically upgrade the target to use
|
|
// the correct new game ID (and platform, if specified).
|
|
for (const ObsoleteGameID *o = obsoleteGameIDsTable; o->from; ++o) {
|
|
if (!scumm_stricmp(gameid, o->from)) {
|
|
// Match found, perform upgrade
|
|
gameid = o->to;
|
|
ConfMan.set("gameid", o->to);
|
|
|
|
if (o->platform != Common::kPlatformUnknown)
|
|
ConfMan.set("platform", Common::getPlatformCode(o->platform));
|
|
|
|
warning("Target upgraded from game ID %s to %s", o->from, o->to);
|
|
ConfMan.flushToDisk();
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Lookup the game ID in our database. If this lookup fails, then
|
|
// the game ID is unknown, and we have to abort.
|
|
const GameSettings *g = gameVariantsTable;
|
|
while (g->gameid) {
|
|
if (!scumm_stricmp(gameid, g->gameid))
|
|
break;
|
|
g++;
|
|
}
|
|
if (!g->gameid) {
|
|
return 0;
|
|
}
|
|
|
|
// We now want to calculate the MD5 of the games detection file, so that we
|
|
// can store it in savegames etc..
|
|
gameid = g->gameid;
|
|
char detectName[256], tempName[256];
|
|
uint8 md5sum[16];
|
|
SubstResFileNames subst = { 0, 0, kGenAsIs };
|
|
bool found = false;
|
|
|
|
GameSettings game = *g;
|
|
|
|
// To this end, we first have to figure out what the proper detection file
|
|
// is (00.LFL, 000.LFL, ...). So we iterate over all possible names,
|
|
// and once we find a matching file, we assume that's it.
|
|
for (int method = 0; method < kDetectNameMethodsCount && !found; method++) {
|
|
if (!generateDetectName(game, method, detectName))
|
|
continue;
|
|
|
|
strcpy(tempName, detectName);
|
|
|
|
int substLastIndex = 0;
|
|
do {
|
|
// FIXME: Repeatedly calling File::exists like this is a bad idea.
|
|
// Instead, use the fs.h code to get a list of all files in that
|
|
// directory and simply check whether that filename is contained
|
|
// in it.
|
|
if (Common::File::exists(detectName)) {
|
|
found = true;
|
|
break;
|
|
}
|
|
|
|
substLastIndex = findSubstResFileName(subst, tempName, substLastIndex);
|
|
applySubstResFileName(subst, tempName, detectName, sizeof(detectName));
|
|
} while (subst.almostGameID != 0);
|
|
|
|
if (found) {
|
|
if (subst.almostGameID != 0)
|
|
debug(5, "Generated filename substitute: %s -> %s", tempName, detectName);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Unable to locate game data
|
|
if (!found) {
|
|
return 0;
|
|
}
|
|
|
|
// Force game to have Mac platform if needed
|
|
if (subst.almostGameID) {
|
|
if (subst.genMethod == kGenMac ||
|
|
subst.genMethod == kGenMacNoParens)
|
|
game.platform = Common::kPlatformMacintosh;
|
|
}
|
|
|
|
// Determine a MD5 checksum which then is used to narrow down the choice
|
|
// of game variants.
|
|
const char *md5 = NULL;
|
|
char md5buf[33];
|
|
|
|
// First, check if the MD5 was overridden with a config file entry.
|
|
if (ConfMan.hasKey("target_md5")) {
|
|
assert(ConfMan.get("target_md5").size() == 32);
|
|
md5 = ConfMan.get("target_md5").c_str();
|
|
} else {
|
|
// Next, check if the MD5 was overridden via a target_md5.txt file.
|
|
Common::File target_md5F;
|
|
target_md5F.open("target_md5.txt");
|
|
|
|
if (target_md5F.isOpen()) {
|
|
bool valid = true;
|
|
|
|
target_md5F.readLine(md5buf, 33);
|
|
for (int j = 0; j < 32 && valid; ++j)
|
|
if (!((md5buf[j] >= '0' && md5buf[j] <= '9') ||
|
|
(md5buf[j] >= 'A' && md5buf[j] <= 'F') ||
|
|
(md5buf[j] >= 'a' && md5buf[j] <= 'f')))
|
|
valid = false;
|
|
|
|
if (valid)
|
|
md5 = md5buf;
|
|
}
|
|
}
|
|
|
|
// Finally, if no MD5 value has been determined so far, compute it from the
|
|
// detect file.
|
|
if (!md5) {
|
|
// Compute the MD5 of the file, and (if we succeeded) store a hex version
|
|
// of it in gameMD5 (useful to print it to the user in messages).
|
|
if (Common::md5_file(detectName, md5sum, kMD5FileSizeLimit)) {
|
|
for (int j = 0; j < 16; j++) {
|
|
sprintf(md5buf + j*2, "%02x", (int)md5sum[j]);
|
|
}
|
|
}
|
|
md5 = md5buf;
|
|
}
|
|
|
|
|
|
|
|
// Now look up the MD5 in our lookup table (md5table).
|
|
const MD5Table *elem = findInMD5Table(md5);
|
|
|
|
|
|
// If a match was found, we use the information obtained from the md5table
|
|
// to walk through the gameVariantsTable array and find a match there.
|
|
// Otherwise, we print a warning about the MD5 being unknwon.
|
|
if (elem) {
|
|
// The MD5 is known and was found in our md5table.
|
|
debug(5, "Using MD5 '%s'", md5);
|
|
|
|
// Sanity check: Make sure the gameids match!
|
|
if (scumm_stricmp(elem->gameid, gameid)) {
|
|
error("MD5 %s implies gameid '%s', but gameid '%s' was used",
|
|
md5, elem->gameid, gameid);
|
|
}
|
|
|
|
// Compute the precise game settings using gameVariantsTable.
|
|
for (g = gameVariantsTable; g->gameid; ++g) {
|
|
if (g->gameid[0] == 0 || !scumm_stricmp(elem->gameid, g->gameid)) {
|
|
// The gameid either matches, or is empty (the latter indicates
|
|
// a generic entry, used currently for generic HE specifies.
|
|
|
|
if (g->variant == 0 || !scumm_stricmp(elem->variant, g->variant)) {
|
|
// Perfect match found, use it and stop the loop
|
|
game = *g;
|
|
game.gameid = gameid;
|
|
if (elem->platform != Common::kPlatformUnknown) {
|
|
if (game.platform != Common::kPlatformUnknown && game.platform != elem->platform)
|
|
warning("Platform values differ for MD5 '%s': %d vs %d (please report to Fingolfin)",
|
|
md5, game.platform, elem->platform);
|
|
game.platform = elem->platform;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
printf("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5);
|
|
}
|
|
|
|
|
|
|
|
// Check for a user override of the platform. We allow the user to override
|
|
// the platform, to make it possible to add games which are not yet in
|
|
// our MD5 database but require a specific platform setting.
|
|
if (ConfMan.hasKey("platform"))
|
|
game.platform = Common::parsePlatform(ConfMan.get("platform"));
|
|
|
|
|
|
// V3 FM-TOWNS games *always* should use the corresponding music driver,
|
|
// anything else makes no sense for them.
|
|
if (game.platform == Common::kPlatformFMTowns && game.version == 3) {
|
|
game.midi = MDT_TOWNS;
|
|
}
|
|
|
|
// Finally, we have massaged the GameDescriptor to our satisfaction, and can
|
|
// instantiate the appropriate game engine. Hooray!
|
|
switch (game.version) {
|
|
case 1:
|
|
case 2:
|
|
if (game.id == GID_MANIAC && game.platform == Common::kPlatformC64)
|
|
engine = new ScummEngine_c64(syst, game, md5sum, subst);
|
|
else
|
|
engine = new ScummEngine_v2(syst, game, md5sum, subst);
|
|
break;
|
|
case 3:
|
|
if (game.features & GF_OLD_BUNDLE)
|
|
engine = new ScummEngine_v3old(syst, game, md5sum, subst);
|
|
else
|
|
engine = new ScummEngine_v3(syst, game, md5sum, subst);
|
|
break;
|
|
case 4:
|
|
engine = new ScummEngine_v4(syst, game, md5sum, subst);
|
|
break;
|
|
case 5:
|
|
engine = new ScummEngine_v5(syst, game, md5sum, subst);
|
|
break;
|
|
case 6:
|
|
switch (game.heversion) {
|
|
#ifndef DISABLE_HE
|
|
case 100:
|
|
engine = new ScummEngine_v100he(syst, game, md5sum, subst);
|
|
break;
|
|
case 99:
|
|
engine = new ScummEngine_v99he(syst, game, md5sum, subst);
|
|
break;
|
|
case 98:
|
|
case 95:
|
|
case 90:
|
|
engine = new ScummEngine_v90he(syst, game, md5sum, subst);
|
|
break;
|
|
case 80:
|
|
engine = new ScummEngine_v80he(syst, game, md5sum, subst);
|
|
break;
|
|
case 73:
|
|
case 72:
|
|
engine = new ScummEngine_v72he(syst, game, md5sum, subst);
|
|
break;
|
|
case 71:
|
|
engine = new ScummEngine_v71he(syst, game, md5sum, subst);
|
|
break;
|
|
case 70:
|
|
engine = new ScummEngine_v70he(syst, game, md5sum, subst);
|
|
break;
|
|
#endif
|
|
#ifndef PALMOS_68K
|
|
case 61:
|
|
engine = new ScummEngine_v60he(syst, game, md5sum, subst);
|
|
break;
|
|
#endif
|
|
default:
|
|
engine = new ScummEngine_v6(syst, game, md5sum, subst);
|
|
}
|
|
break;
|
|
#ifndef DISABLE_SCUMM_7_8
|
|
case 7:
|
|
engine = new ScummEngine_v7(syst, game, md5sum, subst);
|
|
break;
|
|
case 8:
|
|
engine = new ScummEngine_v8(syst, game, md5sum, subst);
|
|
break;
|
|
#endif
|
|
default:
|
|
error("Engine_SCUMM_create(): Unknown version of game engine");
|
|
}
|
|
|
|
return engine;
|
|
}
|
|
|
|
REGISTER_PLUGIN(SCUMM, "Scumm Engine");
|
|
|
|
#ifdef PALMOS_68K
|
|
#include "scumm_globals.h"
|
|
|
|
_GINIT(Scumm_md5table)
|
|
_GSETPTR(md5table, GBVARS_MD5TABLE_INDEX, MD5Table, GBVARS_SCUMM)
|
|
_GEND
|
|
|
|
_GRELEASE(Scumm_md5table)
|
|
_GRELEASEPTR(GBVARS_MD5TABLE_INDEX, GBVARS_SCUMM)
|
|
_GEND
|
|
|
|
#endif
|