Ticket #10981: full_patch.diff

File full_patch.diff, 529.4 KB (added by Duffadash, 5 years ago)
  • AUTHORS

    diff --git a/AUTHORS b/AUTHORS
    index 2800b62..7ccd755 100644
    a b Other contributions  
    533533     Janne Huttunen               - V3 actor mask support, Dig/FT SMUSH audio
    534534     Kovacs Endre Janos           - Several fixes for Simon1
    535535     Jeroen Janssen               - Numerous readability and bugfix patches
    536      Keith Kaisershot             - Several Pegasus Prime patches
     536     Keith Kaisershot             - Several Pegasus Prime patches and DVD
     537                                    additions
    537538     Andreas Karlsson             - Initial port for SymbianOS
    538539     Claudio Matsuoka             - Daily Linux builds
    539540     Thomas Mayer                 - PSP port contributions
  • Makefile

    diff --git a/Makefile b/Makefile
    index 93a84a5..8f84b26 100644
    a b ZIP ?= zip -q  
    7878# Misc stuff - you should never have to edit this                     #
    7979#######################################################################
    8080
    81 EXECUTABLE  := $(EXEPRE)scummvm$(EXEEXT)
     81EXECUTABLE  := $(EXEPRE)PegasusPrime$(EXEEXT)
    8282
    8383include $(srcdir)/Makefile.common
    8484
  • Makefile.common

    diff --git a/Makefile.common b/Makefile.common
    index b56300a..57647db 100644
    a b dist-src: \  
    233233DIST_FILES_DOCS:=$(addprefix $(srcdir)/,AUTHORS COPYING COPYING.BSD COPYING.LGPL COPYING.FREEFONT COPYRIGHT NEWS README)
    234234
    235235# Themes files
    236 DIST_FILES_THEMES=scummmodern.zip scummclassic.zip
     236DIST_FILES_THEMES=scummclassic.zip
    237237ifdef USE_TRANSLATION
    238238DIST_FILES_THEMES+=translations.dat
    239239endif
  • backends/mixer/sdl/sdl-mixer.cpp

    diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp
    index 7c709e9..b391782 100644
    a b  
    3333#ifdef GP2X
    3434#define SAMPLES_PER_SEC 11025
    3535#else
    36 #define SAMPLES_PER_SEC 22050
     36#define SAMPLES_PER_SEC 44100
    3737#endif
    3838//#define SAMPLES_PER_SEC 44100
    3939
  • backends/platform/sdl/macosx/macosx-main.cpp

    diff --git a/backends/platform/sdl/macosx/macosx-main.cpp b/backends/platform/sdl/macosx/macosx-main.cpp
    index 1b9fc1b..712a4ab 100644
    a b  
    2020 *
    2121 */
    2222
     23// Disable symbol overrides so that we can use system headers.
     24#define FORBIDDEN_SYMBOL_ALLOW_ALL
     25
    2326#include "common/scummsys.h"
    2427
    2528#ifdef MACOSX
    2629
    2730#include "backends/platform/sdl/macosx/macosx.h"
    2831#include "backends/plugins/sdl/sdl-provider.h"
     32#include "base/commandLine.h"
    2933#include "base/main.h"
     34#include "common/config-manager.h"
     35#include "common/fs.h"
     36
     37#include "CoreFoundation/CoreFoundation.h"
     38
     39#define PEGASUS_DVD_TARGET "pegasus-dvd-release"
    3040
    3141int main(int argc, char *argv[]) {
    3242
    int main(int argc, char *argv[]) {  
    4151        PluginManager::instance().addPluginProvider(new SDLPluginProvider());
    4252#endif
    4353
     54        // HACK: Special Pegasus release parameters
     55
     56        // Attempt to detect the PP Data directory
     57        // Get URL of the Resource directory of the .app bundle
     58        CFURLRef fileUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
     59
     60        if (!fileUrl) {
     61                warning("Failed to get bundle URL");
     62                return 1;
     63        }
     64
     65        // Try to convert the URL to an absolute path
     66        char buf[MAXPATHLEN];
     67        if (!CFURLGetFileSystemRepresentation(fileUrl, true, (UInt8 *)buf, sizeof(buf))) {
     68                warning("Failed to get FS representation of bundle URL");
     69                return 1;
     70        }
     71
     72        CFRelease(fileUrl);
     73
     74        Common::String bundlePath(buf);
     75        Common::FSNode bundleNode(bundlePath);
     76        Common::FSNode bundleParent = bundleNode.getParent();
     77        Common::FSNode ppDataDirectory = bundleParent.getChild("PP Data");
     78
     79        Common::String ppDataPath;
     80
     81        // If we have the "PP Data" folder in the same directory as this bundle
     82        if (ppDataDirectory.exists()) {
     83                // Try to use this directory
     84                ppDataPath = ppDataDirectory.getPath();
     85        } else {
     86                // Try to get it off the disc
     87                Common::String discPath("/Volumes/Journeyman/");
     88                Common::FSNode discNode(discPath);
     89                Common::FSNode discDataDirectory = discNode.getChild("PP Data");
     90                if (discDataDirectory.exists()) {
     91                        ppDataPath = discDataDirectory.getPath();
     92                } else {
     93                        warning("Game data missing");
     94                        return 1;
     95                }
     96        }
     97
     98        // Work this into the config file
     99        Base::registerDefaults();
     100        ConfMan.loadDefaultConfigFile();
     101
     102        // Add the special target if it doesn't already exist
     103        if (!ConfMan.hasGameDomain(PEGASUS_DVD_TARGET)) {
     104                ConfMan.addGameDomain(PEGASUS_DVD_TARGET);
     105                ConfMan.set("gameid", "pegasus", PEGASUS_DVD_TARGET);
     106                ConfMan.set("gfx_mode", "opengl_linear", PEGASUS_DVD_TARGET);
     107                ConfMan.set("fullscreen", "true", PEGASUS_DVD_TARGET);
     108                ConfMan.set("platform", "macintosh", PEGASUS_DVD_TARGET);
     109        }
     110
     111        // Always update the path
     112        ConfMan.set("path", ppDataPath, PEGASUS_DVD_TARGET);
     113
     114        // Flush for good luck
     115        ConfMan.flushToDisk();
     116
     117        const char *pegasusParams[] = {
     118                argv[0],
     119                "--gui-theme=scummpegasus",
     120                PEGASUS_DVD_TARGET
     121        };
     122
    44123        // Invoke the actual ScummVM main entry point:
    45         int res = scummvm_main(argc, argv);
     124        int res = scummvm_main(ARRAYSIZE(pegasusParams), pegasusParams);
    46125
    47126        // Free OSystem
    48127        delete (OSystem_MacOSX *)g_system;
  • backends/platform/sdl/macosx/macosx.cpp

    diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp
    index 924e33b..5e61df3 100644
    a b  
    4343
    4444OSystem_MacOSX::OSystem_MacOSX()
    4545        :
    46         OSystem_POSIX("Library/Preferences/ScummVM Preferences") {
     46        OSystem_POSIX("Library/Preferences/Pegasus Prime Preferences") {
    4747}
    4848
    4949void OSystem_MacOSX::init() {
  • backends/platform/sdl/posix/posix-main.cpp

    diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp
    index d07db11..2bacaa8 100644
    a b  
    2020 *
    2121 */
    2222
     23// Disable symbol overrides so that we can use system headers.
     24#define FORBIDDEN_SYMBOL_ALLOW_ALL
     25
    2326#include "common/scummsys.h"
    2427
    2528#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3)
    2629
     30#include <mntent.h>
     31
    2732#include "backends/platform/sdl/posix/posix.h"
    2833#include "backends/plugins/sdl/sdl-provider.h"
     34#include "base/commandLine.h"
    2935#include "base/main.h"
     36#include "common/config-manager.h"
     37#include "common/fs.h"
     38
     39#define PEGASUS_DVD_TARGET "pegasus-dvd-release"
    3040
    3141int main(int argc, char *argv[]) {
    3242
    int main(int argc, char *argv[]) {  
    4151        PluginManager::instance().addPluginProvider(new SDLPluginProvider());
    4252#endif
    4353
     54        Common::String dataPath(DATA_PATH);
     55        Common::FSNode ppDataDirectory(dataPath + "/PP Data/");
     56
     57        Common::String ppDataPath;
     58
     59        // If we have the "PP Data" folder in the same directory as this bundle
     60        if (ppDataDirectory.exists()) {
     61                // Try to use this directory
     62                ppDataPath = ppDataDirectory.getPath();
     63        } else {
     64                // Search mounted volumes for the Journeyman disc
     65                bool foundData = false;
     66                FILE* fp = setmntent(_PATH_MOUNTED, "r");
     67                mntent* ent;
     68                while ((ent = getmntent(fp))) {
     69                        Common::String discPath(ent->mnt_dir);
     70                        Common::FSNode discNode(discPath);
     71                        Common::FSNode discDataDirectory = discNode.getChild("PP Data");
     72                        if (discDataDirectory.exists()) {
     73                                foundData = true;
     74                                ppDataPath = discDataDirectory.getPath();
     75                                break;
     76                        }
     77                }
     78               
     79                if (!foundData) {
     80                        warning("Game data missing");
     81                        return 1;
     82                }
     83        }
     84
     85        Base::registerDefaults();
     86        ConfMan.loadDefaultConfigFile();
     87
     88        // Add the special target if it doesn't already exist
     89        if (!ConfMan.hasGameDomain(PEGASUS_DVD_TARGET)) {
     90                ConfMan.addGameDomain(PEGASUS_DVD_TARGET);
     91                ConfMan.set("gameid", "pegasus", PEGASUS_DVD_TARGET);
     92                ConfMan.set("gfx_mode", "opengl_linear", PEGASUS_DVD_TARGET);
     93                ConfMan.set("fullscreen", "true", PEGASUS_DVD_TARGET);
     94                ConfMan.set("platform", "linux", PEGASUS_DVD_TARGET);
     95        }
     96
     97        // Always update the path
     98        ConfMan.set("path", ppDataPath, PEGASUS_DVD_TARGET);
     99
     100        // Flush for good luck
     101        ConfMan.flushToDisk();
     102
     103        const char *pegasusParams[] = {
     104                argv[0],
     105                "--gui-theme=scummpegasus",
     106                PEGASUS_DVD_TARGET
     107        };
     108
    44109        // Invoke the actual ScummVM main entry point:
    45         int res = scummvm_main(argc, argv);
     110        int res = scummvm_main(ARRAYSIZE(pegasusParams), pegasusParams);
    46111
    47112        // Free OSystem
    48113        delete (OSystem_POSIX *)g_system;
  • backends/platform/sdl/posix/posix.cpp

    diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp
    index a711c3a..2d8a4e5 100644
    a b Common::WriteStream *OSystem_POSIX::createLogFile() {  
    107107#ifdef MACOSX
    108108        logFile += "/Library";
    109109#else
    110         logFile += "/.scummvm";
     110        logFile += "/.PegasusPrime";
    111111#endif
    112112#ifdef SAMSUNGTV
    113113        logFile = "/mtd_ram";
    Common::WriteStream *OSystem_POSIX::createLogFile() {  
    151151                return 0;
    152152        }
    153153
    154         logFile += "/scummvm.log";
     154        logFile += "/Pegasus Prime.log";
    155155
    156156        Common::FSNode file(logFile);
    157157        Common::WriteStream *stream = file.createWriteStream();
  • backends/platform/sdl/posix/posix.h

    diff --git a/backends/platform/sdl/posix/posix.h b/backends/platform/sdl/posix/posix.h
    index 01a0152..f2e6a46 100644
    a b  
    2828class OSystem_POSIX : public OSystem_SDL {
    2929public:
    3030        // Let the subclasses be able to change _baseConfigName in the constructor
    31         OSystem_POSIX(Common::String baseConfigName = ".scummvmrc");
     31        OSystem_POSIX(Common::String baseConfigName = ".PegasusPrimerc");
    3232        virtual ~OSystem_POSIX() {}
    3333
    3434        virtual bool hasFeature(Feature f);
  • backends/platform/sdl/win32/win32-main.cpp

    diff --git a/backends/platform/sdl/win32/win32-main.cpp b/backends/platform/sdl/win32/win32-main.cpp
    index e5b26c3..a93c04a 100644
    a b  
    3737
    3838#include "backends/platform/sdl/win32/win32.h"
    3939#include "backends/plugins/sdl/sdl-provider.h"
     40#include "base/commandLine.h"
    4041#include "base/main.h"
     42#include "common/config-manager.h"
     43#include "common/fs.h"
    4144
    4245int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/,  LPSTR /*lpCmdLine*/, int /*iShowCmd*/) {
    4346        SDL_SetModuleHandle(GetModuleHandle(NULL));
    4447        return main(__argc, __argv);
    4548}
    4649
     50#define PEGASUS_DVD_TARGET "pegasus-dvd-release"
     51
    4752int main(int argc, char *argv[]) {
    4853        // Create our OSystem instance
    4954        g_system = new OSystem_Win32();
    int main(int argc, char *argv[]) {  
    5661        PluginManager::instance().addPluginProvider(new SDLPluginProvider());
    5762#endif
    5863
     64        // Get the path to our EXE
     65        HMODULE hModule = GetModuleHandleW(NULL);
     66        WCHAR wideCharPath[MAX_PATH];
     67        GetModuleFileNameW(hModule, wideCharPath, MAX_PATH);
     68
     69        // Convert to ANSI
     70        char buf[MAX_PATH];
     71        WideCharToMultiByte(CP_ACP, 0, wideCharPath, -1, buf, MAX_PATH, NULL, NULL);
     72
     73        // Find the directory the EXE is in
     74        Common::String exePath(buf);
     75        Common::FSNode exeNode(exePath);
     76        Common::FSNode ppDataDirectory = exeNode.getParent().getChild("PP Data");
     77
     78        Common::String ppDataPath;
     79
     80        // If we have the "PP Data" folder in the same directory as this bundle
     81        if (ppDataDirectory.exists()) {
     82                // Try to use this directory
     83                ppDataPath = ppDataDirectory.getPath();
     84        } else {
     85                // Search mounted volumes for the Journeyman disc
     86                bool foundData = false;
     87                char szLogicalDrives[26 * 4 + 1];
     88                DWORD dwResult = GetLogicalDriveStrings(sizeof(szLogicalDrives), szLogicalDrives);
     89                if (dwResult > 0 && dwResult <= sizeof(szLogicalDrives)) {
     90                        char *szSingleDrive = szLogicalDrives;
     91                        while (*szSingleDrive) {
     92                                if (GetVolumeInformation(szSingleDrive, buf, sizeof(buf), NULL, NULL, NULL, NULL, 0) && !scumm_stricmp(buf, "Journeyman")) {
     93                                        Common::String discPath(szSingleDrive);
     94                                        Common::FSNode discNode(discPath);
     95                                        Common::FSNode discDataDirectory = discNode.getChild("PP Data");
     96                                        if (discDataDirectory.exists()) {
     97                                                foundData = true;
     98                                                ppDataPath = discDataDirectory.getPath();
     99                                                break;
     100                                        }
     101                                }
     102                                szSingleDrive += strlen(szSingleDrive) + 1;
     103                        }
     104                }
     105
     106                if (!foundData) {
     107                        warning("Game data missing");
     108                        return 1;
     109                }
     110        }
     111
     112        // Work this into the config file
     113        Base::registerDefaults();
     114        ConfMan.loadDefaultConfigFile();
     115
     116        // Add the special target if it doesn't already exist
     117        if (!ConfMan.hasGameDomain(PEGASUS_DVD_TARGET)) {
     118                ConfMan.addGameDomain(PEGASUS_DVD_TARGET);
     119                ConfMan.set("gameid", "pegasus", PEGASUS_DVD_TARGET);
     120                ConfMan.set("gfx_mode", "opengl_linear", PEGASUS_DVD_TARGET);
     121                ConfMan.set("fullscreen", "true", PEGASUS_DVD_TARGET);
     122                ConfMan.set("console", "false", PEGASUS_DVD_TARGET);
     123                ConfMan.set("platform", "windows", PEGASUS_DVD_TARGET);
     124        }
     125
     126        // Always update the path
     127        ConfMan.set("path", ppDataPath, PEGASUS_DVD_TARGET);
     128
     129        // Flush for good luck
     130        ConfMan.flushToDisk();
     131
     132        const char *pegasusParams[] = {
     133                argv[0],
     134                "--gui-theme=scummpegasus",
     135                PEGASUS_DVD_TARGET
     136        };
     137
    59138        // Invoke the actual ScummVM main entry point:
    60         int res = scummvm_main(argc, argv);
     139        int res = scummvm_main(ARRAYSIZE(pegasusParams), pegasusParams);
    61140
    62141        // Free OSystem
    63142        delete (OSystem_Win32 *)g_system;
  • backends/platform/sdl/win32/win32.cpp

    diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp
    index 5f860ad..eb89ffb 100644
    a b  
    4444
    4545#include "common/memstream.h"
    4646
    47 #define DEFAULT_CONFIG_FILE "scummvm.ini"
     47#define DEFAULT_CONFIG_FILE "Pegasus Prime.ini"
    4848
    4949void OSystem_Win32::init() {
    5050        // Initialize File System Factory
    Common::String OSystem_Win32::getDefaultConfigFileName() {  
    175175                        }
    176176                }
    177177
    178                 strcat(configFile, "\\ScummVM");
     178                strcat(configFile, "\\Pegasus Prime");
    179179                if (!CreateDirectory(configFile, NULL)) {
    180180                        if (GetLastError() != ERROR_ALREADY_EXISTS)
    181                                 error("Cannot create ScummVM application data folder");
     181                                error("Cannot create Pegasus Prime application data folder");
    182182                }
    183183
    184184                strcat(configFile, "\\" DEFAULT_CONFIG_FILE);
    Common::WriteStream *OSystem_Win32::createLogFile() {  
    237237                        CreateDirectory(logFile, NULL);
    238238                }
    239239
    240                 strcat(logFile, "\\ScummVM");
     240                strcat(logFile, "\\Pegasus Prime");
    241241                CreateDirectory(logFile, NULL);
    242242                strcat(logFile, "\\Logs");
    243243                CreateDirectory(logFile, NULL);
    244                 strcat(logFile, "\\scummvm.log");
     244                strcat(logFile, "\\Pegasus Prime.log");
    245245
    246246                Common::FSNode file(logFile);
    247247                Common::WriteStream *stream = file.createWriteStream();
  • backends/saves/posix/posix-saves.cpp

    diff --git a/backends/saves/posix/posix-saves.cpp b/backends/saves/posix/posix-saves.cpp
    index 9682832..b31d820 100644
    a b  
    4343
    4444
    4545#ifdef MACOSX
    46 #define DEFAULT_SAVE_PATH "Documents/ScummVM Savegames"
     46#define DEFAULT_SAVE_PATH "Library/Application Support/Pegasus Prime Saves"
    4747#else
    48 #define DEFAULT_SAVE_PATH ".scummvm"
     48#define DEFAULT_SAVE_PATH ".PegasusPrime"
    4949#endif
    5050
    5151POSIXSaveFileManager::POSIXSaveFileManager() {
  • backends/saves/windows/windows-saves.cpp

    diff --git a/backends/saves/windows/windows-saves.cpp b/backends/saves/windows/windows-saves.cpp
    index b84ab13..943ea75 100644
    a b WindowsSaveFileManager::WindowsSaveFileManager() {  
    6363                        }
    6464                }
    6565
    66                 strcat(defaultSavepath, "\\ScummVM");
     66                strcat(defaultSavepath, "\\Pegasus Prime");
    6767                if (!CreateDirectory(defaultSavepath, NULL)) {
    6868                        if (GetLastError() != ERROR_ALREADY_EXISTS)
    69                                 error("Cannot create ScummVM application data folder");
     69                                error("Cannot create Pegasus Prime application data folder");
    7070                }
    7171
    7272                strcat(defaultSavepath, "\\Saved games");
    7373                if (!CreateDirectory(defaultSavepath, NULL)) {
    7474                        if (GetLastError() != ERROR_ALREADY_EXISTS)
    75                                 error("Cannot create ScummVM Saved games folder");
     75                                error("Cannot create Pegasus Prime Saved games folder");
    7676                }
    7777
    7878                ConfMan.registerDefault("savepath", defaultSavepath);
  • configure

    diff --git a/configure b/configure
    index 5499cec..b874090 100755
    a b _plugin_prefix=  
    159159_plugin_suffix=
    160160_nasm=auto
    161161_optimization_level=
    162 _default_optimization_level=-O2
     162_default_optimization_level=-Os
    163163# Default commands
    164164_ranlib=ranlib
    165165_strip=strip
  • devtools/credits.pl

    diff --git a/devtools/credits.pl b/devtools/credits.pl
    index 53f0d11..4fdc0db 100755
    a b begin_credits("Credits");  
    10971097                                add_person("Janne Huttunen", "", "V3 actor mask support, Dig/FT SMUSH audio");
    10981098                                add_person("Kov&aacute;cs Endre J&aacute;nos", "", "Several fixes for Simon1");
    10991099                                add_person("Jeroen Janssen", "japj", "Numerous readability and bugfix patches");
    1100                                 add_person("Keith Kaisershot", "blitter", "Several Pegasus Prime patches");
     1100                                add_person("Keith Kaisershot", "blitter", "Several Pegasus Prime patches and DVD additions");
    11011101                                add_person("Andreas Karlsson", "Sprawl", "Initial port for SymbianOS");
    11021102                                add_person("Claudio Matsuoka", "", "Daily Linux builds");
    11031103                                add_person("Thomas Mayer", "", "PSP port contributions");
  • new file dists/pegasus/Info.plist

    diff --git a/dists/pegasus/Info.plist b/dists/pegasus/Info.plist
    new file mode 100644
    index 0000000..4490d1e
    - +  
     1<?xml version="1.0" encoding="UTF-8"?>
     2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
     3<plist version="1.0">
     4<dict>
     5        <key>CFBundleDevelopmentRegion</key>
     6        <string>English</string>
     7        <key>CFBundleLocalizations</key>
     8        <array>
     9                <string>en</string>
     10                <string>ca</string>
     11                <string>cs</string>
     12                <string>da</string>
     13                <string>de</string>
     14                <string>es</string>
     15                <string>fr</string>
     16                <string>hu</string>
     17                <string>it</string>
     18                <string>nb</string>
     19                <string>nn</string>
     20                <string>pl</string>
     21                <string>pt</string>
     22                <string>ru</string>
     23                <string>se</string>
     24                <string>uk</string>
     25        </array>
     26        <key>CFBundleDisplayName</key>
     27        <string>ScummVM</string>
     28        <key>CFBundleExecutable</key>
     29        <string>scummvm</string>
     30        <key>CFBundleGetInfoString</key>
     31        <string>1.6.0git, Copyright 2001-2013 The ScummVM team</string>
     32        <key>CFBundleIconFile</key>
     33        <string>pegasus.icns</string>
     34        <key>CFBundleIdentifier</key>
     35        <string>org.scummvm.scummvm</string>
     36        <key>CFBundleInfoDictionaryVersion</key>
     37        <string>6.0</string>
     38        <key>CFBundleName</key>
     39        <string>ScummVM</string>
     40        <key>CFBundlePackageType</key>
     41        <string>APPL</string>
     42        <key>CFBundleShortVersionString</key>
     43        <string>1.6.0git</string>
     44        <key>CFBundleVersion</key>
     45        <string>1.6.0git</string>
     46        <key>NSPrincipalClass</key>
     47        <string>NSApplication</string>
     48        <key>NSHumanReadableCopyright</key>
     49        <string>Copyright 2001-2013 The ScummVM team</string>
     50        <key>SUFeedURL</key>
     51        <string>http://www.scummvm.org/appcasts/macosx/release.xml</string>
     52        <key>SUPublicDSAKeyFile</key>
     53        <string>dsa_pub.pem</string>
     54</dict>
     55</plist>
  • new file dists/pegasus/PegasusPrime.desktop

    diff --git a/dists/pegasus/PegasusPrime.desktop b/dists/pegasus/PegasusPrime.desktop
    new file mode 100644
    index 0000000..a9a2a63
    - +  
     1[Desktop Entry]
     2Name=Pegasus Prime
     3Comment=The epic time travel adventure begins
     4Exec=PegasusPrime
     5Icon=pegasus
     6Terminal=false
     7Type=Application
     8Categories=Game;AdventureGame;
     9StartupNotify=false
  • new file dists/pegasus/debian/README.source

    diff --git a/dists/pegasus/debian/README.source b/dists/pegasus/debian/README.source
    new file mode 100644
    index 0000000..a7252c2
    - +  
     1This project uses a custom build of ScummVM licensed under GNU GPLv2 using
     2revision d04667e58a889e4744f36fb5797a69fa437a1abf. You may obtain the sources
     3from GitHub: https://github.com/scummvm/scummvm (direct link:
     4https://github.com/scummvm/scummvm/archive/d04667e58a889e4744f36fb5797a69fa437a1abf.zip).
     5On top of that revision, it has been patched with the "full_patch.diff"
     6(included in the pegasusprime source tarball) The dists/pegasus directory
     7missing from the patch is also included in the pegasusprime source tarball.
     8
     9This is a cutdown ScummVM build because Pegasus Prime does not need many of the
     10usual features of ScummVM.
  • new file dists/pegasus/debian/changelog

    diff --git a/dists/pegasus/debian/changelog b/dists/pegasus/debian/changelog
    new file mode 100644
    index 0000000..c681a98
    - +  
     1pegasusprime (1.0-5) unstable; urgency=low
     2
     3  * Minor bugfix release
     4
     5 -- Keith Kaisershot <archives@thejourneymanproject.com>  Mon, 10 Mar 2014 13:29:11 -0800
     6
     7pegasusprime (1.0-4) unstable; urgency=low
     8
     9  * Minor bugfix release
     10
     11 -- Keith Kaisershot <archives@thejourneymanproject.com>  Sun, 09 Mar 2014 18:18:45 -0800
     12
     13pegasusprime (1.0-3) unstable; urgency=low
     14
     15  * Minor bugfix release
     16
     17 -- Keith Kaisershot <archives@thejourneymanproject.com>  Thu, 27 Feb 2014 10:05:56 -0800
     18
     19pegasusprime (1.0-2) unstable; urgency=low
     20
     21  * Minor bugfix release
     22
     23 -- Keith Kaisershot <archives@thejourneymanproject.com>  Mon, 24 Feb 2014 18:15:56 -0800
     24
     25pegasusprime (1.0-1) unstable; urgency=low
     26
     27  * Initial release
     28
     29 -- Keith Kaisershot <archives@thejourneymanproject.com>  Tue, 31 Dec 2013 15:44:53 -0600
  • new file dists/pegasus/debian/compat

    diff --git a/dists/pegasus/debian/compat b/dists/pegasus/debian/compat
    new file mode 100644
    index 0000000..7f8f011
    - +  
     17
  • new file dists/pegasus/debian/control

    diff --git a/dists/pegasus/debian/control b/dists/pegasus/debian/control
    new file mode 100644
    index 0000000..0362061
    - +  
     1Source: pegasusprime
     2Section: games
     3Priority: optional
     4Maintainer: Keith Kaisershot <archives@thejourneymanproject.com>
     5Build-Depends: debhelper (>= 7.0.50~), autotools-dev
     6Standards-Version: 3.8.4
     7Homepage: http://www.thejourneymanproject.com
     8
     9Package: pegasusprime
     10Architecture: any
     11Depends: ${shlibs:Depends}, ${misc:Depends}
     12Description: time travel adventure game
     13 Experience the origin of the Journeyman Project series in this "director's
     14 cut" remake of the award-winning time travel adventure game with greatly
     15 enhanced animation and sound. As Agent 5 of the Temporal Protectorate, you
     16 must explore across centuries for clues to a sinister mystery as Earth's
     17 future hangs in the balance.
  • new file dists/pegasus/debian/copyright

    diff --git a/dists/pegasus/debian/copyright b/dists/pegasus/debian/copyright
    new file mode 100644
    index 0000000..2fa382e
    - +  
     1Pegasus Prime was debianized by Keith Kaisershot <archives@thejourneymanproject.com> the 31st Dec 2013.
     2
     3Upstream Authors: see `/usr/share/doc/scummvm/AUTHORS'.
     4
     5ScummVM is Copyright © 2002-2013 The ScummVM Project
     6
     7 This program is free software; you can redistribute it and/or modify it
     8 under the terms of the GNU General Public License as published by the
     9 Free Software Foundation; either version 2, or (at your option) any
     10 later version.
     11
     12 On Debian GNU/Linux systems, the complete text of the GNU General
     13 Public License can be found in `/usr/share/common-licenses/GPL'.
     14
     15This copyright also applies to the Debian-related build scripts.
     16
     17Some parts of ScummVM (the mt32 softsynth code) is covered by a more
     18permissive BSD-style license:
     19
     20 * Permission is hereby granted, free of charge, to any person obtaining a copy
     21 * of this software and associated documentation files (the "Software"), to
     22 * deal in the Software without restriction, including without limitation the
     23 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     24 * sell copies of the Software, and to permit persons to whom the Software is
     25 * furnished to do so, subject to the following conditions:
     26 *
     27 * The above copyright notice and this permission notice shall be included in
     28 * all copies or substantial portions of the Software.
     29 *
     30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     32 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     33 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     34 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     35 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     36 * IN THE SOFTWARE.
  • new file dists/pegasus/debian/docs

    diff --git a/dists/pegasus/debian/docs b/dists/pegasus/debian/docs
    new file mode 100644
    index 0000000..c73c810
    - +  
     1AUTHORS
     2COPYRIGHT
     3README
     4TODO
     5NEWS
  • new file dists/pegasus/debian/menu

    diff --git a/dists/pegasus/debian/menu b/dists/pegasus/debian/menu
    new file mode 100644
    index 0000000..bf946ff
    - +  
     1?package(pegasusprime):needs="x11" section="Games/Adventure" \
     2  title="Pegasus Prime" command="/usr/games/PegasusPrime" \
     3  icon="/usr/share/icons/pegasus.xpm"
  • new file dists/pegasus/debian/rules

    diff --git a/dists/pegasus/debian/rules b/dists/pegasus/debian/rules
    new file mode 100755
    index 0000000..5f72554
    - +  
     1#!/usr/bin/make -f
     2
     3%:
     4        dh $@
     5
     6override_dh_auto_configure:
     7        ./configure --prefix=/usr --bindir=/usr/games --datadir=/usr/share/PegasusPrime --docdir=/usr/share/doc/pegasusprime --disable-all-engines --enable-engine=pegasus --enable-optimizations --enable-keymapper --disable-eventrecorder --disable-mt32emu --disable-alsa --disable-bink --disable-faad --disable-flac --disable-fluidsynth --disable-mad --disable-png --disable-timidity
     8
     9override_dh_auto_test:
     10
     11
     12
  • new file dists/pegasus/debian/source/format

    diff --git a/dists/pegasus/debian/source/format b/dists/pegasus/debian/source/format
    new file mode 100644
    index 0000000..163aaf8
    - +  
     13.0 (quilt)
  • new file dists/pegasus/pegasus.xpm

    diff --git a/dists/pegasus/pegasus.icns b/dists/pegasus/pegasus.icns
    new file mode 100644
    index 0000000..83a4351
    Binary files /dev/null and b/dists/pegasus/pegasus.icns differ
    diff --git a/dists/pegasus/pegasus.ico b/dists/pegasus/pegasus.ico
    new file mode 100644
    index 0000000..d523358
    Binary files /dev/null and b/dists/pegasus/pegasus.ico differ
    diff --git a/dists/pegasus/pegasus.xpm b/dists/pegasus/pegasus.xpm
    new file mode 100644
    index 0000000..d967ede
    - +  
     1/* XPM */
     2static const char *pegasus_icon[] = {
     3/* columns rows colors chars-per-pixel */
     4"256 256 256 2 ",
     5"   c #010101",
     6".  c #0B0301",
     7"X  c #010B01",
     8"o  c #0B0B02",
     9"O  c #02010B",
     10"+  c #0B030B",
     11"@  c #060A0B",
     12"#  c #130301",
     13"$  c #1B0301",
     14"%  c #130B02",
     15"&  c #180B07",
     16"*  c #061403",
     17"=  c #171504",
     18"-  c #020113",
     19";  c #090516",
     20":  c #150916",
     21">  c #171618",
     22",  c #0A1415",
     23"<  c #240301",
     24"1  c #2C0200",
     25"2  c #270B03",
     26"3  c #330300",
     27"4  c #3B0300",
     28"5  c #340C01",
     29"6  c #3B0B01",
     30"7  c #38090B",
     31"8  c #2C1400",
     32"9  c #261703",
     33"0  c #331300",
     34"q  c #3B1300",
     35"w  c #371A03",
     36"e  c #261717",
     37"r  c #310E17",
     38"t  c #18280A",
     39"y  c #282703",
     40"u  c #372702",
     41"i  c #2F2C11",
     42"p  c #050225",
     43"a  c #170526",
     44"s  c #16112D",
     45"d  c #261627",
     46"f  c #2D1231",
     47"g  c #2F282D",
     48"h  c #1C202A",
     49"j  c #470902",
     50"k  c #560A03",
     51"l  c #441401",
     52"z  c #4B1B00",
     53"x  c #481702",
     54"c  c #531C00",
     55"v  c #591704",
     56"b  c #4F1216",
     57"n  c #661906",
     58"m  c #661B15",
     59"M  c #73170C",
     60"N  c #492702",
     61"B  c #542300",
     62"V  c #5B2300",
     63"C  c #592A02",
     64"Z  c #493502",
     65"A  c #583803",
     66"S  c #4E2D16",
     67"D  c #632C01",
     68"F  c #692605",
     69"G  c #762906",
     70"H  c #683602",
     71"J  c #773603",
     72"K  c #6B2517",
     73"L  c #782916",
     74"P  c #723618",
     75"I  c #4E132D",
     76"U  c #6E192D",
     77"Y  c #502D2D",
     78"T  c #732D2A",
     79"R  c #374619",
     80"E  c #564606",
     81"W  c #694703",
     82"Q  c #784703",
     83"!  c #764816",
     84"~  c #705208",
     85"^  c #776B07",
     86"/  c #77492D",
     87"(  c #5D532A",
     88")  c #12044D",
     89"_  c #2E104C",
     90"`  c #332A4D",
     91"'  c #310E6D",
     92"]  c #22156A",
     93"[  c #4F1250",
     94"{  c #772C4F",
     95"}  c #5D2264",
     96"|  c #6B5354",
     97" . c #3A474B",
     98".. c #873904",
     99"X. c #852A19",
     100"o. c #863719",
     101"O. c #913209",
     102"+. c #AD3503",
     103"@. c #872A26",
     104"#. c #8A3626",
     105"$. c #96392B",
     106"%. c #963736",
     107"&. c #8B2D34",
     108"*. c #A33D2F",
     109"=. c #871A0F",
     110"-. c #874902",
     111";. c #974904",
     112":. c #895602",
     113">. c #965902",
     114",. c #904B18",
     115"<. c #A75703",
     116"1. c #B05009",
     117"2. c #996602",
     118"3. c #8E6D07",
     119"4. c #A56903",
     120"5. c #B86803",
     121"6. c #A97506",
     122"7. c #B77804",
     123"8. c #AF7316",
     124"9. c #95452A",
     125"0. c #984937",
     126"q. c #8E492C",
     127"w. c #A6452B",
     128"e. c #A64533",
     129"r. c #B64F2E",
     130"t. c #B06D2D",
     131"y. c #8D6D2F",
     132"u. c #C8540B",
     133"i. c #C66904",
     134"p. c #C87702",
     135"a. c #D67903",
     136"s. c #D1700F",
     137"d. c #E67903",
     138"f. c #F17105",
     139"g. c #C95626",
     140"h. c #CD562D",
     141"j. c #D0712D",
     142"k. c #E95F15",
     143"l. c #92314D",
     144"z. c #93306F",
     145"x. c #A33365",
     146"c. c #984B4B",
     147"v. c #A64F52",
     148"b. c #95476F",
     149"n. c #AB506F",
     150"m. c #A76C59",
     151"M. c #D2645D",
     152"N. c #C13800",
     153"B. c #B6870D",
     154"V. c #A6950F",
     155"C. c #C88603",
     156"Z. c #D88703",
     157"A. c #D1920D",
     158"S. c #E68803",
     159"D. c #E99702",
     160"F. c #F99902",
     161"G. c #F39011",
     162"H. c #D7AC05",
     163"J. c #FEA401",
     164"K. c #FEAB00",
     165"L. c #F7A705",
     166"P. c #FEB400",
     167"I. c #FFBB00",
     168"U. c #F9B808",
     169"Y. c #FEA916",
     170"T. c #FEB718",
     171"R. c #E8AC05",
     172"E. c #CE8B2E",
     173"W. c #EB942A",
     174"Q. c #FBB32E",
     175"!. c #DCAC2B",
     176"~. c #FFC400",
     177"^. c #FECB00",
     178"/. c #FAC708",
     179"(. c #FED400",
     180"). c #FFDB01",
     181"_. c #FAD808",
     182"`. c #FFC719",
     183"'. c #F7D411",
     184"]. c #FFE400",
     185"[. c #FFEB00",
     186"{. c #FBE609",
     187"}. c #FFF300",
     188"|. c #FFFE00",
     189" X c #FDF508",
     190".X c #FDEA16",
     191"XX c #FFC728",
     192"oX c #FFD82A",
     193"OX c #FFC737",
     194"+X c #FFD535",
     195"@X c #EBCF2C",
     196"#X c #FEE92E",
     197"$X c #D6CA06",
     198"%X c #AA9361",
     199"&X c #FBB44C",
     200"*X c #E3985E",
     201"=X c #FECB4D",
     202"-X c #FECF73",
     203";X c #FFE96E",
     204":X c #FCE855",
     205">X c #320A90",
     206",X c #3509AE",
     207"<X c #211698",
     208"1X c #591FA0",
     209"2X c #6A51A6",
     210"3X c #3407D0",
     211"4X c #3106F9",
     212"5X c #2623E7",
     213"6X c #4F0EFA",
     214"7X c #6E14FD",
     215"8X c #712FFA",
     216"9X c #5B22DA",
     217"0X c #6A52EA",
     218"qX c #962F8C",
     219"wX c #A230A3",
     220"eX c #AE528E",
     221"rX c #AF50AF",
     222"tX c #A25A9A",
     223"yX c #CF5F9E",
     224"uX c #A735D0",
     225"iX c #8B19FE",
     226"pX c #8C36F6",
     227"aX c #B737FE",
     228"sX c #AB33F9",
     229"dX c #9A2ADA",
     230"fX c #CA35FE",
     231"gX c #E039E4",
     232"hX c #B352CE",
     233"jX c #954BF6",
     234"kX c #B14FF7",
     235"lX c #A357D9",
     236"zX c #CF52CF",
     237"xX c #CF50FC",
     238"cX c #FD5AFF",
     239"vX c #EC50FC",
     240"bX c #D36CFB",
     241"nX c #FE67FF",
     242"mX c #FD77FE",
     243"MX c #E86FFB",
     244"NX c #D868D0",
     245"BX c #C92FAB",
     246"VX c #FDB394",
     247"CX c #FDB3AC",
     248"ZX c #E3929D",
     249"AX c #FFCD8F",
     250"SX c #FEEE8A",
     251"DX c #FFCAAA",
     252"FX c #FFEDAD",
     253"GX c #FF86FE",
     254"HX c #FF97FF",
     255"JX c #F491E9",
     256"KX c #FEB1FA",
     257"LX c #F9A7D0",
     258"PX c #FFC7D8",
     259"IX c #9E9595",
     260"UX c None",
     261/* pixels */
     262"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     263"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     264"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     265"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     266"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     267"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     268"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     269"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     270"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     271"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     272"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     273"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& = = = > = > t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     274"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXg g i i e w 9 2 8 8 8 0 w 9 9 e e h g ` ` ` ` `  .` UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     275"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> g g Y ` Y Y b l q 0 7 5 5 2 1 3 1 7 q q l 7 S I Y `  .`  . .<X .<X`  .UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     276"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXe e i S S Y S Y r 5 < 1 < < < < # # # # % 3 k k k x j x j x r i e ` ` ` `  . . .` R UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     277"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> i i S S S b q 5 3 1 < # % # . . . . .       . 7 M k k k j j k k k k k c b w i g R g g g t > t > UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     278"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> e i S b x 6 7 3 < $ . . .       O       O     O   . b &.&.=.M n n M M n k n k v k k k j r r 9 e = % o * o o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     279"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> g S S c x j 1 2 # . #             O   O   O   O O     . I &.l.l.&.@.@.@.L X.X.K F n k k j j 4 3 1 5 & % % % @ o o o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     280"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXe i S S b j 4 < # . .     .           O     O O   O   O O   . b { %.&.&.#.@.#.&.@.@.@.L L K n n n v k j 5 < < $ # # . . o o * UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     281"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXe i Y S k k 3 < # .   O   O   O     O O O     O       O O O . . : Y &.&.%.@.@.#.&.&.&.#.#.#.@.@.#.#.T L L K n k j 3 1 < $ % o o * * o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     282"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& e i b x j 3 $ .         O O O     O O     O O     O   O O O O O @ : I l.&.#.&.#.&.#.$.$.#.#.o.#.#.#.#.@.@.L L L m n k j 3 3 < # . @ o * = t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     283"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX% e e w b j 4 < # . O                 O       O     O O   O   O O + + . & Y %.%.%.%.%.$.%.$.#.#.$.#.#.#.o.L X.X.L L L L L K v v j 1 1 # # o * = t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     284"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& e 2 7 j 4 1 #   .           O     O   O   O     O O     O O O O O ; + & > T l.v.e.e.e.9.9.$.$.$.9.#.#.#.#.#.#.#.#.X.L L L L K K n v 6 1 < # % = t i R t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     285"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo > 9 5 4 4 1 $ . O     O     O   O   O   O   O O     O   O   O   O O O + + & & T n.M.M.m.v.0.w.w.9.w.9.$.9.9.9.9.#.#.#.#.o.#.X.L =.M L K F k 4 1 < = t t y R R > UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     286"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX% e 2 5 j 3 $ .     O       O     O     O   O O     O     O         O     o & % e q.*XCXVXVX*X*X*X*Xt.h.r.r.0.q.#.$.#.#.o.@.o.o.o.o.X.L L L K n v j 4 1 & = t t y t * UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     287"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& > 1 4 4 1 # .             O     O   O     O     O O                   O X @ + & e 0.VXFXDXAX;X;X;X:X;X-XVX*X*XM.r.e.w.#.$.#.#.o.o.o.X.o.L K L G n F c j 1 < 9 t t t t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     288"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX & 2 5 4 4 < .   O         O O   O O   O   O O   O                     O   @ X % > & 9 0.VXFXFX;X;X;X;X:X:X;X;X;X;X-X&X*X*Xe.,.w.9.$.O.o.o.#.L G L L G K m v j 4 1 $ o t t t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     289"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo & r 7 4 3 $ .   O   O     O       O       O O   O                       X   X o @ > & e 0.AXDXDXSX-XSX;X;X;X;X:X;X:X:X:X-X-XVX*Xh.w.$.O.o.#.X.L L L L L G K F n v 4 < # * t t R t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     290"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX@ > r l j 3 $ .       O     O   O   O   O O                                     X X + > & w c.VXPXFXAX;XSXAX;XSX-X-X-X;X-X:X:X=X;XDXVXM.v.*.$.#.o.@.#.o.X.L L K G F F c j 1 % = * t t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     291"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> d I b j 3 #       O O   O O   O       O   O                               X X O @ @ , & e i v.CXPXPXAXAX-XAXAXSXAXSX-X-X:X=X=X:X:X-XPXPXCXZXr.#.o.o.#.P P X.L L F K K K v l < $ * * t t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     292"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: f I r j 3 $ . O           O   O O   O O                                     @   @ @ , , > > e c.CXPXPXDXSXSXAXSXDXAXSXAX-X-X-X-X-X-X=XDXKXKXPXCX*Xg.,.#.#.#.L P X.G K m G K V x 3 2 o * t t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     293"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: d g I 7 4 $ O O O O O O   O         O                                           @ @ , , > > h i c.CXPXPXDXAXDXAXAXAXAXAXAXAX-X-XAX-X-X-X;XPXKXKXPXVXVXE.w.o.#.o.o.L L L K F n n n x 1 $ * * * * * UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     294"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& 2 r 7 j 1 # . O O O   O O       O O O                                   O     @ @ , , , , h > e r c.ZXKXCXDXAXAXAXAXAXDXAXDXAXAXAXAXVX-X-X-XCXLXCXAX-X-XVX*Xg.O.#.X.X.o.L P L n n n v q 1 #   @ X X   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     295"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX% & e 7 4 4 $ O O O O O   O   O O O O                                         @ @ , @ , , , , , > e i v.JXKXPXDXDXDXFXDXDXAXDXDXDXDXAXAXAX-XAX-XAXAXVXAX-X-X-XVX-X*X$.X.@.@.P L L L K n m m x 1           X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     296"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX & < 1 4 3 <   O   O O O O O O     O                                       X   @ , , , - @ , , , , e g n.JXJXDXDXDXDXDXAXAXDXAXAXDXDXDXAXAXAXAXVX-X-XVX-XVXVXAX-X-X-X*Xr.=.@.P L T L K K m V v x $             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     297"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: 2 1 3 j < . O O O O O O O     O O O                                     O @ @ , , , @ @ @ , , > > h g qXGXKXCXDXDXDXFXDXPXDXVXVXVXDXDXDXCXAXAXAX-X-X-X-X-XVX-XVX-XVXDXVXv.O.L #.T L L K F m n v j #             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     298"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & < 4 j 3 # O O O O O O O O O O O                                       O @ @ , @ , @ O - , h > d h d f rXGXKXLXPXPXPXPXPXPXPXDXCXCXVXDXCXDXDXAXAXAX-X-XVX-XVXAXVXAXCXCXJXLXM.=.X.@.P X.L K K n n v 7 X             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     299"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& e & 1 j 4 # O - O O O O O   O O O O                                     O @ @ @ , @ O O O , s h h g g g Y tXGXKXKXKXKXPXKXKXKXKXKXPXDXVXVXDXVXAXVXAXAXAXAXVXVXVXDXDXLXPXKXKXHXJXyX@.o.T L P L m m v v x <               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     300"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& 2 5 4 4 < O O - O O O O O O O O O                                     O - @ @ @ ; O @ , : h h ` ` ` g g g rXGXHXKXKXKXKXKXKXKXKXKXPXPXDXVXDXDXDXDXVXDXDXDXDXDXDXCXLXPXKXKXHXHXGXmXyX&.L L L L K m m v v j .           @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     301"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& 2 5 j j 1 . O O O O O O O O O O                                   O O O O @ @ @ @ - - + @ , s g h ` g g g I tXGXKXPXPXPXPXPXPXKXKXKXKXLXCXCXCXCXCXDXCXCXCXPXPXLXLXPXKXKXKXHXGXGXGXGXmXzX{ U T T K K K m v v 5               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     302"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & 1 4 j 4 # O - - - O O - - O O O                               O O O O O O @ @ @ + - @ ; @ @ , e d d g g g g b.LXPXPXFXDXDXDXPXPXPXKXKXKXLXCXVXZXCXCXCXLXLXKXKXKXKXKXKXKXHXGXGXGXGXGXHXGXzX{ L T L L K m n v k 2 X           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     303"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& < 1 4 4 < . - - - - O O O O - - O                                   O   O O @ O - + + + @ @ @ + , > d e d I Y l.ZXIX*XVXAXFXDXDXFXDXDXPXPXKXLXCXVXVXCXCXCXPXLXKXKXKXKXKXHXGXGXGXGXGXHXGXGXmXrXT L U K K m m n v j .           @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     304"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: & 2 3 4 1 # O - - - - O - O - O O                             O O O O O @ + + O @ + @ . . @ : > f I Y { { c.c.v.n.b.Y T T c.%XZXVXAXAXAXDXDXDXCXCXVXVXVXVXVXCXCXPXKXKXHXHXGXGXHXHXHXHXHXHXHXGXmXx.L L K K m m v v v 5 O             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     305"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo & < 1 3 3 $ O p p p - - - - O O O                             O O O O O + @ + ; @ + .   o d Y { c.n.n.M.M.M.M.j.M.tX9X} g d e I Y P / 0.%X*XAXAXAXVXVXZXZXZXVXZXVXVXPXKXHXHXGXHXHXHXHXHXHXHXHXGXGXNX@.L K T K m m v v k $             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     306"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: & 1 1 4 1 O - p p p - - - - - O O                         O @ O O O @ @ + + O O % + + r T b.n.n.M.M.M.M.M.M.j.j.M.uX8X2X_ a : : 2 & r r S / y.*XVXVXVXVXVXZXZX*XZXVXZXJXmXHXHXHXHXKXHXHXHXHXHXHXmXnXeX@.T T K m m v v v 6               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     307"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ & 2 1 3 3 < O p p p p - p - - p O                         X @ - O O @ + @ O + + . . : Y c.BXM.M.M.M.M.j.k.h.k.h.j.h.rX8X9X) ; : : : : d f e 9 r S 0.*XAXAXVX*X*XM.*X*X*XZXJXGXHXHXHXHXKXHXKXHXHXHXGXnXvXl.L T K K m m v v x #             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     308"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& < 1 3 4 1 # p p ) p p p p p p -                         O O , - O O + ; + @ : # + f c.yXyXM.h.h.h.h.h.h.h.j.h.j.h.M.rXpX1X_ a : : a > a : > > e e w b 0.*XVXZX*X*XM.M.M.M.JXGXHXHXHXHXKXHXKXHXHXGXGXmXnXzXU L U U K m k v v 5 .             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     309"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: & 2 3 4 4 $ + p p p p p p p p - O                         @ ; - O O O @ + + . # d l.M.yXyXM.M.h.h.u.u.k.h.h.h.h.h.g.h.eXpX1X_ : & : > : : : : : : : > : r m v.M.ZXyXZX*XM.k.yXmXGXHXHXHXHXHXHXHXHXHXGXGXmXcXrXT M K K m m n v k #           @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     310"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX% : < 1 4 1 + : ) ) ) p ) p p p O                         O O - O . O + . . O + Y v.yXyXM.M.h.h.h.h.h.h.k.h.h.h.h.h.g.r.qX8X1X_ : + : : + + : : + : : & : : & < Y M.LXNXZXyXM.M.NXnXGXJXHXHXHXHXHXHXGXGXGXmXmXvXl.m m K m m v v b 2               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     311"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ 2 1 1 4 1 : p ) ] ) p p p p p O                         O O O +   O     O & / yXyXM.h.h.h.h.N.h.h.N.g.h.h.h.h.h.g.g.t.b.dX1X) ; + ; ; ; ; + + + + + + : & : & & Y M.JXJXNXNXyXyXNXmXmXGXHXHXHXGXHXGXHXGXmXnXnXwXU K m m m m v v 6 .             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     312"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. % $ 1 1 3 < a ) ] ) ) ) ) ) p p O                         O O O     . .   2 x.yXyXM.M.k.h.h.h.N.N.h.h.h.g.g.h.h.h.g.g.t.b.dX1X_ - . + ; ; O O . + . O + & + & : + : b b.MXGXNXNXyXyXvXnXmXmXGXGXGXGXGXGXGXmXmXnXvXl.m m m m m m n x <               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     313"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& $ < < 3 3 $ ) <X<X] ) ) ) p p p                         O O O   O . . O r v.yXM.M.h.h.h.g.r.h.h.h.h.N.h.g.h.k.h.h.g.g.r.qX2X1X] - O . ; - O O   O O . + + + : + & & e d z.mXGXMXzXzXzXxXnXnXmXmXGXGXmXGXGXmXmXnXnXx.U K m m m v v v 3               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     314"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX# # < 1 4 1 : <X<X<X) ] ) ) ) ) -                           O O . O   O 2 v.yXyXn.g.g.g.g.g.g.g.r.g.g.N.g.g.g.h.h.h.g.s.r.b.dX1X_ ;   + ; O O O     O O   O + + : : > > e d tXmXmXMXzXrXhXxXvXnXnXmXmXmXmXmXmXmXmXnXBXU T U m m m v v 6 .             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     315"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX# & $ 7 7 r 7 _ 3X3X<X<X] ] ) ) p -                             O . .   < x.M.BXh.h.g.r.r.r.r.g.r.g.g.g.g.u.s.g.g.h.h.j.g.r.qX2X1X) -   O O O O           O O . + + ; : @ > > g zXGXmXMXzXrXhXxXvXcXnXnXmXmXmXmXnXmXnXgX{ K K m m m n v j $               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     316"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: d f f [ I _ >X4X4X<X<X<X] ] ) ) O                               . # # { M.eXM.h.r.r.r.r.h.h.r.r.h.r.g.g.g.g.g.g.g.h.g.g.r.eX9X1X_ -   O O O O O             O O O ; ; > > e > [ NXmXMXNXhXhXuXkXvXcXcXnXnXnXnXnXnXcXcXqXm m m m m m b x 3 .           @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     317"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: g ' ' [ U [ 3X4X4X5X<X<X] <X) p -                             . . . I n.n.v.r.r.r.r.r.r.r.r.r.g.r.N.r.g.r.u.g.g.u.g.u.g.t.b.uX1X_ - O O - O O O               . O @ , > e > > h } mXmXvXzXrXuXkXfXvXvXcXcXcXcXnXnXcXcXBXU K m m m v v v l .             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     318"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX > <X,X,X>X[ ] 3X4X4X4X3X<X<X<X) p O                           O .   j x.n.M.r.r.r.r.r.r.r.r.r.r.r.h.r.r.g.N.r.u.N.g.g.g.u.r.qX0X1Xf - O O - O O                   O @ , , > h h > > 2XmXnXNXyXwXrXaXaXvXvXvXcXcXcXcXcXcXgX} m m m m v v v l # O           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     319"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX, ) 9X0X9X1X1X<X5X4X4X4X4X3X<X<X) p - O                         . # # @.yXx.v.e.*.*.r.x.h.v.r.r.r.r.r.r.r.g.r.1.r.r.g.r.1.r.r.b.dX1Xf O   O O O O O         O O   O   @ , > > h > , > f hXmXnXzXeXwXuXsXxXxXvXcXcXvXcXvXvXgXqXY m m m m v v l < O             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     320"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXs <X5X5X8X9X,X,X3X4X4X4X4X4X<X<X) p - O   O                   .   $ b x.M.v.r.*.*.r.e.h.v.r.r.r.r.r.w.r.N.r.r.r.r.N.r.1.r.1.r.b.dX1X_ O   O O O O O               @ @ @ * t , > h d h g } MXnXzXBXeXwXuXaXfXxXvXvXvXvXvXvXsXqXU m m m b v v k < .             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     321"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX) <X8X0X5X3X} ,X4X4X4X4X4X4X4X<Xp - - O O O                     O 7 l.n.v.r.e.r.*.e.r.*.e.e.r.e.r.r.r.r.r.r.*.N.r.r.r.r.+.1.w.b.1X1X_ . O O O     O           O O O X @ * , , > i h d d _ uXnXvXzXrXqXuXkXaXfXfXgXvXvXgXfXuXqXm m m m m v v x 5               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     322"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp ] 5X0X8X,X} [ ,X4X4X4X4X4X4X4X,Xp - - O O                   .     b n.eXh.e.e.*.e.e.e.e.r.v.e.e.r.e.r.w.r.w.r.e.w.r.w.w.1.+.w.z.1X1X) * X O O O     O           O O @ X * * , t h h i h h 1XvXvXzXhXwXwXuXaXkXfXfXvXfXfXfXdXwXU m m m m b v k 5               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     323"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXs ] 0X5X>X_ I _ ,X4X4X4X4X4X4X4X3X) p - O O O                     . &.eXqXr.r.*.*.e.e.e.e.e.e.e.e.e.e.r.r.r.w.r.e.r.+.w.r.w.w.O.z.1X1X_ O   O - O O O       O       O   X @ , , t h g g h h ' kXvXxXhXwXwXuXsXaXfXfXxXfXfXfXsXwXT m m m v v v v 5 .             X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     324"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXp ` ' ' f 7 7 _ ,X4X6X4X4X4X4X4X3X) - - - O O                 . O $ x.rXx.r.e.e.e.r.*.e.e.e.e.e.e.e.e.e.*.w.w.w.w.w.r.w.w.w.O.w.{ 1X1Xh O   . O O O   O O             X @ @ * * , e g h d h ` dXvXgXzXwXuXuXsXaXfXfXfXfXfXaXaXwXU m m b b v v v 6 .               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     325"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX, > e : < 7 j _ ,X6X6X6X4X4X4X4X5X) - - O O O                 . . b eXeXx.*.*.*.e.*.e.e.*.e.e.e.e.*.w.w.e.e.w.w.w.w.w.w.w.w.O.O.l.1X1Xh O . . O O                 O O X @ * , * , t g t h g f wXfXvXuXuXuXuXsXaXaXaXfXaXfXfXfXwX{ m m m m v v x 6 #             @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     326"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & # $ 1 7 7 ' ,X6X6X6X4X6X4X4X4X) p - - O O O                 # { BXeX*.*.*.w.*.*.e.e.e.e.e.0.e.%.e.w.e.w.w.w.e.9.9.w.$.o.O.#.| } 1X_ + . . O O O   O           O   O   * * , , t t i h g f } zXxXdXwXuXsXaXsXaXfXfXsXfXsXfXdX{ m m m v m v x q <               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     327"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. & $ 2 r r 7 ' ,X6X7X6X6X4X6X4X3X) - p - - O                 . # l.eXn.*.+.*.w.w.*.e.*.*.e.e.e.%.e.%.e.e.$.9.w.w.w.e.9.$.O.O.#.{ 1X1X_ + . . +     O   O         O       @ * * , t g h g g g ` uXxXuXdXdXsXaXfXfXfXiXfXfXfXfXBX{ m m n b v v v x 1           O   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     328"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo & 2 2 r r I ' ,X9X6X6X6X4X4X4X4X] - - O - O                   < x.yXx.*.$.*.*.*.e.e.*.e.0.e.0.e.9.e.9.9.e.e.9.e.9.9.w.r.t.w.,.{ 1X>Xs # . . + . O           O         X @ @ * t , g h h g h _ wXpXuXrXdXaXsXaXsXfXsXfXfXfXfXdXU v m b n v v x x 1       X   X   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     329"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. & < 2 r I I ' 3X6X7X6X6X6X6X4X4X) - p - O O           .     . 7 n.BXM.*.+.*.*.e.e.$.e.$.e.e.w.e.e.$.w.e.w.9.$.$.9.e.t.j.E.E.5.,.` ' e = & # . @   O   O               X @ * * , t t h g h h _ 1XdXuXuXsXsXaXaXaXsXsXfXfXiXsXdXU m m m m V v c x 0 o   X     X X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     330"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX@ & < 2 r r [ ,X6X6X6X7X6X6X4X6X4X) - - - - O O           .     I eXyXx.*.+.*.*.*.*.%.*.e.e.e.%.*.9.e.$.9.e.9.e.w.r.j.E.E.A.S.Z.<.@.K B q 2 $ .       .     O             @ * * * t t h g h h f } dXdXuXsXsXaXaXaXsXsXfXsXsXdXz.T m m v v v v c c l = * X X X     UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     331"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo & 2 < r I [ 1X6X6X7X6X6X6X6X4X4X) - p - O O             .   . I eXBXv.*.O.w.*.*.*.e.$.*.$.e.$.%.*.$.e.$.9.9.w.g.s.S.S.S.G.L.L.Z.i.1.O.n 6 & . .     O   O             X X X * , t t h g g h ` z.wXuXsXaXaXaXaXaXsXaXiXfXdXz.U m m m m n v c v c u y * * * X X   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     332"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. & 2 e r I I 1X3X7X7X6X7X6X6X6X4X) p - - - - O         .   . . U BXyXx.*.O.$.*.*.e.$.*.*.*.$.e.e.$.e.$.$.w.w.g.s.S.S.a.S.K.~.(.~.I.D.a.1.=.j $ # .   O             O   X @ * * * > t g h g h f 1XwXwXsXaXsXsXfXfXsXsXsXdXz.&.U m m m V V v v c B u y t = * * o @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     333"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX# > 2 2 e b I [ ,X6X7X7X7X6X6X7X4X<Xp p - - - O           .     k yXzXn.*.O.$.*.$.%.*.*.$.*.*.$.e.$.$.9.$.,.r.s.a.d.a.Z.J.^._.).).(.(.^.J.k.O.k 1 & .                 O O X X * * t t h g g s _ 1XwXuXdXsXsXaXsXsXfXiXdXqX&.@.M m F m m v v v c c Z y y y y = * + UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     334"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX+ & e r r e I [ ' 3X7X7X7X6X6X6X6X,Xp p p - O O           .     j eXzXM.*.=.$.*.*.$.%.*.$.$.$.%.$.$.$.$.*.w.u.s.i.u.S.F.~.).).).(.(.^.^.~.Q.g.=.k 1 + O . O           O   X * * * t > i g h h _ 1XrXwXdXaXaXaXaXfXiXuXqXl.&.@.K m S n V n v V n V u u y y y y *   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     335"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo : e r : r I [ [ ,X7X7X6X7X6X6X6X3X) p - - O O         .       7 x.zXyX*.+.$.$.$.*.$.$.*.*.$.$.$.$.$.$.*.w.u.5.1.s.F.K.~.).).).).^.(.~.Y.G.u.=.M j $ ; O                 X X X * , t h h g g f } wXdXsXsXsXsXsXiXdXx.z.l.&.U U m F n n V v F F V u u y y R y *   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     336"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX@ & e 2 & & r I I >X6X7X7X6X7X6X6X4X<X- p - - - O             . < l.BXyXx.=.*.*.*.*.$.$.%.$.$.$.$.$.$.$.*.,.;.O.O.i.D.L.U.(.).).(.^.~.P.W.t.,.G M k r ; O                 X X * o t t h h h e r z.wXuXsXsXsXsXsXwXz.l.l.&.U =.M m m V v c n G J Z u Z y y y y t O UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     337"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX & = & # # $ r [ 1X7XiX7X7X6X6X6X6X,Xp - O - -   O     .     O $ l.zXzXe.$.$.$.$.$.$.$.$.$.$.$.$.$.$.*.$.O.G n n J 7.H.U.^.(.).(.~.P.W.j.0./ T m k 7 a O                   X * * > t t t e e g { qXwXsXjXsXdXwXx.z.l.l.U =.U U F F n V v F J J A u y u Z y y t X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     338"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX@ o # & # $ $ r [ 1XiX7X7X7X6X6X6X6X4X) O - - - O O     .       . I zXyXx.&.$.&.$.$.@.$.$.$.$.$.$.$.%.$.$.o.G k l N W 3.A.I.^.).^.U.D.8.q.| | } U b 7 ; O                   X X * = t t t > > I &.x.BXiXsXdXqXx.l.l.&.&.@.L K n F F n n n F ..Q H Z u u u y y = UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     339"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  @ % # # $ < 2 [ dX7XiX7X7X7X6X7X6X4X,X- - - - O O O   O O O .   r BXzXn.*.$.#.@.%.&.&.$.$.$.$.$.$.$.$.#.X.n j 0 9 u N Q H./.(.(.U.Z.,.T Y } } I k 7 : O                 X X X * , > h > > h U l.qXwXdXuXqXl.l.l.l.U =.L K m F F n V V F J ..Q A Z Z N u u y = UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     340"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX@ . # $ $ < 5 I 1X9X7X7X7X6X6X6X6X6X4X) - - - O O O     O .     # l.zXBXv.$.#.@.$.$.$.$.%.%.$.$.%.$.$.#.X.n j 8 9 9 = 2 ~ H.)._.U.6.P S Y / Y b k 7 ; @ X                 X X X * = t > @ d &.x.x.qXwXqXz.l.&.&.U =.@.L m K F F n n n J ....W W E Z u Z Z y = UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     341"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX @ % $ $ < 8 b { qX9X7X7X7X7X7X6X6X4X] p p - - O O   O O . .   + b yXgXn.$.#.&.&.$.$.$.%.$.*.%.$.$.$.$.=.v j 5 & o .   2 B.].}.H.Q c l N b b k j 3 O O             O X @ X X * @ t , = , r l.l.l.l.l.l.l.&.&.=.@.@.X.M K F F F F v F ..;...W E W A Z Z Z i = UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     342"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX X % $ < 2 5 k [ z.1X,X7X7X7X6X6X6X6X3Xs - - - - O O O O       O d l.gXeX*.%.&.%.%.$.%.%.$.%.$.%.%.$.@.@.n j 5 & % .     3._.[.H.A N 7 w z x j j $ + O                 X X * * * = > > > T %.&.&.l.&.&.&.&.@.=.&.L M K K n F F n V J ;.;.-.W ~ ~ E A E E i = UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     343"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  X % 2 1 5 0 j U U } 1X6X7X7X7X6X6X6X4X>X- - - - - O O O O .   + : I BXzXx.%.%.&.%.%.%.%.%.%.%.$.%.$.$.@.m 4 1 2 o     X ~ /.{.B.H N l q x c j 3 #                 X X X X X @ * * @ > r &.%.&.*.&.&.@.@.=.@.=.=.X.L F F F G F D G -.>.<.Q Q ~ ~ W A W ~ E o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     344"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXO X * $ 5 6 q 6 v U } 1X9XiXiX6X8X6X6X6X4X) O - - - - O O O O . . + & x.vXrXv.%.@.@.%.%.%.%.%.&.$.$.&.$.@.M j 3 < .     X u V.'.3.S q q q j k j 1 .                 X O X X X o = o @ > T $.%.&.%.%.&.@.X.=.@.U @.=.F G F F F F F -.;.>.>.^ ~ :.~ W W :.3.u o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     345"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  X X $ 5 l l z b { z.qXqX7X7X8X6X6X6X4X6X,Xp - - - O O O . O + + +   I BXzXeX%.$.$.%.%.%.%.%.$.&.%.&.$.$.L j 4 < .       t 3.V.A w q 0 6 j j j < O     X             X @ * @ * * @ * b &.%.%.*.&.*.&.@.@.@.=.=.=.L M G F G F F ..;.<.<.:.2.2.:.:.~ ~ 6.2.y UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     346"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX X * % 5 l c B Y c.b.z.} 1X7X6X6X6X6X6X6X4X>X- - - O O O O O O O     - l.zXrXx.c.%.*.%.%.%.%.%.$.&.%.%.%.@.m j 3 .       X y y > & 0 q 6 j j 3 # O                   X X * o * o @ d &.0.%.%.%.%.$.@.=.@.X.X.X.L D G F G D F J ;.;.<.>.3.6.6.3.:.^ :.C.6.y UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     347"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX * * 2 x v C c.c.b.x.{ } 1X6X8X6X6X6X5X6X3X) p - O O O O O .   O . O 7 qXzXhXx.l.%.l.%.%.%.&.%.&.$.%.%.&.m j 3 #   X         + e 7 q j j j <     X   X X         X X = * o o o , T 0.%.%.%.*.l.%.@.$.=.X.X.G G G D G F F J ;.<.<.<.2.6.6.6.3.:.:.4.D.6.= UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     348"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX * * 9 N S T c.c./ %.&.{ } 9X7X6X6X6X4X6X5X>X) -   O O O O O O O .   O r BXgXhXn.e.%.%.%.%.%.%.%.%.v.v.l.U k 4 $ .       O @ : 5 5 6 l j 4 $   X   @ X       X X   o o * * * @ S %.c.*.l.c.%.%.%.$.@.$.=.L G H G G G F G -.<.i.4.2.6.B.7.6.2.3.4.Z.L.3.X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     349"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX * * = N T / / ,.y.*.&.=.U 1X7X6X7X6X6X5X4X,X] ) O O O - O O O O . O . ; f eXvXrXx.%.%.%.%.%.%.%.l.v.x.v.&.m j 3 #       . & w 5 5 6 6 j 1 .   O   X   @ X @   O X o * o , & b &.%.%.%.%.%.l.*.%.@.@.=.=...G G G G F G ..<.i.5.2.2.C.C.7.6.6.2.C.D.L.E X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     350"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX * X * Z / / ,.,.,.,.,.$.=.U 1X6X6X6X4X6X3X,X>X' p p - O O O O O O O O + ; r z.zXwXv.l.%.&.&.%.l.x.b.n.l.&.M k 7 < . O   . & 8 0 6 l j j $     o   X   X O   @   o X o & & b &.$.$.#.#.%.%.%.%.$.@.X.L G J J G G G D J <.i.5.5.6.C.C.C.7.6.6.7.S.P.A.u . UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     351"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX @ * * i ! / ,.! ,.! ,.,.w.=.[ 9X6X6X6X6X3X,X>X' ) a p O O O O   . O . + ; ; 7 l.eXn.v.%.%.%.%.c.qXeXn.%.@.@.m 7 1 #     . < 5 7 q j k 4 #         @   X   .   o     X > b @.$.$.$.@.#.$.%.*.*.$.X.L ..G G J G J F J <.5.i.4.5.C.Z.A.C.C.6.7.C.D.I.B.y @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     352"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX@ X * t u ~ ! -.:.,.3.:.y.j.r.=.I ,X4X5X6X3X,X>X' ] ) a - - O O   O O ; O + ; - < U x.eXx.l.%.%.n.rXrXn.&.=.@.=.j 4 2 % * # < 7 7 l x k 1     X   . . . O X @     X   w T $.$.@.@.@.#.%.%.$.%.%.X.G J G J G G J G J <.p.p.5.4.B.A.A.A.C.B.6.C.S.L.~.3.y @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     353"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    * * t E ~ :.,.;.,.,.t.E.M.e.M [ 1X3X9X3X,X<X>X] _ ) a ; O O O   . O ; O - O O $ I { eXn.x.l.eXuXuXqX&.&.&.U m j j w y i g b b b x 3 #       .       .         > Y @.&.@.$.@.@.#.@.&.%.#.o.o...J G J J G J G J <.p.p.5.7.C.C.D.D.D.C.C.C.D.K.~.R.W e UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     354"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  X * t E ^ 3.:.,.,.8.j.E.*XM.1.K I >X,X,X,X>X' ' ) ) ) a ; ; - O   O O O O + ; ; ; d I { b.z.rXhXkXuXn.l.l.&.=.k v S S ( Y { I b j < O @ .   .       . . & > Y T &.$.$.@.@.@.$.@.&.$.o.o.X.P ..G G G J G G -.4.p.p.7.7.p.S.D.D.A.Z.Z.A.D.P.~.^.C.y % UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     355"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXX   X t E ^ 3.2.,.2.t.E.E.W.j.j.+.v I ' >X>X' ' ' _ _ _ a a p ; O O O O O ; + - @ ; > > d } b.wXrXrXzXhXwXx.%.&.M v S R Y Y Y Y b 4 # . + o   . . . . & r m U &.$.$.$.@.o.X.@.$.@.@.@.X.G J G G J J J J J -.5.p.p.p.p.C.D.D.L.D.Z.A.D.R.L.U.^.~.2.t * UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     356"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo X @ t E y.y.y.8.t.t.E.*XE.E.j.s.+.=.I _ ' _ _ _ _ ) a a a p ; ; O O O O O O @ - ; , , > , h ` } z.z.qXwXqXqXz.&.n k u i S b k j < o o % @ & & > e S T &.$.$.$.$.@.$.@.@.o.X.X.X.L J J X.G J J G J J ..8.p.C.p.p.Z.A.D.L.D.D.D.D.A.R.@XQ.U./.L.W t , UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     357"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXe h e > t y Z ^ y.t.t.t.E.*X*X*Xj.B.s.j.+.=.k f f ) _ _ _ _ a a a ; ; ; O O O O O ; @ ; ; : > ; > > > h g Y [ } } } { b j l 8 w j j 4 < < 5 6 w b m T T %.%.$.$.$.$.@.X.X.X.o.X.X.X.G G J L J J ..G J ..,.5.p.a.Z.Z.A.R.P.I.I.L.D.D.D.A.!.!.=X!.Q.*X| ) ` _ ` UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     358"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXy e i g Y  .` g Y i i w w u N ! y.y.m.%XZXZXZX%Xj.p.s.s.s.g.=.k r f a a f ) a a a : + ; + O O O O O O + ; ; ; ; : > > ; , : & : r r Y r j j 3 6 k k k k n m m L #.%.0.%.%.%.#.@.#.o.X.o.L L o.G G G J G L G G G F J ;.7.a.a.p.p.Z.D.U./._.^.~.P.D.C.C.V.%X%X%X%XIXtX0X2X2X2X2X0X2X2X . .i = = UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     359"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> e e g Y g Y Y Y Y Y Y Y S S A m M C S Y | | tXtXIXNXIXZX*X*Xj.E.A.s.g.=.k b r r a r a a : : : + + O O O + + O + + , : : : : : : & # & $ & 2 & 5 j k F G v k =.+.O.$.@.@.X.L &.#.&.o.L o.G ..X.G L G P J G H G ..J J J J o.4.s.a.a.a.Z.Z.H.$X{..X.X`.D.6.2.:.Q ~ ! / / | ( } 2X2X2X2X2X2X2X2X2X| R i y 9 = = * o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     360"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXi e g g i Y Y Y T Y { l.&.l.l.&.@.&.l.&.{ &.l.{ z.z.z.b.b.IXlXIXyXIXyX*XW.W.G.u.O.M k 7 r r : : : : + : # + O . O . . . + . . + # # & & & # # % = $ 2 6 k O.1.;.O.M =.1.1.1.,.L G M L L L L G G G G G G ..J G G H G G J J ..,.4.p.Z.Z.p.i.d.R.$X_.{..X:X@X8.-.H H S N N C N u w r e d  .g g `  . .g Y u w y 9 9 9 = = = % o o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     361"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& e e Y Y m S K I U { z.qXx.x.BXx.n.qXBXx.qXqXx.qXqXqXx.eXn.b.n.b.tXIXlXyXIXeX%XE.G.G.d.N.=.k j < : + : : + + + + + + . O + . . . . . # . # # % & & 9 2 & 2 k =.u.a.5.1.O.M O.+.1.+...G F v F G F G G F G G G J G J G G G G G ..>.6.p.C.a.a.a.a.S.R.(..X:X&XE.,.W D C N N z w w w 9 = & % % * % < & t * = % & % & & % % % % % o = % = , = UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     362"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & e 9 8 7 b Y U &.z.z.BXBXgXgXgXvXgXgXgXgXgXgXzXvXNXzXxXxXgXzXzXyXeXeXqXb.eXeXeXn.m.t.t.G.G.G.s.O.=.k j 1 < # + + + . . & + + + . . . . % . # # % % 9 9 w w 6 k M u.f.a.i.5.u.O.=.O.N.u.u.<...G n F F F F F L F F G D G J J -.;.4.8.C.C.p.i.p.a.d.D.L.~.'.Q.t.,.E S C S S 7 q 0 9 9 % % . o         .   * o   o . .         . . . . . % = = = t * UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     363"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX% : e 8 w x N k M &.wXgXvXgXcXcXcXcXcXcXcXcXcXcXcXcXcXcXcXvXMXMXMXvXxXkXxXhXzXrXwXqXz.b.l.q.o.-.,.s.F.F.s.+.M k k 5 8 & & & & + # % # & % & $ % % % % = 9 9 u Z C G =.N.f.F.S.p.5.i.s.O.=.+.u.i.a.p.5.>.;.G G J ........Q ,.,.1.1.8.p.Z.C.Z.C.C.a.a.a.F.P./.!.8.P c l l 0 w 0 2 9 e & = X o X   X X                                   .   . . % o o y R R i > UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     364"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & 2 $ 1 4 k m { x.BXgXvXvXvXnXnXcXnXcXnXnXcXnXnXcXcXcXcXcXcXvXvXvXbXxXxXxXxXfXkXkXhXhXhXqX{ &.@.=.G O.1.S.Y.F.d.u.+.=.n v 4 < 2 2 $ & < & 9 w w w 9 9 8 8 w N H H ..+.u.Y.K.F.D.Z.j.Z.s.u.+.O.N.u.u.s.A.Z.s.i.5.5.5.8.5.p.8.s.8.A.s.a.a.a.a.p.S.S.F.F.F.L.A.>.H x l 6 0 2 = = % % o % o o o     X     X                                             . o i R R R t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     365"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & & 2 2 1 7 k U z.gXvXcXcXcXcXcXcXnXnXnXnXnXnXnXnXcXcXcXcXnXvXvXMXvXvXvXbXxXxXxXxXxXxXxXfXkXhXqXl.U T L K G O.i.Y.K.J.f.N.O.=.n k j x l 0 8 w u u Z Z A N w z B D -.1.u.d.T.(.^.L.S.S.A.Z.d.S.u.+.+.N.u.k.d.d.d.a.p.a.Z.a.p.a.Z.Z.S.S.S.F.D.S.S.S.S.L.P.L.A.2.D j 6 5 2 & & = o o o o o o X   .   X   X       X X                                         o * t R R R R t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     366"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & $ < 5 1 3 U wXgXgXcXnXcXcXnXnXcXnXnXnXmXnXnXnXcXnXcXcXcXnXcXvXvXvXbXbXxXxXxXxXxXbXxXkXxXkXkXkXzXeXz.{ &.@.L M G ,.s.Y.I.K.G.a.u.+.+.O.O.F F D H W :.2.2.Q ......O.N.k.G./.(.{.{.P.F.G.Z.Z.Z.S.f.f.N.N.N.N.i.a.i.f.d.S.f.S.d.d.S.S.S.D.D.K.P.P.P.K.P.P.C.2.H v 6 1 2 % = % o * o X o X o X   X     X           X                                               o t y y y R t * UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     367"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & 2 1 3 3 3 j BXgXvXcXcXcXnXnXnXnXnXnXmXnXnXnXnXnXnXnXnXnXMXMXMXMXMXbXMXbXbXxXbXxXbXxXxXkXxXxXkXkXaXhXzXrXx.l.l.@.L M k G ,.A.^.(.P.K.F.S.f.u.u.N.i.a.p.i.i.i.i.5.<.u.a.G.F.P.~.(._.{.~.Y.D.Z.a.d.S.f.F.F.f.u.1.N.N.u.k.f.f.F.f.S.f.f.D.R.U.U.R.~.(.).~.A.2.L c l 2 2 % o o o o o o o         X                                                                       . o * = t t y t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     368"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & 2 2 < 1 4 j z.gXvXcXnXcXcXcXnXnXnXnXnXnXnXnXnXnXnXnXnXnXnXmXmXMXGXMXMXMXMXMXMXbXMXbXbXxXxXkXkXkXkXkXkXhXrXrXeXn.x.x.&.@.L n n G 8.R.I.^.~.P.J.S.F.F.F.S.d.i.i.i.p.C.Z.D.U.~.~.I.I.^.{.{._./.S.a.Z.S.S.F.F.J.J.F.S.i.u.u.u.u.a.a.a.d.f.F.R.~._.{.}.[.(.A.4.J b b b 2 = o o o o o o X   X X                                                                                 X   . X * t t t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     369"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX: > 2 2 < 1 1 I BXvXcXvXcXcXcXnXnXnXnXnXnXnXmXnXnXnXnXnXnXmXJXJXJXKXJXJXKXLXLXLXCXVXVXLXLXbXbXbXbXxXkXaXaXkXrXBXrXeXeXn.n.v.l.@.=.M v K ,.A.U././.I.P.K.J.F.G.S.a.B.C.D.U.^.(.(.^.^.I.I.I._._._.(.D.S.d.S.S.S.F.J.J.J.P.K.D.Z.p.7.p.C.A.A.H.U./.].}.|.[.H.2.J m m b r & & o o X o . X o     X                                                                                           X * t R t t @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     370"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXe e 2 2 6 3 7 wXgXcXcXcXcXcXcXnXnXnXnXnXnXnXnXnXnXnXmXmXJXVX-X-X-X-X-X;X-X;X:X:X+X#X#X#X#X:X:X=XVXZXNXNXkXaXsXhXeXwXx.n.n.x.x.c.*.%.@.M v v P t.R.U.I.I.I.P.J.J.L.L.U.U.(.].].].).(.^.~.I.P.^._.]._.U.S.S.S.F.F.J.K.P.P.~.~.~.I.U.U.I.^._.].].[.}.|.|.R.7.Q c b I I f r % o X .   X X                                                                                                       X X t t t t t UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     371"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> d d e r 5 4 I BXvXvXvXcXcXcXcXnXnXnXnXmXnXnXnXmXMXJXCXVX-X:X=X+X+X=X+X#X#X#X#X#X#X#X.X#X.X.X.X.X.XoX+X&X&X*X*XM.rXwXeXeXx.n.x.x.v.%.%.$.X.G n v V ! E.W.I.I.I.P.P.~.^.(.(.].{.[.[.).).(.^.I.P.I.(.).]./.D.S.D.F.F.J.K.P.I.~.~.I.^.(.).].[.}.}.}.|.|._.C.;.H K b b r : : & o o . .   X                                                                                                             * * t t t t * UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     372"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> d e r 3 j j } gXcXvXcXcXcXcXnXnXnXnXnXnXnXnXnXmXJXLX-X=X+X#X+XoX+X#X#X+X#X+XoX+X#X#X#X#XoX.XoX.XoX.X{.{..X'./.U.W.M.eXeXn.n.x.v.l.c.c.%.%.#.X.G n v c ( t.!.Y.P.I.I.~.^.(.).].[.[.[.].).(.^.I.I.I.(.).].^.L.F.L.F.F.J.J.P.~.~.I.~.~.(.).].[.}.}.|. X'.8.! F B b [ [ f : o o o                                                                                                                         X t t t t t @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     373"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& e d e 5 3 j wXvXvXvXcXcXcXcXnXcXnXcXnXnXnXnXmXJXVX&XOX+X+X+X+XoXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX'.oX_..XoX'._.'.XXXXXXQ.W.j.n.x.x.v.v.%.%.%.%.$.$.X.M v v S ( y.%XW.U.~.~.^.).).].[.[.[.].).).(.^.^.^.(.].].(.I.I.I.J.J.K.P.I.~.I.I.I.~.(.(.].[.}.|._.6.,.P P v v b [ _ a . X .                                                                                                                             * * * * X X X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     374"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX& & 2 2 r j I dXgXvXgXvXvXvXcXcXnXcXcXnXnXnXmXJXVX&X+XoXXXXX+X+XoX+XoX+X+XoX+XoX+XoXoXoX#XoXoX.XoX'..X`.'..X'.`.`.`.XXT././.T.W.h.n.x.c.%.%.%.%.$.o.O.X.M v x x Y / y.E.Y.~.(.].).].[.].[.].).).).).].).].].].^.~./.^.^.~.~.~.~.~.I.P.U.~.(.).[.}.[.$X2.P K K m v I f _ s @     .                                             X   X                                                                                         X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     375"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. # & < < 1 b dXvXvXvXvXvXvXcXcXcXcXcXnXcXnXMXCX&XXXQ.OXOXXXOXXXXX+XOXoX+X+X+XoX+X+X+XoXoXoXoXoXoXoXoXoX'.oXoX`.`.`.XXT.T.`.T./.U.K.h.c.l.%.9.%.$.$.$.#.o.L n k c S R S ! 8.D.{.).).).[.[.].[.].].].].].[.[.[.].~.P.U.^.^.(.^.~.~.~.I.I.~.~.^.].}.[.A.>.! T T S v b I _ s @ o                                                     X   X X X                                                                                     @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     376"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo # $ 1 4 3 k uXfXgXgXvXvXcXcXcXcXMXcXcXcXmXCX*XOXOXOXOXOXOXOXOXOXOX+X+XOX+XOXoXoXoXoXoXoXoXoXoXoXoXoXoXoXoX`.`.`.XXXXT.T.T.T.`.U.U.U.K.j.e.%.%.$.$.$.o.#.@.o.G v k x z w u Z Q A.{.).].}.}.[.[.[.[.[.[.[.[.].[.].~.L.I.^.(.(.(.(.(.^.(.^.^.(.).[.[.C.Q H D F m v j r d : O @ . O                                               X X         X                                                                                         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     377"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  . & : 7 k k m wXfXvXvXvXvXvXvXvXvXvXcXcXcXLX&XOXOXOXQ.OXQ.OXOXOXXX+XOX+X+X+X+X+X+X+X+X+XoXoXoX+X+XoX+XoXXX+X`.`.XX`.`.Q.Q.T.T.T.T.T.T.U./.P.G.r.%.&.#.#.o.o.o.o.G F k 6 l 0 9 9 2 B C.{.}.|.|.}.}.}.}.|.}.}.[.].].).~.P.U.^.(.).).].).)._.].{.{.[.).7.D V z x x v k 7 & o .                                                   X X X X X X   X                                                                                             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     378"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. . o : I I U U x.fXfXfXvXvXvXvXvXxXvXcXnXMXVX=XXXQ.OXOXQ.OXQ.OXXXXXOXXXOX+XOX+X+X=X+X=X=X+X+X+XOX=X+XOXOXXXXXXXQ.XXT.XXQ.T.T.Y.Y.T.Y.T.L.Y.P.K.K.G.r.$.#.$.o.o.X.o.X.G k 6 l l 8 9 2 8 A $X|.|.|.|.}.}.}.}.}.[.[.].].).U.J.P.~.(.(._.).].).].[. X|.|.B.C B N c c k k 6 % .                                                     X X X X   X X   X   X                                                                                           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     379"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo & : I U [ } z.gXfXvXvXxXvXxXvXvXvXvXMXJX&XXXXXXXOXQ.Q.OXXXOXOXOXOXOXOXOXOX=X+X=X=X=X=X=X=X=X=XOX+X+X+X+XOXXXXXXXT.XXXX`.XXQ.Y.T.Y.Q.Y.Y.Y.Y.L.F.J.F.1.$.O.$.X.o.X.X.G F l l 6 0 9 9 9 i 3. X|.|.|.|.[.}.}.[.].].].].).I.L.P.~.^.(.(.(.).].].}.|.|.}.3.S S m S V k j 2 o   .                                                     X X X X X X X   X   X X                                                                                         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     380"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX% $ : f [ [ } } uXfXfXfXxXxXvXxXvXvXvXvXCX+X`.XXXXOXXXXXOXQ.XXXXOXOXOXOX=X=X=X=X=X=X=X=X=X:X=X+X+X+XoXoXoXoX'.'.`./.'.'./.`.`.`.`.T.T.T.Y.Y.Y.Y.G.F.Y.Y.S.1.;.o.o.L ....L K c j 6 0 w y 9 y A '.|.|.|.}.[.}.[.[.].].].).(.P.J.K.I.~.^.^.^.(.].[.}.|.|.H./ Y Y Y Y m k 2 %                                                         X X   X X X X X X X X o X X X X X X                                                                               @ UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     381"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. & & 7 [ } U } uXkXfXxXfXxXxXxXxXvXbXMXZXOX'.XXXXXXXXOXOXQ.Q.OXOXOX=XOXOX=X=X=X=X=X-X=X&X=X=XOXoXoXoX'.oX_.'.'.'.'.'./.`.`./.`.T./.`.U.T.T.Y.Y.F.F.Y.G.F.F.G.1.o.o.X.X.X.G G v j l q u y y 9 y V.|.|.|.|.[.[.[.[.[.].).].).K.F.K.P.^.^.(.(.(.).].|.|. Xy.| | Y Y U b k 2 .                                       . . .   . .   o   o . o . o X * X X o X X X X X X X X X X                                                                               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     382"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo . o a j I [ { qXsXfXfXxXfXxXxXxXfXxXvXCXoX'.+XXXXXXXQ.XXXXXXXXOXOXOX&X=X=X=X&X-X&X=X=X=X=X=X=XXX_.)._./.XX&X&X=X&XQ.OXOX&X&XQ.Y.U.P.U.~.~.~.~.I.P.K.Y.G.F.G.G.i.O.X.L L X.G G v j j x u u u y 9 ^ |.|.|.|.[.].[.}.[.[.].].).D.F.K.P.~.~.^.(.^.).[.}.|.@X| { Y Y Y m b b r :                                       . % o % % % % % % % % % = % = = o X o X   X   X X X X X X X X                                                                             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     383"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXo o . & 7 b U [ qXsXsXfXaXxXxXxXxXxXxXMXCXoXXXXXXXXXXXXXXXXXXXXXOXOX&X=X=X=X=X&X=X=X=X=XOXOXOX&XXX/.`.Q.Q.!.ZXZXNXIXIXNXNXZXZXZXZXZX*X*XQ.`.U.I.I.I.U.Y.Y.Y.G.G.G.G.<.X...o.J L G F k k z A E Z u 9 Z _.|.|.}.[.}.[.[.].].}.$XE 9 :.L.~.~.^.^.^.(.).[.}.|.@X( Y S S S S m b f p .                         . . . % . % o = 2 2 8 2 0 0 0 w q 0 w 0 0 0 8 2 % % o = o o X X X X X X X X   X                                                                       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     384"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. # & 1 b b [ } sXaXsXfXkXfXfXxXxXxXxXVX.X'.XXXXXXXXXXXXXXXXXXOXOX=X=X=X&X=X&X-X&X=XXXXX@XQ.Q.&X*XZXNXhXlXlXlXkXkXkXkXlXkXkXkXlXlXkXkXhXhXNXNX*XW.R.W.A.G.J.F.F.F.W.1.O.O.L G L G G V v V A ~ E Z y Z _.|.|.}.}.}.[.].).).H.u     X A A.~.I.^.^.(.).[.|.}.V.S w w u b z k b r ; O                   X . % % 9 9 9 y w N z c V V D D H J -.-.J H H D D C B z N w 8 = % o .   X X X X X X X X X                                                                   O UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     385"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX. . # : 7 b U U dXsXsXsXaXaXfXkXkXxXfXVX'.oXXX`.`.`.`.XXXXXXXXXXOX=X=X=X&X-X&X=X&X=XOX`./.`.*X*XyXlXbXlXlXuXtX2X2X2X2X2X2X2X2X2XrX2X2XrXlXlXbXxXbXNXyXM.E.D.F.F.J.F.G.s.1.O.G L G ....G n D E ~ W Z u E $X|.|.|.}.|.|.}.].V.= X     O O y 6.U.^.).)._.[.}.}.H.u 8 w w l j j j r ;           .   .       X = = 2 q z B D J :.>.>.<.2.4.7.7.7.8.6.8.t.8.2.Q Q H B c z 0 2 # o o     X   X X X X X                                                                   @   UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     386"UXUXUXUXUXUXUXUXUXUXUXUXUXUX. . # # r j b U qXsXsXsXaXaXkXaXaXxXfXZX'.oXXXXX`.`.`.XXXXXX`.XXQ.OXOX&X=X&X-X&X&X=X&XQ.T.Q.ZXNXkXkXkXlX2X} ` ` g g  .g g h h ` g f I g ` } 2XlXlXkXkXjXjXrXeXj.s.d.F.F.Z.1.O.o.M G ;.O.G n G Q ^ W E E ~ _.|.|.}.[.|.{.V.~ * X             * E V.^.(._.}.|.|.V.w 9 9 w w q j 4 2 . .     . # .         9 Z Z N c n F ..:.6.A.A.B.B.7.C.B.C.B.B.B.E.%XV.E.V.8.2.Q J H V z q 8 = o o   X   X X X X X X                                                                   UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     387"UXUXUXUXUXUXUXUXUXUXUXUXUXUX. . . $ 7 k b U dXsXsXsXsXaXaXkXxXaXyX~._.XXXXXX`.`.`.`.T.XXQ.OXOXOX&X=X&X&X=X&X&X&XT.Y.ZXhXjXkXkXlX2X` s a e 9 = = t t t * t * * * * % o s ) `  .] 2XkXkXpX9X1X} 0.S.S.Z.g.;.O.G O.;.<.=.G J :.3.~ W E :.$X|.|.|._.V.Z .                   O   = E B./.[.|.|.H.u 2 2 2 5 5 j 4 < . . . . . # . #   o y W 7.5.2.>.>.4.7.A.A.E.A.B.C.B.B.7.B.7.8.B.8.E.E.E.E.E.B.E.V.6.4.:.J B w 2 & % .         X X X                                                                     UXUXUXUXUXUXUXUXUXUXUXUXUX",
     388"UXUXUXUXUXUXUXUXUXUXUXUXUXo . . . < 4 k U qXiXsXsXaXaXaXaXkXaXyXT._.oXoXoX`.`.`.`.XXXXXXQ.Q.&X=X&X=X=XOXOXQ.&X&X*XNXjXjXlX2X} ` d + + + & & = > = > = = * , t , > > = > h h h s _ ` } } } ' ' } c.1.<.5.,.O...;.1.<.O.G -.3.3.~ W W ^ $X$X$X^ i X           UXUXUXUXUX      O   = S ^ V.$XV.w # & 2 8 6 j j 3 # . % . % . % # 9 A Q 4.7.C.7.7.7.B.A.E.A.E.B.7.7.8.6.6.6.6.7.8.B.E.E.E.E.E.E.A.E.A.B.8.6.Q D B q 2 = % X X .   X X X                                                                     UXUXUXUXUXUXUXUXUXUXUXUX",
     389"UXUXUXUXUXUXUXUXUXUXUXUX. . . . $ 1 j k U dXiXsXsXiXsXsXsXkXzXQ.'.`.XX`.`.`.`.`.`.`.XXQ.OXOX=X&X=X&XOXXXXXU.W.yXkXkXjX2X` p . . . : + o & @ + @ , & @ @ , = , t , & @ > , h h h ; ; p > : a _ [ ' U O...O.+.;.1.5.1.O.O.;.6.3.:.~ ~ ~ ^ ( =               UXUXUXUXUXUXUX          X * = Z E 9 % $ 2 w l c k 4 $ # . % . % % 9 W 2.4.6.C.7.7.7.6.C.A.A.E.B.7.6.6.4.4.2.6.6.8.8.8.8.B.V.E.E.V.E.B.E.E.B.E.B.>.J C l 8 % . .           X                                                                   UXUXUXUXUXUXUXUXUXUXUXUX",
     390"UXUXUXUXUXUXUXUXUXUXUXUX. . . . < 3 j k } dXdXdXuXdXsXsXsXfX*X`.XXoXXX`.`.`.`.`.`.Q.OXQ.OX&X&X&X=XOXXX`.U.Q.hXkXkXlX2Xs ; + # # # + # . + + + o , @ ; + @ , , , , > % , s h h h > > & # # : r _ ' ' U G =.;.u.i.1.;.+.;.4.C.4.>.:.:.A X             X UXUXUXUXUXUXUXUXUXUXUX            O @ = & < 5 l z V n j < # # # . % 9 H >.2.4.4.6.B.B.7.6.7.C.B.E.B.6.6.4.4.2.<.2.4.6.6.6.B.8.B.E.V.E.E.B.E.B.E.E.E.B.2.Q V z w 9 % o       X                                                                       UXUXUXUXUXUXUXUXUXUXUX",
     391"UXUXUXUXUXUXUXUXUXUXUXo # . . & 1 j k U qXwXwXwXuXuXuXsXsXM.I.XXXX`.`.`.`./.U.`.XXXXXXOXQ.OX&X&XOXXX/.U.*XlXjXkX2Xf   . . o + + + + +   O . O O .   + O @ , , t h > , : , s s h > > = & & 2 w f _ ' ' U J 1.p.d.1.+.;.5.C.C.6.2.2.:.~ =           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX          O & 8 0 N A H ! J M j 2 9 = 9 w D J J :.:.2.4.6.6.6.6.6.B.B.B.B.6.6.4.6.4.2.4.4.6.6.6.6.8.8.8.8.8.V.t.B.B.B.B.E.V.E.V.:.J D N 9 * o                                                                             UXUXUXUXUXUXUXUXUXUXUX",
     392"UXUXUXUXUXUXUXUXUXUXUX& % . . < 4 j I { qXqXqXwXwXwXwXuXrXW./.XX`.XX`.`.U.`.U.`.XXQ.XXQ.&X&X&XQ.XXI.P.W.lXkXlX| >   . & . + . + O O O O     O   O   O O - @ t , t e > : : s s s s > > & 2 9 9 2 f [ ' >XT 4.a.i.u.N.i.Z.A.C.C.6.8.y.y.i o     UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      > 9 w u A ! ,.,.:.O.M v z Z Q :.:.Q -.:.2.3.3.2.3.4.6.6.6.B.B.6.6.4.4.2.2.2.2.2.6.8.6.6.6.8.8.V.8.B.B.t.V.E.V.8.E.B.E.7.>.P D N 9 =     X   X                                                                     UXUXUXUXUXUXUXUXUXUX",
     393"UXUXUXUXUXUXUXUXUXUX@ & % o # 1 4 k U { z.z.qXqXqXtXeXwXM.Y.`.Q.T.XXT.T.T.U.T.`.Q.OX&XQ.Q.&X&XOXU.I.*XlXkXlX} p + % # # + + O . O .     O     O   O O - - , > e t g d > > , > s d s : > : & & 2 : f _ ' [ ;.i.k.u.u.a.D.D.H.!.%XIXm.| S > o UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> i i S N N A ! ! ,.>.-.O.O.=.;.8.7.7.B.6.6.6.6.6.6.2.2.4.6.6.8.8.6.4.4.4.2.4.4.4.4.4.4.6.6.6.6.6.8.8.t.B.B.8.B.t.B.B.E.V.B.B.3.-.H N 9 % .             X X X                                                           UXUXUXUXUXUXUXUXUX",
     394"UXUXUXUXUXUXUXUXUXUX. % . . $ 3 j k U z.z.z.z.z.qXqXeXn.G.T.Q.T.T.Q.T.Y.T.U.T.Q.Q.OXQ.&X&XQ.Q.T.I.E.kXjXlX .p . # + . + . O O                     O O O ; ; & e d i g g e e e d > e e = 2 9 2 8 1 7 b b =.N.k.f.k.s.a.Z.C.E.%XlX0XlX|  .i > %   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX> i g ( Y S P S P H W ! ,.;.<.1.N.f.G.G.D.R.H.A.C.C.C.V.6.6.2.3.4.6.6.3.2.2.2.2.2.2.2.3.8.3.6.4.4.2.4.4.6.8.8.8.8.8.6.V.8.8.E.V.E.B.8.-.D N = o   X   X         X                                                           UXUXUXUXUXUXUXUXUX",
     395"UXUXUXUXUXUXUXUXUX@ . . . . $ 4 k U { { l.z.l.z.z.z.z.j.Y.Q.Q.Y.Y.T.Y.U.U.U.Q.Q.&X&XQ.Q.Q.Q.XXP.W.rXjX2X} :   . + + + + O O                     O O O ; : a d d g Y S g g e e e e e e u w q x v M =.N.N.f.f.f.f.u.+.;.-.H T b.2X2XtX| ( w u y e % @ UXUXUXUXUXUXUXUXUXUXUXUXUX@ e g Y ( Y ( S S S N B C A ~ Q ;.5.Z.J.F.F.J.J.F.F.D.H.H.H.H.A.C.B.B.6.6.2.>.2.>.2.2.2.2.6.4.4.2.4.4.4.4.2.4.6.6.6.8.6.8.8.8.8.V.t.B.8.B.2.H V 0 % o X             X                                                             UXUXUXUXUXUXUXUX",
     396"UXUXUXUXUXUXUXUXUX        # $ 7 b U { l.l.{ l.z.z.z.x.W.T.Y.Q.Y.T.T.T.U.Y.T.Q.&X&X&X&XW.Q.XX`.Y.tXdX2Xf + . # . . .   O                         O O @ ; : d f ` Y  .g g R S u u w N A H J ..+.N.N.k.f.F.F.J.F.u.+.M m k 6 j j b Y I I 7 0 8 w 9 y e > UXUXUXUXUXUXUXUXUXUX& & e i S S S K S v l x k z v c v n ..;.$X).I.P.J.F.F.F.F.L.R.H.H.H.H.H.H.H.C.7.2.2.2.<.>.2.2.3.6.2.2.2.2.2.4.2.4.4.4.6.6.6.6.6.8.8.8.B.B.B.B.8.:.V x 8 = o   X         X                                                             UXUXUXUXUXUXUXUX",
     397"UXUXUXUXUXUXUXUX.         $ < j M U U &.&.l.l.l.l.x.h.Y.Y.Q.Y.Q.Y.Y.Y.Y.L.Y.&X&X&XW.&XQ.T.XXU.m.2X` e & % # + . + O                             O O ; : e r f Y Y R Y S S S N B D G ;.N.u.k.f.G.F.J.J.J.J.J.i.$.+.M j 7 5 2 2 < 1 1 < < 3 < 2 9 u S R i > UXUXUXUXUXUXUX@ e 7 w w 7 c v k v k k v n v n F ..<.;.v 2._.[.).~.F.F.F.S.D.F.L.L.L.L.L.R.R.D.H.C.C.6.4.2.>.2.6.6.2.2.2.>.>.>.2.2.2.2.2.2.4.2.3.6.3.6.8.8.B.8.B.8.Q c q 2 o   X X       X X X                                                         UXUXUXUXUXUXUXUX",
     398"UXUXUXUXUXUXUXUXX       . $ 1 k U U &.&.&.&.&.l.l.l.s.Y.Y.Y.W.Y.Y.Y.Y.Y.Y.Y.&X&XQ.W.&XQ.Y.T.A.} ' s % % + . . O O                           O O O + : : d f Y Y Y ( A P H J ..;.N.i.f.G.F.F.K.K.P.P.P.P.L.t.q.O.1.O.3 8 2 # # # # $ # $ 1 1 1 2 w R R R i e UXUXUXUXUX> 9 w r 0 3 7 j j k k m U K K F G -.S.L.;.n D 3.$X[.).^.~.U.U.L.D.L.F.L.L.F.L.D.D.L.R.R.H.A.C.2.>.2.2.2.2.2.2.>.>.>.>.>.2.2.2.2.2.2.2.4.2.3.8.8.6.8.V.3.K x 5 % X X   X       X X               O                                           UXUXUXUXUXUXUX",
     399"UXUXUXUXUXUXUX        O . < 4 k =.U U U &.&.&.l.l.w.G.T.Y.Q.Q.Y.Y.Y.Y.Y.L.Q.&X*X*X&X&XW.Y.T.v.' f > & % % +   O                               O O + : e e Y ( ( ~ ! Q ;.1.N.k.f.G.J.P.I.P.P.P.P.I.P.P.Y.E./ U +.u.5.x & % # % . . . . . # < 1 1 0 i i i i e & UXUXUX> 9 r w 5 < 1 1 j k k n U m K F G D 5.P.D.H v G H 3.$X].).).(.(.^.~.I.R.D.H.F.F.F.J.J.R.D.R.H.H.C.6.3.3.2.2.>.>.>.:.:.>.>.:.>.>.>.2.2.2.3.2.2.3.3.2.6.8.8.Q N q 2 o X   X     O * X X           O   O O                                       UXUXUXUXUXUXUX",
     400"UXUXUXUXUXUXUXo * , s h + 1 4 v U @.U @.&.&.&.&.l.u.G.Y.Y.W.Y.Y.Y.Y.G.Y.W.Q.VX&XW.!.Q.Q.Y.E.} ` d & @ . . .                               O O O ; + e e i E ~ 3.:.<.1.u.d.G.K./.~.^.~.~.I.P.P.I.P.I.R.A./ U O.1.a.a.B % # % # # .   .   .   # < 1 & o o X X @ @ @ & 2 8 8 < 1 1 1 4 k M M m K K n V J >.D.~.6.u l n H W ^ B.).).(.(.(.).).(././.^.U.L.L.F.D.D.D.D.H.H.H.A.6.3.:.:.>.:.-.>.;.>.;.;.:.>.>.2.2.2.2.2.2.2.2.2.2.6.:.D x 0 % o . X X     X X X         O O   ; + + .                                   UXUXUXUXUXUXUX",
     401"UXUXUXUXUXUXUX: ] <X<Xh : 3 4 b M U @.@.@.&.U &.*.d.Y.Y.G.Y.W.Y.G.Y.Y.G.W.*X&X*X*XW.Y.Y.W.b.` ` : o % . +                                   O . + > i i H :.6.i.i.s.G.U.(.].).).(.(.^.~./.I.I.I.I.P.8.P Y @.N.d.D.S.Q % . # . .               . $ $ .         o & 9 2 2 < 1 3 3 7 k m m K G F V B D -.Z.P.L.W 9 8 x n C Z E V.~.).(._.).).].{.[.[.{.).(.U.D.d.Z.S.L.R.R.H.A.6.:.:.-.:.-.-.-.:.-.:.>.:.>.:.>.:.2.2.2.2.3.2.2.2.3.Q c q 2 . X X X X   X @         O O ; : a a a ) p O                                 UXUXUXUXUXUX",
     402"UXUXUXUXUXUX, ] 5X5X<Xh $ 3 j m U L L @.@.@.&.@.w.G.Y.Y.Y.G.W.Y.Y.G.G.W.&X*X*XW.W.W.Y.Y.%X} f d & # .                                       O + % e u H ..1.i.a.D./.{.|.|.|.].].).(.~.~.~.I.I./.U.A.! P T O.i.F.F.Z.;.< . . . . .               . # # .         o 2 2 < 1 3 3 4 k n m K F V V V D J 5.K.K.p.Z 9 & q F D A R  .E.'.).(.(._._.).].[.[.}.}.|.{.U.D.S.S.Z.D.D.H.A.6.:.-.:.-.:.-.:.:.;.:.;.:.>.>.>.>.2.>.>.:.:.:.>.:.:.D l 5 &   X         X   O     O ; a ) ' ,X3X3X) X     X                           UXUXUXUXUXUX",
     403"UXUXUXUXUXUXh ] 5X5X<Xh < 4 k b M U M L L @.@.@.g.G.G.F.G.Y.W.W.G.G.G.W.*X*X*XW.E.W.Y.W.n.[ h : # . . .                                     + . = e C ;.N.d.D.'. X|.|.|.|.|.}.].).^.^.~.~.~.I.L.8./ K T +.1.d.F.F.D.<.0   . . .                   . # .         . 2 2 2 1 1 4 k k M n F V V V D H ;.D.P.L.2.u % % 8 V G P ( | | E.$X].(.(.(.).).].[.}.|.|.|.|._.R.S.d.Z.C.Z.A.C.8.>.-.-.;.-.-.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.J z 5 < .   X X       X O O O ; a _ >X3X6X7XiX' O O                               UXUXUXUXUXUX",
     404"UXUXUXUXUXUX` <X5X5X] p < j k m K M M L L X.@.o.s.G.G.Y.W.G.G.G.G.G.W.*X*X*Xj.j.W.G.H.M.z._ d o . .                                       . @ % 8 C ..N.d.`. X|.|.|.|.|.|.|. X[.(.(.^./.~.^.R.>.P / T O.1.S.D.F.D.S.5.x . . . .                     # #         # e e r 1 3 j k n n n V F V D F -.p.J.K.S.Q 9 % % 2 w c ! ( |  .| y.H.).(.^.(.).].[.|.|.|.|.|.|.}._.U.S.a.p.Z.Z.7.2.:.-.:.-.-.-.-.-.-.-.:.-.:.-.-.:.-.-.-.Q Q Q Q Q D l 2 $ O X X X         O O : ) >X3X4X6XiXiX1X: O                                 UXUXUXUXUX",
     405"UXUXUXUXUXUX] <X5X<X_ : < j m m L K L L L L o.$.s.G.G.G.G.W.W.A.S.E.E.W.W.E.j.s.E.S.A.m.} p : o . .                                         . = x O.1.A.'. X|.|.|.|.|.|.|.|.|.}.].).).^.~.R.,.H P / ,.+.a.F.L.D.S.S.i.D # . . .                     . # .       & r r r 3 j k n n v V V V F F H <.D.J.J.p.A = o o % = w C (  . .R R W H.).(.).).).].}.|.|.|.|.|.|.}.]./.A.i.C.C.7.6.>.Q -.-.-.-.-.-.-.:.-.Q -.-.-.Q Q -.Q Q J J J H H x 5 8 : ; * X X O   O O O a _ ,X3X6X7XiXsX1Xf O   O O                           UXUXUXUXUX",
     406"UXUXUXUXUXs <X5X5X2Xh # 1 j b M M K L L L X.o.1.s.G.G.G.W.W.G.G.A.j.W.j.j.j.7.j.s.A.E.qX_ s + o .                                         . % 9 k O.s.'. X|.|.|.|.|.|.|.|.|.|.|.}.].].].Y.,.D H H $.1.u.S.K.F.D.S.Z.i.J &     .                       . . .   X & Y g e j k n n v V V n F D D -.7.D.F.D.6.Z & . % % . & q v b R i t y E H.|.[.].].[.|.|.|.|.|.}.}.[.[.).U.Z.5.i.7.5.>.-.-.-.-.-.-.-.Q -.-.-.Q ..Q ..J J J J J H D F D z q 2 a _ > *     O O O ; r ' >X3X6X7XiXfX7Xf @   O O                           UXUXUXUXUX",
     407"UXUXUXUXUXh <X5X5X<Xe & < j n K K M M L L G o.1.G.G.G.G.d.W.j.W.W.s.A.j.j.i.5.i.s.E.M.} s : + o .                                         . # 5 k +.U.}.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.!.>.H H H G O.1.a.L.L.G.A.Z.p.7.Q 2 . . . .                       . .   o h ` ` g j k n n v V V V n D J >.C.D.D.Z.2.u % o % % o . & 8 q l y y y y Z $X|.}.[.[.|.|.|.}.}.[.}.].].).^.L.7.>.<.>.>.-.-.-...-.-.Q -.-.J J J J J J J J J H G D D F V c q 3 a f h * X X   O - - a ' >X9X6XiXiXfXdX_ O   O O                             UXUXUXUX",
     408"UXUXUXUXUX` 5X5X5X .t # 1 7 m n n K K G L L O.u.f.S.f.S.G.W.W.S.A.s.s.s.i.8.u.8.s.j.c.f : : % o . O                                       o & j M u.).[. X}.|.|.|.|.|.|.|.|.|.|.|.|.@X>.H H L X.X.=.1.S.L.F.S.A.A.7.8.-.8 . .                           . # X , ` 1X} Y b M n n V V F V V D ..7.Z.Z.Z.C.Q 9 % % . % . . . . 9 5 q 9 = 9 % Z _.|.}.|.|.|.}.}.[.}.[.[.{.].^.P.B.......-.-.-.Q ..Q J J Q J J J J J H J J G D D F V V V c B 6 7 r ) f > * * @ - ; p a ' >X,X6X7XiXiX7X' @   O O                             UXUXUXUX",
     409"UXUXUXUXUX .5X5X5Xt , o 1 j b n m F M M M G X.u.G.G.G.G.Z.W.j.E.j.j.s.5.1.<.1.5.s.E.c.a ; + + .           O   O   O O                     . & k M S.).).].}. X|.|.|.|.|.|.|.|.|.|.{.6.J D T T l.&.O.5.D.L.G.Z.Z.s.E.s.;.0 # . .                         . # o , <X2X>XI M k v v V n V F V D :.C.D.C.C.7.A 9 % o . % .     . . & 0 q 9 = = y ^ {.|.|.|.}.}.}.}.[.[.[.{.{._.H.4.J M ..-.-.-.J J Q J J J J J H J H G H D D D D D D V c V c l 4 r f ] ` * *   - - ; a _ >X,X6X7XiXiX6X' - X O O                             UXUXUXUX",
     410"UXUXUXUX, ` ] ) s + # < 7 7 b n n n G G K G =.s.G.G.G.s.E.G.W.s.s.i.s.1.<.1.1.1.8.j.T a ; @ o . O         O O O O O O O               . . O & 4 F C./.'.(.).}.|.|.|.|.|.|.|.|.|.{.6.Q H P l.b.eXx.1.Z.D.Z.Z.s.C.E.8.j.>.q # .                           . # . , <X5X .} U M M V V V F V C H 2.C.C.C.C.6.A 9 % X . . .         % 2 5 0 2 = t t V.}.}.|. X}.{.[.}.[.[. X/.B.3.,.P M =...Q -.J J J H J J J H H G H D D D D D D V V B B V B l b f ' 1X] h * O - - p a _ ' 9X6X7X7X7X9X' +   - O                             UXUXUXUX",
     411"UXUXUXUX, , @ X     # 1 6 l v n n n K M G n J s.G.f.G.s.s.j.j.j.s.i.i.1.+.;.;.1.g.5.S + @ + @ + O O O O O O - - - - O O   O         . + + . # 5 F t.A.R././.].}.|.|.|.|.|.|.|.'.8.H H P q.n.rXyXm.j.W.E.A.8.8.8.8.t.s.8.N # .                           . # . +  .0X` { U M n V V V n V D J 4.C.C.7.7.6.A & = o . .         X   o # 2 q 2 t t R V.].|.|.}.{.[.}.[.].^.B.! ! ! H K G J J J J J J J J H J H D D D D D D D D V V V V B V B l 7 [ } 3X1Xh *   - - ; a _ ' 3X6X7X7X7X,X_ ; O O @ O                           UXUXUXUX",
     412"UXUXUXUX@ X         # < 7 k v m n n F M n n J s.G.f.W.G.A.Z.j.A.8.i.1.1.;.+.;.1.4.,.x , @ @ @ + O O O - O - ; ; ; ; - O         O O . . % o % = z F ! V.H.H.^.{.|.|.|.|.|. X#Xt.W ~ H ! c.n.qXv.j.E.E.E.E.8.8.4.<.8.t.8.z                               . .   % e ` [ U m m n V V V V V D Q 6.7.7.7.7.4.A % o o .               . o & 2 0 u i E y.:X$X X{.}.}.[.{./.B.Q ! / / q.X.G ..J J H H H H H H D J D F D D D D V V V V V V V C B l l r } 1X<Xh = X - ; p a f 1X6X6X7XiX7X,X_ ; @ O O O                           UXUXUXUX",
     413"UXUXUXUXO X         # < q x v n n F n n n G L i.d.G.s.a.s.j.s.j.s.1.1.;.+.;.;.1.1.,.N & @ @ @ @ @ O ; - - p p a p ; ; - O O O O O . . O + & > = 9 6 x E 3.B.H.).}.|. X X.X@Xy.! ! P J ,.l.l.e.1.5.8.t.j.m.j.8.1.>.;.<.-.8 . .                             . . # 9 > b m m m V V V V V V H 2.6.6.6.6.6.4.A % o   .   X X             % & 5 q u R ( IXIX$X$X[.[.[.].T.y.E ( ( / 0.,.;.-.Q Q H J H J D H D H H F H D D C D D C C V V B B B z x r _ ,X} g * @ ; - p a _ ,X6X7X7XiX7X>Xs p O O O O                           UXUXUXUX",
     414"UXUXUXUX            . < j v v n n n F n n F ..i.G.S.a.s.s.s.s.i.i.<.;.+.+.O.O.;.,...S : & : , + , - ; , p a a a a : - - - O O O ; + @ + * , > i w c x N Z ! 3.H. X|.}..X-Xy.! P J o.o.#.$.,.;.<.<.8.4.r.t.t.t.8.;.;...F < .                               . . % 2 & j m m n B B V V v V J :.6.6.6.6.6.2.A o     . X * X               o 2 0 z Z R IXIXIX$X$X{.|._.E.( S A P S #.t.p.7.4.:.Q H H D D H D H D D D D D D D D V D V V C V B x l w _ 1X}  .t @ ; - ; a ' ,X6X7X7XiX7X>Xa : O - - O                           UXUXUXUX",
     415"UXUXUXUX            . < 6 x v v v n F n n n G i.s.d.s.i.8.5.1.1.1.+.O.O.O.O.o.O.o.J w a s e > : : : a a > s f f f a p p - + + O + @ & = t > g { eXqXT N u ( y.%X@X{.@X%Xy.! ! -.o.O.O.O.O.;.;.<.;.;.;.;.q.0.0.,.,.....V #   .                             . # 2 8 < 4 x v m V c V V V V H 2.4.6.6.4.6.4.A = . .   X * *                 o 2 l N R R IXIXIX%X$X X!.y.P E A D V x D >.C.R.C.2.Q Q H H D H D D D F D D D D C C V V B V V B N l q f 1X} g > * + ; - a >X6X7XiXiXiX6X3X) : @ - @ O                           UXUXUXUX",
     416"UXUXUXUX          . . $ 6 j v v n v n F n G G 1.s.s.i.5.1.<.;.;.O.O.=.O...G o.o.o.F 0 > d d f d a a s f f f f f f f a p ; ; @ + o o * > h ` tXbXmXNXy.A E / m.IXIXZX%Xc.P P q.#.$.O.O.O.;.<.,.<.,.;.;...,.,.q.q.,.;.-.D $                                 . # 8 8 5 4 k v V c c v V V V J 2.2.2.2.2.2.4.W % o     X * *                 X o & 5 R R | %XIXIXIX%X%Xy.( E A B x 9 % 8 W 7.A.C.7.2.-.H D C D D D D D D D D D V V D V V C V z w l ` 1X} Y t = , ; : a >X6X7XiX7XiX7X6X>X,   O -                             UXUXUXUX",
     417"UXUXUXUXX         o . $ 3 x c n n v n n F F G 1.i.s.1.1.1.;.+.O.O.O.G ..=.X.#.o.o.G 5 > f f f d d d f f _ _ [ _ f s > ; ; ; , @ @ * t g b.NXGXNXyXn.w.J ! y.m.IXIXIXtXy./ ,.$.$.$.O.;.;.,.>.4.,.;.;.;.;...P / q.,.,.,.V #     .                           . & w 0 2 4 x V V V c V v V D Q :.:.:.>.>.2.2.W 9       X X X                   X . % w u R (  .2XIX%X%Xy.^ P c l 9 * * = = N Q 2.C.C.6.:.Q J H D D D D D D D D D D C C C C B z z w [ 9X1XR y > ; ; ; r >X6X7XiXiXiXiX7X,Xp O O -   X                         UXUXUXUX",
     418"UXUXUXUX  X X X X   . # 1 l v v v n n n n n G ;.1.1.1.O.O.O.O.=.=.=.G G L #.#.%.$.F 6 > f _ f [ _ ` _ _ [ _ ` _ _ d d , , , > s > h | hXMXGXNXeXm.v.w.,.,.,.m.m.eXm.n.c.*.*.$.$.O.O.,.,.,.;.,.1.,.,.;.....J P ! ,.9.,.N #                                 . & w w 0 3 j v V c c V V c V W Q :.:.:.:.:.3.Q 9         X                       X * = 9 q l w Y y.m.y.! H z 5 9 * * * o o o % w Q 6.C.B.4.:.-.J H D D D D D D C D C C C C B N N b 1X0X} g y t h ; ; r >X6X7XiXiXiXfXiX>Xa . O O O                           UXUXUXUX",
     419"UXUXUXUX  X X X     . # $ l v v n n v n n n G =.;.1.O.O...=.M G G M G =.#.#.%.c.$.K l d f ` [ ` [ _ ` [ ` _ [ _ f d > , , , h g z.rXbXbXNXeXv.c.0.0.9.,.,.w.v.m.m.n.n.v.w.w.,.O.,.;.,.;.,.,.,.,.,.,.,.o.....o.o.,.2.,.0                                     2 w w 2 1 j v V V c c c V V H ~ ~ Q :.~ ~ :.~ y X                             X X * * t = 8 w w N E R N N w = * * * * X   X o = 9 N Q 4.C.7.2.:.Q H H D D D C D C D C C C C Z l } 1X1X1Xg y t , : ; a >X6XiXiXaXfXfXiX' + + O O                             UXUXUXUX",
     420"UXUXUXUX@ X X X X . . . $ 6 k v v v n n n F F ..;.+.O...=.G G M M G M X.%.l.l.c.#.M b d ` ` ' } [ ` ` [ ' ` f h > > > > ` ` } rXbXGXNXeXv.0.9.9.0.9.q.0.0.r.w.w.v.v.e.w.,.w.9.,.;.-...o.,.,.,.,.,.,.,.....L P o.,.8.J =                                   . 2 u N 8 3 j v V v c c c V C H H W ~ Q Q Q Q W y .                           X X * * t * * * t 9 9 9 9 = = * * * * * * o *   X X X % 2 N :.7.B.7.6.>.-.J H D C C C C C C D C z b ' 9X9X} t t t > > ; _ ,X7XiXiXfXfXfXdX) @ O @ -                             UXUXUXUX",
     421"UXUXUXUX  X   X X     . $ 3 k x v v v n v n n F O.O.O.M M M M n M M M X.%.l.n.b.&.M m I ` ] ' } [ ` f f f f d s > > s g } bXGXbXbXyXn.0.q.9.9.,.9.9.0.0.0.0.9.0.0.0.0.9.,.O.,.o.,.,.,.o.o.,.9.q.q.q.,.o...J o.P q.8.D #                                   # 8 A Z 2 3 j k V c c B c B B D A H W H Q W ~ A 9 .                           X X t * * * * * * * * = * X * * * * * * X * * * o       X o 9 Z :.7.p.C.4.:.Q H H D C C C C V C N w 1X2X2X` y t h > , + _ 3XiXiXfXfXfXfX,Xd ; O @ O                             UXUXUXUX",
     422"UXUXUXUXX X X       . . # 3 k x v v v v n n n G O.O.=.M M n n M n M M @.&.x.b.x.#.M m I f _ ' [ ` f d : > : h h h ` } rXbXGXGXNXeXm.0.q.9.$.q.9.9.9.0.0.e.0.0.0.0.0.w.9.o.9.,.,.,.o.,.,.,.9.9.,.q.,.q.,.,.P ..o.,.8.S                                     $ w A Z 8 1 j x v V c c c c V B z B B C H H H A 9 o                         X * * * * * * * * * * * * * * * * * X * * X X * X X X X X X o X o 9 E W 4.7.7.2.:.Q J H C C C C C C Y } 0X1XR y t t > : : ' 6X7XsXfXfXgXiX>Xa ;   O O                             UXUXUXUX",
     423"UXUXUXUX    X         . # 1 j k v k v v v n n F G ..M M n n n n n M =.L &.l.b.b.l.T U I g ` ` ` f g f > , > g } qXhXMXGXbXNXyXn.m.0.9.#.9.9.q.0.0.0.0.0.0.0.0.0.0.y.9.q.,.9.o.9.9.9.9.,.9.q.9.9.9.,.q.,.,.o.o.,.>.q.w                                   . < z A Z 9 1 j k c c z z c c c x l 6 l x B N B z 9 o .                     X * * * * * * * * * * * * * X * X X X * X X X * X X X X X           * = y u Q 2.7.B.6.:.W D C C A A N I 1X9X` t y t i e @ ; >X6XiXsXfXfXfXiX] a ; O   O O                           UXUXUXUX",
     424"UXUXUXUX  X             . 1 j v k k v v n V n F G M M n M M n M n M M M L &.l.b.l.{ K b f f h d e > > h h } eXzXMXGXbXhXtXn.m.c.0.0.9.q.9.9.$.9.9.q.0.0.0.r.0.0.0.9.0.9.q.9.9.9.9.q.9.0.w.y.0.q.y.9.q.q./ q.q.y.,.P : O                                 . < N A Z y 1 j k c c z c c c c x 5 5 3 6 q l x q 2 #                       X X * * * * * * * * * X * X X * X X X X X X X X X X X X X X . X     o o o = = u H >.6.6.3.-.Q H A A S [ 2X1X` y i i h > @ p >X6XiXsXfXfXfX9X) ; ; O @ @ O                           UXUXUXUX",
     425"UXUXUXUX                . < 4 x c v v v n v v n M n k n k k n n n M M M L L &.l.b.%.U m r s e & o @ > [ rXMXGXMXJXNXtXm.v.c.0.q.q.q.9.0.9.q.0.9.9.9.0.0.0.v.0.0.9.0.9.9.9.0.9.q.9.0.0.v.c.v.0.c.c.0.0.0.0.q.,.8.w.I + +                                   1 N E Z r 2 4 j k c c c x c c l 3 1 1 1 3 6 6 5 2 $                       X X X X X X * * * * X X * X X X * X * X X * X X   X   X                     X X o 9 Z Q >.6.2.Q W A Z ' 9X1XR y t i i > & : >X7X7XsXfXfXiX>Xp - - @ O                             X UXUXUXUX",
     426"UXUXUXUX                . $ 3 x x v v k v v n n n n n k n n n n n n M M M M L { %.c.$.L b e f h s } 2XbXMXMXNXhXtXn.c.c.c.c.c.0.0.q.9.9.9.q.q.9.9.9.0.0.0.e.0.0.0.0.0.0.0.0.c.c.0.v.t.v.v.m.v.v.c.c.y.m.c.0.,.t.b._ + +                                 . 5 C A N 9 < 4 k x c c x c c c x 3 1 1 1 1 3 5 3 5 <                           X X X X X X   X X X X X X X X X X X X X X X   X X X X                 X X X X X o 9 z ~ 2.2.:.A S ' 1X` t y i t e e > a ,X9X7XsXfXfXiX' - O O - O                     X X   X   UXUXUXUX",
     427"UXUXUXUX                . $ 3 j k v c v v v v n k M k n k n n n n n n M L G X.X.#.w.9...K I _ } dXxXbXbXhXyXn.m.b.c.c.0.0.0.0.0.q.9.9.q.9.$.9.9.9.9.0.0.0.0.c.0.0.c.0.0.0.c.c.c.m.n.n.m.m.n.n.n.tXm.eXtXn.t.t.tXqX_ a + . .                             # 5 Z E u % $ 4 j x x z c x c c x 3 1 1 1 1 1 1 1 1 1 #                             X X     X X X X X X X X X X X X X X X X X X X                     . X   X . o o = 9 N Q :.W u _ f t t y t R t > = s >X6X7XiXiXiX6X) @ O O O O                 % % * X   X   UXUXUXUX",
     428"UXUXUXUX                  # < l c c k z v v k v n v n k n k k k n n n G M O.;.<.1.<.4.:.H Y dXxXbXbXrXn.c.0.q.q.q.c.q.c.0.0.0.q.9.9.$.q.q.9.$.q.9.9.0.0.0.0.t.c.v.c.c.v.v.v.n.m.n.n.eXtXtXrXrXNXlXbXbXrXn.m.tXwX1Xs a + O O .                           $ 6 A W u % $ 3 j k x c x c c z x 6 1 < 1 1 1 1 1 5 1 1 .                                     X X X X X X     X X X X X X X                               X     . .   o . & u A u > * = t > t t > = > e >X3X7X7XiX7X<X; X     O X                 = 9 o o X X X UXUXUXUX",
     429"UXUXUXUX                  # < 6 x k x k v v v v v v n k k n k M v n G =.,.1.1.5.i.5.t.l.} 1X2XrXrXm.c.%./ P q.! #.q.q.q.0.0.0.9.q.$.,.9.#.9.#.9.9.9.0.0.0.v.v.0.v.c.v.v.v.n.n.n.eXrXtXhXbXkXlXbXbXbXlXtXm.b.uX2X' ) _ a ; O O                           < q W ~ u % % 3 j x x z x x x x z l 1 < < 1 1 1 1 1 1 1 < .                                         X X X X   X X X X X   X   X                             . .   . .   X X 9 S P u = = o & t > > > : & ' 6X7X7X7X3X)   @ O O O                 . 2 9 = o X X   UXUXUXUX",
     430"UXUXUXUX                . . # 4 x k x k c v v v v v k k v v G M G O.;.1.5.5.1.8.0.b.2X8X8X,Xd ! t.9.q.! / P #.q.q.q.q.q.q.9.0.9.q.9.q.o.o.9.9.9.9.0.0.0.c.v.c.v.v.v.v.m.n.n.eXIXyXhXlXkXbXbXbXbXbXbXtXm.n.rXwX1X>X_ ' ' p O                           . < z Q ~ w # % 5 j x z x x x x z c l 1 < < 1 1 1 1 1 3 3 3 <                                       X     X X     X X X X X     X X                             .   . . . . % R q.T A A i y > o @ , ; + : _ 3X7X7X7X<X    O O O                   . y y t = * o X UXUXUXUX",
     431"UXUXUXUXUX                . # 1 x x x x k z k v v v n n n M ..;.1.<.1.<...J P } 1X6X9X1X' a + 0 :.4.,.,.o.P q.#.#.q.q.#.q.#.#.q.9.9.9.#.9.#.9.9.9.0.0.0.e.c.v.v.v.n.n.n.eXeXeXrXlXkXkXbXbXbXbXbXbXyXm.n.rXlX1X1X>X,X9X1X;                           . # 5 H 3.~ y # % < j v z x x x x x x x 3 < 1 1 1 1 1 1 1 3 3 3 < .                                           X   X   X X     X X                                 . . . . . & i c.{ T W H H S i r 9 : + : : a ,X6X6X3X) O     O O X                 % u y t = = o o UXUXUXUX",
     432"UXUXUXUXUX                  . $ j x x k x x x v F G J ..;.1.1.;.;.-.F c r f ' ,X3X1X' s ; ; +   S ,.4.,.,.,.#.#.#.,.o.,.q.,.q.9.9.,.9.o.o.9.q.q.0.0.0.v.c.v.v.m.n.n.n.eXeXyXNXlXbXkXbXbXbXbXbXbXrXn.n.tXlXdX1X>X9XiXiX'                             . # q :.2.^ w & % 8 j v c x x x x l x x 6 < < 1 1 1 1 3 3 3 3 3 3 <                                                     X X X   X                                 .   . o o 9 / v.c.T W W P P P S S w r 2 2 < >X6X3X' p ;     O         X         o 9 u y y = = = o UXUXUXUX",
     433"UXUXUXUXUX    X             . $ 3 l j x k x c n G ..<.i.u.;.J V N r r a s _ ' ' ] ] a + + . + + # S t.8.,.,.,.o.o.! o.o.o.#.,.o.q.#.,.9.9.#.$.$.9.0.0.c.v.v.n.n.n.n.n.eXIXhXlXkXbXbXbXbXbXbXJXlXeXeXtXuX9X1X1X9XsXfX9X)   O O                       # $ l 3.2.~ N & % 2 q c k c x x x x x x l 1 < 1 1 1 1 3 3 3 3 3 4 3 <                                                 X   X   X   X                             .   X o o o Y v.b.c./ ~ ! ! ! W P A T S r r 3 ' ,X>Xa - O     X                   % y u y y y = * o UXUXUXUX",
     434"UXUXUXUXUX    O               $ < 6 l j x n F ..;.5.i.5.P b & : + : p a a a a a a O O + O O + + . # K t.8.>.,.,.-.P P o.,.o.,.q.o.q.q.o.9.q.%.q.0.0.c.v.m.b.m.eXtXeXeXyXlXlXbXkXbXbXbXJXJXbXNXn.n.rXpXdX9X1XdXfXgXiX,Xp - O O O                   . % < D 2.3.3.Z & 9 & 0 j z x x l l l x x j 3 1 1 1 1 1 3 3 3 3 4 3 4 3 < X                                                   X X   X                           .   X   X X S c.n.c./ ! ! ! ! ! ! P P P S m b l _ >X_ : . O                       # 2 u R u y y 9 % o UXUXUXUX",
     435"UXUXUXUXUXUXX     X   X X   . # $ 5 x c F ..<.p.a.t.#.[ _ ; + O O O ; ; a +     X X   O . + + . + O # S t.8.2.;.,.....P o.,.o.#.,.#.#.q.q.$.q.0.0.c.c.v.v.n.eXtXtXtXrXlXbXbXbXbXbXbXMXbXbXyXm.tXrXlX0X8XpXsXvXcXfX6X] a ; O                       . 2 q Q 6.4.3.Z 8 8 8 8 l c c x l l x x x l 6 1 1 1 3 3 3 3 3 3 3 3 4 4 4 1 . X                                                         X                         X . o o S c.b.| / ~ ~ ! ! / / P P T T T T I T [ { r + # . O         X     X     & u Z Z Z y y t @   UXUXUXUX",
     436"UXUXUXUXUXUXX X X             . $ 5 B Q >.5.i.r.#.I _ ) a + . . . O O . O .               . @ + + + . # x ,.8.6.>.,.o.o.P o.o.! #.q.#.#.#.9.0.0.c.c.v.n.n.eXeXtXNXlXbXbXbXbXJXbXbXGXbXNXyXn.tXlXlX8XpXdXxXvXnXxXiX3X) p - O O                   . % q c 2.B.6.:.Z w w 8 8 x c v x l l l l q q q 3 3 3 1 1 3 3 4 3 3 4 4 3 6 6 3 &                                                   X                         X   . o o % S c.c.c./ ! ! ! ,.! / ! P P P T { } qX1X{ U 2 # # # .                 X   & N Z Z Z u y t @ UXUXUXUXUX",
     437"UXUXUXUXUXUX.   X   X   X     . # 0 H <.i.1.#.Y _ s a a : .   .                         O O @ @ + . + + . 7 ,.t.8.8.:.,.o.o.o.,.o.#.q.#.#.q.0.c.c.v.n.n.tXtXrXNXlXkXbXbXbXMXbXMXbXNXyXeXn.2XlXpXpX8XlXxXmXmXcXaX6X<Xa ; O O O                 . . $ l Q B.B.B.:.B u w u w x c V N l l l l l l l 5 3 3 1 1 3 3 5 4 6 3 3 4 4 j l j <                                                   X   X                     X X X = S 0.c.{ / ! ~ ! ! / ! / P P P T { { z.1XqXz.b 2 $ $ # # #           . .   . w Z Z Z Z u u 9 o UXUXUXUXUX",
     438"UXUXUXUXUXUX. X X               $ 5 Q <...S f f a a ; + .     .                           O + @ + + + + O # 7 K y.8.8.2.,.q.,.o.#.P #.&.&.%.c.c.v.m.n.tXlXlXlXbXbXbXbXbXbXbXJXZXyXtXn.tXdXdX0XdXpXkXMXmXmXnXkXpX6X) : - O O                 . . # < B 2.B.C.B.>.Z N N N u S c v c x l q q q l q q 6 3 3 1 3 3 4 4 4 3 4 4 6 4 l x x 5 %   X   X                                       X                     X X X = u P q.c.{ / ! ! ! ! q./ / ! P P L T { } } z.z.[ r 8 2 & & & # # .       . . & 8 A W E Z u y u =   UXUXUXUXUX",
     439"UXUXUXUXUXUX  X   X     X X     $ 3 l w e > a p - O .                                     O + ; > & : . + ; + r Y c.t.8.8.1.,.$.9.q.q.%.c.c.c.c.n.n.tXhXlXbXbXbXbXbXbXJXNXyXtXyXtXtXrX2X0X8XpXkXbXmXmXmXnXvXjX6X>Xa ; ; O O O           . . . . < 6 Q C.C.B.B.:.A N N A E A B B c c q q q l l q q 6 6 3 1 1 3 5 6 6 4 4 4 4 4 j k c z 6 < o X X X X                                   X X X       X .   X X   o 9 C ! #.&./ ! ~ ! ! ! / / / q.P P L T T T T T U I I e 2 8 9 2 2 < $ # .   . & & 5 A ~ ~ E Z Z Z y =   UXUXUXUXUX",
     440"UXUXUXUXUXUXUX  X           X * $ $   O - O O . .                                           : : : : : : + @ + : r f T c.t.8.8.8.8.w.9.,.q.0.c.c.v.b.eXyXNXlXNXNXbXZXyXIXyXeXyXtXlXuX2XpXpXlXbXMXGXmXmXnXvXaX8X3X) a ; - O O             . . . % 2 x 2.C.C.7.B.3.A A A A E ! A N c c l q q q q w q q 6 3 3 1 3 5 6 6 4 4 4 4 4 j l l x c j 5 $ o X X X                                   X X X X X   X X   o 9 q H o.o.P / / ~ ! ! ! / / / / / P P P T T T T m v q 8 9 9 9 9 = 2 2 % # # 2 2 0 5 c Q ^ ~ E A Z Z u = UXUXUXUXUXUX",
     441"UXUXUXUXUXUXUX    X     X X * * # .     O .       O                                         + : : > e > : : + : ; r r Y 0.y.%Xt.t.t.t.t.t.t.v.e.v.v.n.n.yXIXyXZXyXyXeXeXtXtXlXjXjX0XpXsXbXMXmXGXGXmXmXnXxXpX8X,Xf ; ; O O O           . . . % 2 5 Q B.C.C.C.C.4.Q E E E ! ( E C V V z q q q q q q q 0 3 3 1 3 6 5 6 4 4 4 4 6 6 l l x k z x l q 2 & X X X                     X           X X X X X X o 9 w C H H P ! ! W W ! ~ ! / q./ q./ T P K K T ( T v b j 8 9 9 9 9 9 9 9 2 = = 0 N C w w H :.Q ~ E E Z Z y = UXUXUXUXUXUX",
     442"UXUXUXUXUXUXUX  X X     X * * * X                                                           O ; : d d a f d e : a : : & f Y z.b.eXb.m.m.t.m.t.M.m.n.n.%Xn.tXeXeXIXhXlXlXdXpXpXpXpXkXxXMXmXGXGXmXmXmXnXvXjX8X6X' a - O O O           . . . # 9 0 B 6.A.Z.C.C.C.6.~ ~ ~ E ! ~ E Z N D V x q q 0 q q q q 5 3 1 3 3 6 6 3 4 4 4 4 4 j 6 x x x x c x x l 0 8 % X   X X   X     X X X X X X X X o X X o & w N A J J H H H H ! W ! ~ ! / / / / / / P P P T T P V x l 8 9 9 9 9 9 2 9 2 9 9 w D Q A z z W :.:.~ W E W E 9 X UXUXUXUXUXUX",
     443"UXUXUXUXUXUXUX        X X * * * X o . .                                                     O + : > f f f f f d r a a s s _ _ ' } tXtXtXtXeXeXIXyX%XtXyXeXtXtXlXlXjXjXjXpXjXkXkXbXMXGXGXGXGXGXmXmXmXxXkX8X6X>Xs ; ; ; O O         . . . . % 2 c >.Z.Z.C.Z.C.Z.7.^ ~ ( ( E ~ E A C D F V l 0 q q q q 5 0 5 3 3 3 5 6 5 4 3 4 4 4 6 j l l z z c x x z c x l w 9 & = % % = o o o = o = o o % = 9 u N C A H H H H D D H W ~ ! ! ! / / q.| 0.q.T P K P T P K v l 8 9 9 2 2 9 9 9 9 & % 9 A -.J C z Z Q :.:.~ ~ W ~ E = UXUXUXUXUXUXUX",
     444"UXUXUXUXUXUXUXUX  X   X * * * * X X . . .                                                     O + : a f f ` _ ` ` f f s f s s _ ` } 1X2XlXjXjXjXlXkXlXlXjXlXjXpXjXkXkXkXbXbXbXMXmXGXGXmXmXGXmXmXnXvXkX8X8X9X_ a a ; O O         . . . . % 2 q -.A.Z.Z.C.C.C.C.C.3.! ~ ~ ~ W ~ W A V D F z q 5 0 0 q q 6 6 5 3 3 6 5 3 5 3 3 4 4 4 4 6 q l l j l x x x z N c z z x w w w w w w u u w w w N B C D H H H C D D A A H W ~ ! ! / / / / | | / T P P H K P C c x 8 9 8 2 9 9 2 9 2 = 9 9 N :.-.C z V Q >.Q ~ ~ ~ ~ :.W @ UXUXUXUXUXUXUX",
     445"UXUXUXUXUXUXUXUX      X X * * X X o . # # .                                                     O + : : d f _ ' ` ' } ` _ ` _ ] ] ' 9X7X8X0XjX0XjXjXjXjXkXkXkXkXkXxXMXMXGXGXmXGXGXGXGXGXmXmXnXnXMXjX8X6X9X] a a ; O O         .   . . % 2 0 V C.L.D.Z.Z.C.Z.A.D.7.^ ~ ~ W W W W A D H H D z 0 5 0 q 0 6 q 5 5 5 3 6 5 4 3 3 3 3 4 4 4 6 6 l l l l l x x x x z c B B B B N B B B B B C A D H H A H H D A A C D H H ! ! ! / / / / 0.| q.T P P K F H C B l 8 9 9 8 9 8 8 9 9 9 2 9 w Q ;.-.V N J >.3.Q Q Q Q 3.2.A @ UXUXUXUXUXUXUX",
     446"UXUXUXUXUXUXUXUX    X X X X X X X X . . # #                                                         X + : r f _ ` ' } } ] } <X2X9X9X8X8X8XpXjXjXjXkXkXbXkXbXbXMXMXmXGXGXGXGXGXGXGXmXmXmXmXnXnXbXjX8X9X5X} ` a ; + O O       . . . % $ 9 8 x <.D.F.D.D.C.C.Z.D.D.7.^ W W W Q H H W W A H J C l q 0 5 q 0 q 5 5 5 6 5 6 3 3 3 1 1 3 4 4 6 6 6 6 6 l l j l l x l x z N N N N B N B B C Z C C C C C C C C C C A H H W ! ! ! / / / / q.q./ P K H H K V c x w 8 9 8 8 8 9 9 8 8 8 9 u Q :.J H D J <.2.:.Q Q Q :.6.4.y   UXUXUXUXUXUXUX",
     447"UXUXUXUXUXUXUXUX          X   X     X . # # .                                                     X +   @ > > h f _ ' ' 2X9X6X8X8X8XpXpXjXjXjXkXkXxXMXMXGXMXmXGXGXGXmXmXmXGXGXmXmXmXmXnXnXMXxXjX8X8X6X1X` s ; ; + +   . .   . . % # = 8 q Q D.L.D.F.D.C.C.D.P.R.6.~ ~ W W W W W Q :.W J ..J B q 5 q q 6 q 5 q 0 5 5 6 3 3 3 3 3 5 3 4 4 4 6 6 6 6 6 l l l l l l z z z B B B B B B C B B C C C C B N C B D H H Q ! ! ! / ! / / q./ P K A F C F V B N 8 9 9 9 8 8 8 8 8 8 8 y y H ;.:.J D J <.7.2.>.Q Q Q <.Z.~ X UXUXUXUXUXUXUXUX",
     448"UXUXUXUXUXUXUXUXUXX O X     X X o   . o % # # .                                                         @ @ + : a d f ` ] 9X6X8XpXpXkXkXkXkXxXMXMXcXmXmXGXmXGXGXGXGXGXGXGXmXmXmXmXnXnXnXMXxXjX8X8X8X9X1X] a ; ; + O       . % . # % 2 l H Z.F.F.D.S.S.S.S.L.I.I.6.~ ~ E W W W Q 3.2.:.Q ..J J V q 6 0 q q 5 q 5 0 5 5 6 3 3 3 3 3 4 4 4 4 3 4 6 6 6 6 4 6 l l q l z z N c N N B B B B C B A C C C B A C A H ! ! ! W K H K H K K F C D C C V V c q w 9 9 8 w 8 8 8 8 9 9 w u H >.-.J J D >.7.5.<.:.-.-.-.4.Z.Z O UXUXUXUXUXUXUXUX",
     449"UXUXUXUXUXUXUXUXUX  X           X     o = & $ #                                                       X X X   @ @ , a , h ] 9X0XpXjXsXxXvXMXnXnXnXmXmXmXmXmXmXGXmXmXmXmXmXmXnXnXnXMXbXkXkXjX8X7X8X6X6X>X) : - O . O   . . % % % % 2 w D p.J.F.D.D.D.S.D.L.I.^.U.3.E ^ ~ W Q Q ^ :.2.3.:.Q Q ..J B q 0 5 q 0 5 5 6 5 5 5 3 3 3 3 3 3 3 4 4 3 3 5 3 3 6 4 6 q l l l z z z N c N B N B B B B A C B B A D H H Q ! W H A B V B V B B V V V V V V z w 9 9 8 8 9 9 8 9 9 8 8 w u A <.2.J J J >.p.p.4.4.:.-.>.<.a.6.=   UXUXUXUXUXUXUXUX",
     450"UXUXUXUXUXUXUXUXUX                  o = = y 9 # # .                                                       X     @ @ @ ; : d ] 9X8XpXjXxXvXcXnXmXmXmXmXmXmXmXmXmXmXmXnXmXnXnXnXMXbXbXkXkXjX8X8X6X8X6X5X' : ; O O O . . . . % o % 9 2 v 5.F.J.F.S.D.S.F.F.P.(.^.U.6.E ~ ~ E ^ :.:.2.3.4.2.Q Q ..J J N 0 5 0 q 5 q 0 6 5 5 5 5 3 3 4 3 3 4 3 3 3 3 4 6 6 6 6 l x x z N z B N c N B B B B A C C B B B C D H H ! Q A B c z c c c c c V V V V N z w 8 8 8 8 8 8 w 9 9 8 9 8 u E <.>.J J J ;.a.a.7.5.4.:.;.5.d.F.W O UXUXUXUXUXUXUXUXUX",
     451"UXUXUXUXUXUXUXUXUXUX        X     o = % = 9 9 9 < $                                                             @ O O , : > > ) ,X3X6X8XjXbXMXbXMXMXnXnXnXnXnXnXcXxXxXxXxXxXjXpX8XpXpX8X8X8X5X9X1X,X>Xs ; O O O .   . . % & = 9 w v >.L.K.J.F.D.S.F.F.F./._.^.U.V.E E ~ :.~ :.:.2.2.2.4.:.-.Q J J J z 5 0 0 q q q 0 q 5 5 5 5 6 6 5 6 3 3 5 4 3 6 6 6 q l l l x z z N z N c z B B B C C C B c B V C A H ! ! ! H V c c k z c x c V B c z q w 8 8 8 9 8 8 9 w 9 w 8 8 u A 2.>.-.-.-.-.5.Z.p.7.<.4.2.<.a.J.D.y X UXUXUXUXUXUXUXUXUX",
     452"UXUXUXUXUXUXUXUXUXUX      X o X   X = = y y u w 0 3 $ .                                                       O     X @ ; ; ; @ ; ) ] 3X,X0XjXjXjXkXxXxXkXaXsXiXdX9X9X9X3X,X,X>X>X,X3X9X9X>X_ s : < + - O . . . o . . % 2 y u B G 5.~.(.P.J.F.F.S.F.L.U./.).~.U.B.u Z 3.3.3.2.2.2.4.2.4.4.>.Q -.;.;.J C q 2 q q 5 0 q q 5 0 5 5 6 5 3 1 3 3 3 6 6 q 6 l l x x x z N c B c B N B B B C C N c c B V C H P P ( P P C V c x x x c k N x w w 8 8 9 8 8 8 w 9 8 8 8 u u Z :.4.>.:.-.-.<.p.S.Z.p.5.4.4.5.a.D.J.:.O   UXUXUXUXUXUXUXUXUX",
     453"UXUXUXUXUXUXUXUXUXUXUX    X * o = = = 9 9 w y u w 0 1 $ .                                                     X X X O @ - , @ @ : : g ` ] <X3X0X0X0X9X9X3X3X,X,X>X>X' ' ) _ ) _ ) ' >X>X] a : . . + O . O O . % . . % = y u C -.C.~.(.^.~.K.F.F.D.F.U.U.(.).~.U.~ 9 y ^ V.6.6.3.2.2.2.4.4.>.-.Q :.;.;.-.H q 0 q q q 6 0 0 q q 5 5 5 5 1 1 5 3 6 3 6 l x l x z z z N B z B c c B C B B B z z c c V D H W P ( ! H H V c c v z z z l w 0 8 8 9 w 8 9 8 w 8 9 9 w u A :.<.<.;.;.-.5.D.L.S.p.7.5.5.i.Z.D.K.F.u   UXUXUXUXUXUXUXUXUXUX",
     454"UXUXUXUXUXUXUXUXUXUXUXO     X = t y = = 9 9 w u u N q 1 $ .                                                           @ @ @ @ - - , h h h h _ ] <X<X<X] ] ) ) ) f a a a a a : a a f _ s a - ; O O O O O   . # . . % = y Z H ..C.(.].(.(.~.P.J.F.J.L.~.(.).(.^.H.N % y ^ B.B.A.6.2.>.>.>.2.4.4.:.-.;.>.;.>.J q 2 5 5 q q 0 q q 0 5 0 2 5 1 5 1 1 5 q l x x z z z z z N c c N B B B V B B z N B B D H H J P P H H H D V c x l q w 8 w 9 8 8 8 8 8 w 8 8 9 8 8 u E 4.5.>.-.;.;.4.T.`.J.D.C.7.5.i.C.D.K.P.2.o O UXUXUXUXUXUXUXUXUXUX",
     455"UXUXUXUXUXUXUXUXUXUXUX      X = y y y y y 9 u u u Z C N l 1 # .                                                       X X O @ @ , ; , , > > h g g g g g d a a a ; : ; a : ; : : a a p ; ; ; + O O + + . . # % % o 9 w N -.<.A.(.).{._._.^./.K.J.T./._._.).(./.! o * y W 3.B.!.A.6.2.2.>.>.4.5.4.>.>.<.<.<.<.-.B 0 5 q w q q q 0 0 5 0 5 5 5 5 5 5 q l l l z z z c c c B B B B B B B B B B B B B D H H H H D D B B B z q w w 8 8 8 8 9 8 9 w 0 8 8 w 8 8 2 A :.2.5.<.-.;.;.7.T.#XXXL.D.p.i.i.p.S.J.I.A.w   UXUXUXUXUXUXUXUXUXUXUX",
     456"UXUXUXUXUXUXUXUXUXUXUXUX  X X * y E Z y 9 9 u u N Z A A D x 1 $ # .                                                       X O @ @ , , s > s h > > , , > : ; ; ; ; ; + ; + ; + + ; + ; O . + + O . . . . % % % & & 9 u J 5.R.).).)._.{._.(.^.I.XX=X+X'.{.).^.B.&   o y E 3.B.!.W.A.8.>.>.<.4.5.5.7.<.<.<.<.;.5.;.H N q 0 0 5 0 0 0 5 0 0 0 8 5 5 5 q q q q l z z z c c B B B B B B B B V B V B C D H H C C B z z l q w 0 8 9 8 8 8 8 0 8 0 8 8 8 9 w 0 w W 4.5.<.<.1.<.<.p.I.oX+XOXT.F.Z.a.Z.S.J.P.P.:.O   UXUXUXUXUXUXUXUXUXUXUX",
     457"UXUXUXUXUXUXUXUXUXUXUXUX      X t E E i w y y w N Z A H H D c 4 < # . .                                                     O   @ @ , , s , ; , ; @ ; , ; ; + + ; ; + + ; ; + + O . O . O . . + . . # . . % = & 9 8 x -.R.].].).)._._._.(.^./.+X;X#X_.].).'.E     @ = E :.6.!.Q.W.A.4.;.4.<.4.5.i.7.4.<.;.<.<.<.;.Q B 0 2 0 0 q 6 0 5 0 5 0 0 5 0 5 0 q w w q q z z z z N B B B B c B V B B B B B C B B N w w q w 0 0 8 8 9 8 8 w 0 8 8 0 w 8 8 2 8 Z ~ 4.p.5.1.;.;.5.Z.I.'.XX+XOXXXY.F.D.Z.L.P.~.Z.9   UXUXUXUXUXUXUXUXUXUXUXUX",
     458"UXUXUXUXUXUXUXUXUXUXUXUXUX  X O = u ^ ~ Z N u N N Z A H W W Q F j 1 < # # .                                                       @ + + - + @ O @ - O O @ ; + ; + + + + . O . O . . O   . . . . % % = o % 9 8 w l F ;.H.).].{.).).)._._.{..X:X;XSX#X(.)._.B.o       , u ~ 6.A.&XOXY.C.5.4.<.5.5.7.p.5.5.<.<.<.<.5.u.<.J N 2 5 0 0 0 q 0 0 0 5 0 5 2 0 0 0 0 0 0 0 w q l z l z l x l z N N z N z N w w w q w 0 8 8 8 8 8 0 0 8 0 0 w 8 8 8 8 8 2 u W 4.7.5.<.;.;.5.s.R.~.~.~.`.XXOXOXQ.T.L.J.K.~.U.! . O UXUXUXUXUXUXUXUXUXUXUXUX",
     459"UXUXUXUXUXUXUXUXUXUXUXUXUX  . X o t E 3.3.E Z u Z Z A A W W Q -.J n j 3 < # # . .   .   . .                                                     O O . O   O .               .   .     . . . o . % & % 9 9 u N V ..a.Y.^.).[.[.{.).).).)..X#X;XSX;X:X(.].H.w         * = E 2.B.Q.Q.XXU.D.5.4.5.7.5.p.a.a.p.5.<.<.5.i.i.i.<.J N q 0 0 0 q 0 q q 0 0 0 0 0 0 5 8 5 8 0 8 w 0 0 w 8 0 0 0 q w w 0 w 0 8 8 8 8 8 8 8 0 0 0 8 8 0 8 w 8 w w 8 8 9 N Q 4.i.i.i.1.;.;.5.U./.(.^.~.I././.XX=XOX`./.~./.~.7.    UXUXUXUXUXUXUXUXUXUXUXUXUX",
     460"UXUXUXUXUXUXUXUXUXUXUXUXUXUX  O o t i ^ %X3.E Z B Z A W H W Q Q :.-.F k j 3 < . . . . . .                                                                                 . . . . . o o o % o % % % 9 9 w B G <.D.I.I.I.^.).[.].).).).]..X:XSXSX;X:X).).3.          + X u 2.A.Y.Q.XXT.P.D.5.5.5.5.p.p.a.p.Z.i.5.5.5.5.5.i.1.>.J A l 0 0 0 0 0 0 0 0 0 0 q 0 q 0 0 0 0 8 8 0 8 0 5 8 0 0 0 0 8 8 w 8 w 8 0 8 w 0 0 w 0 w 0 0 8 0 8 8 8 8 Z W 4.p.p.5.1.<.+.+.i.P..X{.(.^.I.I.I./.`.=X-X+X`./._.L.w     UXUXUXUXUXUXUXUXUXUXUXUXUX",
     461"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  * * y E V.*XV.( A A A H W W Q Q Q ;.>...M k j 3 $ # . . # . . .   .   .                                                           .     .   . . . o o o % & = = 9 9 w l V ;.C.I.~.I.I.I.~.^.].].].].]. X.X;XSX;X;X#X).H.y     UXUXUX  O * ~ A.Q.Q.T.U.I.I.D.i.5.i.i.p.p.a.a.d.a.i.5.<.1.5.i.i.5.>.Q A N 0 0 5 5 0 0 0 0 0 w 0 0 0 0 0 0 0 8 0 0 8 8 8 8 8 0 8 8 8 0 0 w 0 0 0 w w 0 0 0 8 8 0 8 9 w N Q 4.7.i.i.5.1.;.+.i.S.K.~._.{.{.^.I.I.I.~.XX=X:X=XoX_./.:.    UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     462"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  O o 9 Z ^ %X*XV.:.W A A W ~ Q -.:.:.>.<.<.;...n k 4 < & # # % # . . . . . . .     .     .                                 . .   . . . . . o o = o o % = = = 8 w w c C ..7.I.(.^.I.I.I.~.I.^.(.].{.{.]. X#X:XSXSX;X#X/.E O   UXUXUXUX      u B.Q.Q.U.U.I.P.P.D.p.p.p.p.p.a.Z.S.S.d.d.p.5.5.5.5.i.i.u.5.>.H C w 0 0 0 0 0 w 0 0 0 0 w q 0 0 w 0 0 w 0 0 0 8 w 8 w w 0 0 w w w 0 w 8 w w 8 8 0 w Z W 2.6.p.a.i.5.1.1.+.1.d.F.P.I.I.(.{..X_./.I.P.~.=XAX-X+X`./.4.# O   UXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     463"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  o = y E %X*X!.B.2.W W Q Q Q Q :.:.>.2.<.5.<.1.O.M k j 5 2 & $ $ # # . # # . . . . . . .   . . .   .   . . .   . . . . .   . o . o o % o = % % = 9 = 9 y u N V D :.C.R.(.].(.(.~.I.I.I.~.I.~.).{.[.[. X#X:XSXSX:X.X~       UXUXUXUXUX    X E W.Q.T.K.P.I.I.~.L.Z.a.p.a.Z.d.S.S.F.S.F.S.p.i.5.i.p.i.a.i.i.4.:.W A N N q q w w w w 0 w w w 0 w q 0 0 w w 8 w w w w w w w w w w w w w w N A ~ ~ 2.5.p.a.i.i.u.1.+.N.a.S.J.J.P.P.P.~.{.{.'.^.~.~.`.-X;X:XoX'.Z.& X   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     464"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    X y Z y.%X*X!.A.2.:.W Q Q :.:.>.>.2.4.4.5.5.i.u.+.M k l 5 1 2 2 $ % # # . % . . . .   . . . . . . . . . . . . . o . . o o o o * = o = = = = 9 8 u q z C H :.7.U.[.}.].).(.^.^.I.I.I.I.~.~.).[.}.[. X#X:XSXSX:XV.      UXUXUXUXUXUXUX    = E.Y.Y.K.P.P.P.~.~.P.D.a.a.a.Z.S.S.F.F.F.J.L.F.Z.p.i.5.5.1.u.a.a.7.4.>.Q J C w q w w w 0 0 8 2 8 2 8 8 8 8 8 8 8 8 8 8 0 0 w u u u Z A Q 3.6.p.C.a.i.5.u.1.N.1.u.a.D.K.P.J.J.J.K.K.I.'..X_.(.(._.=XAX;X=X'.I.Z     UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     465"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    o y ^ %X!.!.Y.D.C.>.Q Q -.:.>.>.<.4.5.7.5.5.i.a.i.+.O.M k j 6 2 2 2 & % $ % # # % # # # % . % o . . % % # % o % % % % = = = = = = = y 9 8 u N V J ,.8.H._. X}.[.].].].(.(.^.~.I.I.~.^.).[.[.[.[..X#X:XSX;X@XZ O   UXUXUXUXUXUXUXUX  O - E Y.Y.P.P.P.P.I.I.I.P.L.S.d.S.S.S.S.F.F.F.J.K.K.L.Z.p.5.5.i.i.a.d.a.i.7.<.2.:.Q W W A Z N N N N u w 0 8 8 8 w w w N Z Z Z Z E ~ :.2.6.B.p.p.i.a.a.u.u.1.1.u.S.K.I.I.P.K.J.J.K.K.P.P./._.{.).).#XSXSXSX:X/.:.o O   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     466"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    * R y.E.E.!.L.D.Z.7.>.:.:.>.>.4.5.4.5.5.7.p.D.D.S.d.i.N.O.M M k x l 5 5 2 8 5 5 2 & 2 $ & % & & = & & & = = 9 9 9 9 w 9 w u u w N B C H J -.7.U..X X X|.|.|.[.[.[.].).(.^.^.~.~.(.].[.}.[.[.[. X#X;XSX:XR   O   UXUXUXUXUXUXUXUXUX    O ( Y.J.K.P.P.I.I.~.~.~.K.D.S.S.S.S.F.F.J.J.K.P.P.I.L.F.Z.a.p.a.a.a.d.i.d.p.p.p.p.7.6.6.2.3.3.:.! Q Q W H W ~ :.:.3.6.3.6.6.C.B.Z.a.a.p.a.i.i.k.u.u.i.a.D.P.~.(.^.~.I.K.J.K.J.K.K.P.I._.{.]..X:XAXSXSX:X2.#     UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     467"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    * t ( %X*XA.D.R.L.F.Z.4.>.>.>.<.4.5.7.p.p.Z.Z.S.D.D.F.S.f.d.u.+.O.=.M n v j j j 5 5 5 2 2 8 2 8 2 9 2 8 8 0 8 0 w q N x c D G J -.<.7.A.H.(.}.|.|.|.|.|.|.|.[.].].].).(.(.^.^.(.].[.}.[.}.[.[. X X;XSX( X X   UXUXUXUXUXUXUXUXUXUXUX    O ~ P.I.P.K.P.I.~.~.~.^.~.L.D.S.F.F.J.J.K.P.P.I.I.I.I.K.L.D.Z.a.a.a.d.i.d.d.d.S.d.d.Z.Z.p.p.7.7.7.8.7.p.p.p.7.B.C.p.Z.Z.d.a.a.a.a.d.u.u.u.u.a.d.D.L.I.^.^.^.^.^.~.P.P.K.J.J.J.J.I.^.(.].{..X;XSXSX-X2.=     UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     468"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX  X   t m.%XA.R.D.D.L.F.F.p.5.<.4.4.5.7.p.Z.Z.S.D.D.D.D.F.F.F.F.G.k.k.N.N.+.O.=.=.n n v k v c v n n v n n n G G G G G ..O.;.1.i.p.R.'. X|.|.|.|.|.|.|.|.|.|.}.}.[.].].).).(.).).[.}.}.}.[.[.[.}.|..X;X| @   O UXUXUXUXUXUXUXUXUXUXUXUXUX    O 3.I.K.K.P.P.I.I.~.^.(.^.P.F.F.L.J.J.K.P.P.P.P.I.I.I.I.I.K.L.D.S.Z.d.d.d.d.d.d.d.f.d.d.d.d.d.a.d.d.S.d.d.a.d.d.d.d.d.d.f.d.a.i.k.s.d.S.D.R.(.).).(.(.^.^.^.~.~.P.P.K.J.J.L.U.^._.).]..X#X;XSXSX8.= O   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     469"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    X g y.E.H.D.D.F.L.J.J.D.S.7.5.5.7.p.a.C.Z.D.D.F.F.L.F.F.F.F.F.F.F.F.f.f.f.f.f.u.u.1.1.1.u.u.1.u.1.u.u.u.s.a.d.G.L.U.^.].[.}. X|.|.|.|.|.|.|.|.|.|.|.|.|.}.[.[.[.].].].[.}.}.[.[.[.[.[.[.[.|.#X| O     UXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    O :.K.P.K.P.P.I.~.~.(.(.(.~.P.J.K.K.P.P.P.P.P.P.I.I.I.I.I.I.I.P.P.L.L.D.D.Z.S.S.S.d.d.d.d.d.d.d.d.d.d.d.d.d.S.S.Z.Z.Z.A.Z.D.R.U.(.].].[.].].).).).).(.^.~.~.~.I.P.K.J.K.~.).).].).]..X:XSXFX%X= O X UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     470"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      i y.A.D.D.F.J.F.F.J.K.L.Z.p.p.p.C.Z.Z.D.D.R.D.F.F.J.F.J.J.J.K.K.K.J.J.J.F.F.F.F.G.G.F.G.F.G.D.F.L.U.U./._.{.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.[.[.[.[.}.}.[.[.[.[.[.}.}. X.X(       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    O X :.P.P.P.P.I.~.~.~.^.(.(.(.~.~.P.P.P.P.P.I.I.I.I.P.I.I.P.I.~.~.^.^.~.~./.R.U.R.R.R.H.H.R.H.H.D.H.H.H.R.I.~._.'._.{.$X{. X}.|.|.|.}.[.].).(.(.).(.(.^.^.~.~.I.I.P.I.(.].].).).).{.#X:XSXIXe     UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     471"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      g y.H.F.D.F.J.J.J.K.P.P.D.Z.Z.S.S.S.D.D.F.L.F.J.J.J.J.J.K.K.J.K.K.J.K.K.K.K.K.P.P.P.P.I.~.~.^._.).[.[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.}.}.}.}.}.[.[.[.[.}.}.|. X~       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      O Q P.P.P.I.I.~.^.^.^.(.).(.^.^.I.P.P.P.P.P.I.P.I.I.I.I.I.I.~.^.(.(.).).].].|.}.[.}.{.[.].[.{.}.}.}.|.}.|.|.|.|.|.|.|.|.|.}.}.}.[.[.].).(.).(.(.^.^.^.~.~.^.^.(.).[.[.].].].].{.#X;XZXd X   UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     472"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      i y.A.D.F.J.J.J.K.K.P.I.P.L.L.D.D.R.D.F.F.L.J.J.J.J.J.K.J.K.K.K.K.K.P.P.P.I.~.~.^.^.(.(.).).].].[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.[.}.[.}.}.}.[.[.[.[.[.{.}. X~         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        ~ P.I.P.I.~.~.~.^.^.(.(.(._.).(.^.I.P.I.P.P.P.I.I.I.~.~.~.^.(.(.(.).].].[.}.|.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.[.[.].).).(.(.(.^.^.(.^.(.).].[.[.[.].).].].[.{.:X%Xe       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     473"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      y 3.D.F.F.F.J.K.K.K.I.~.I.I.I.L.R.F.F.F.L.J.J.J.J.J.J.J.K.K.K.P.P.I.I.I.~.^.^.(.(._.).).[.[.[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.[.[.}.[.}.[.[.[.}.[.}.|.$X~ X       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        ~ P.I.I.~.~.^.~.~.^.^.(.).].].].).(.^.~.I.I.U.I.I.~.~.^.^.^.(.(.)._.].[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.].].].).).(.(.(.(.).).].[.[.[.}.[.].].].].].|.#X%X>       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     474"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      % ^ F.F.J.J.J.J.K.K.P.I.I.~.~.I.P.K.K.J.L.J.J.J.J.J.J.K.K.L.K.P.I.I.I.~.^.^.^.(.).).].].[.[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.[.[.[.[.[.[.[.].[.[.[.[.|.}.$Xu X       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      . E R.~.~.~.^.~.~.~.~.(.(.(.).[.[.[.].].(.^.^.~.~.~.I.~.^.^.(.(._.].].].[.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.[.[.[.].).).).).).].[.[.[.[.[.].].).].].[.]. X.Xy.@       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     475"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        E Z.F.F.J.J.K.K.K.P.I.~.~.^.^.^.^.I.P.P.P.K.K.K.L.K.P.P.K.P.I.P.I.~.^.~.^.(.(.(._.).].[.[.[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.}.[.[.[.[.[.[.[.[.[.].].[.[.V.=         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    O O u A.~.I.I.~.~.~.^.^.^.(.(.).].[.[.[.}.}.[.{.).(.^.^.^.(.(.).).].[.[.}.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.[.[.].].].].].].[.[.[.[.[.[.].].].].].].[.H.(       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     476"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      O = 4.F.F.F.J.K.K.K.P.I.~.~.^.^.(.(.^.^.^.~.I.I.P.P.P.P.P.P.P.I.I.I.~.^.^.(.(.)._.].).].[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.[.[.[.[.[.].[.].[.[.[._.[._.^ O       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        * :.R.~.I.~.~.^.~.^.(.^.).].].[.[.|.|.|.|.|.}.}.].].].).).).].[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.[.[.[.[.[.[.[.[.[.].].].].].[.].].[.].V.>       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     477"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        o -.F.J.J.K.K.K.I.I.I.I.^.^.^.(.(.(.(.(.(.(.^.^.^.~.^.~.~.~.~.~.~.^.(.(.(.).].].[.[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.[.[.[.[.[.].[.].[.[.}.}.}.H.Z         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    X   E C.~.^.^.~.~.^.^.(.(.).].[.}.}.|.|.|.|.|.|.|.|.}.[.}.[.}.}.}.}.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.}.[.[.[.[.[.[.[.].].].[.].].].].].H.^ %       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     478"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX    X   A p.J.K.K.P.P.I.I.I.I.~.^.^.^.(.(.).].].[.{.[.[.[.[.[.].].].].].].].[.[.}.}.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.{.}.[.[.[.[.[.[.[.[.].[.}._.^ =         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        % 6.R.~.~.~.^.(.(.).(.).[.[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.}.[.[.[.[.[.[.].].].[.].[.].].].].[.V.y         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     479"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        o Q A.K.K.L.K.P.I.I.I.~.^.~.^.^.(._.].}.}.}.|.}.|.|.|.|.|.|.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.}.[.[.{.].[.[.].[.].[._.V.9           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        O u 6.~.^.^.^.^.(.).].].[.}.}.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.}.[.[.[.[.[.[.].].[.].].].].].[.].H.~           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     480"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      X 9 ~ D.L.L.K.I.I.~.~.~.^.~.^.^.).).].[.[.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.}.}.[.[.].].].}.).V.Z           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX            E B.~.I.^.(.].].[.}.}.}.}.}.|.|.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.}.[.[.].].].[.[.].].[.[.].).(.].H.^ =         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     481"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        O u 6.D.P.~.^.^.^.~.~.~.^.(.(.).].[.[.}.}.}.}.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.[.}.}.|.|.}.].V.Z             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX          X E A.(.].}.}.}.}.}.}.|.|.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.|.}.}.[.[.].].[.].].].].[.}.}.[.).$X3.y           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     482"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        o Z 3.H.I.~.I.I.~.~.^.(.(.).].{.].}.[.}.}.|.}.|.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.].].}.}._.V.E =           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX          9 E V._.[.}.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.[.].[.[.].[.[.[.].].].}.}.$X^ u           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     483"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX          O 9 A 3.D.I.~.~.~.^.^._.).].[.[.}.}.}.}.}.}.}.|.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}._.V.W y             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX          o u W V.$X|.|.|.|.|.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.[.[.[.].].[.].[.|.[.[.$X3.E 9           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     484"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX        O   o Z ^ B.H.R.U.~._.[.[.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.{.}.$XV.3.Z o X           UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX              % Z 3.V.$X{.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.}.}.[.].{._.$XV.3.Z           O UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     485"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX              * y E 3.H.U.(.].|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.$XV.^ u * *             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX      X   X * * y E 3.$X{.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.]._.H.3.~ y =   X         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     486"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX              X = u E ^ V.H._.}.}.}.}.}.|.|.}.}.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.$X$XV.^ E 9     O             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX                . y Z ~ ^ V.$X$X|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.}.].$XV.^ ~ Z 9                 UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     487"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX                . o 9 Z E ^ ^ 3.^ 3.V.V.V.V.V.V.V.V.V.V.V.V.3.^ V.^ E E u t * * *     X         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX                * * o 9 y E E ^ ^ ^ V.V.V.V.V.V.V.V.V.V.V.V.V.V.^ 3.^ E E u 9 o X               UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     488"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX            X           * X   % = % t = = 9 = = * X         *           X X         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX          X           *         o * * = y = = t o o o X X X                         UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     489"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX                  X             X           O       X X             UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX              X X                     X   X                   X       UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     490"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX                                            UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX                                        UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     491"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     492"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     493"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     494"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     495"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     496"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     497"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     498"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     499"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     500"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     501"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     502"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     503"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     504"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     505"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     506"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     507"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     508"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     509"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     510"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     511"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     512"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     513"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     514"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     515"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     516"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX",
     517"UXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUXUX"
     518};
  • dists/scummvm.rc

    diff --git a/dists/pegasus/scummpegasus.zip b/dists/pegasus/scummpegasus.zip
    new file mode 100644
    index 0000000..78a790e
    Binary files /dev/null and b/dists/pegasus/scummpegasus.zip differ
    diff --git a/dists/scummvm.rc b/dists/scummvm.rc
    index f0609c1..1a9796e 100644
    a b  
    99#define IDI_COUNT 1002
    1010#define ID_GDF_XML __GDF_XML
    1111
    12 IDI_ICON               ICON    DISCARDABLE     "icons/scummvm.ico"
     12IDI_ICON               ICON    DISCARDABLE     "dists/pegasus/pegasus.ico"
    1313IDI_COUNT              ICON    DISCARDABLE     "icons/count.ico"
    1414
    1515ID_GDF_XML             DATA    "dists/win32/scummvm.gdf.xml"
    1616
    1717scummclassic.zip       FILE    "gui/themes/scummclassic.zip"
    18 scummmodern.zip        FILE    "gui/themes/scummmodern.zip"
     18scummpegasus.zip        FILE    "dists/pegasus/scummpegasus.zip"
    1919#ifdef USE_TRANSLATION
    2020translations.dat       FILE    "gui/themes/translations.dat"
    2121#endif
  • engines/pegasus/ai/ai_action.cpp

    diff --git a/engines/pegasus/ai/ai_action.cpp b/engines/pegasus/ai/ai_action.cpp
    index 38d6390..6f24647 100644
    a b AIPlayMessageAction::AIPlayMessageAction(const Common::String &movieName, bool k  
    4545}
    4646
    4747void AIPlayMessageAction::performAIAction(AIRule *) {
    48         if (g_AIArea) {
     48        if (g_AIArea && g_AIArea->isChattyAI()) {
    4949                g_AIArea->checkMiddleArea();
    5050                g_AIArea->playAIMovie(kRightAreaSignature, _movieName, _keepLastFrame, _interruptionFilter);
    5151        }
  • engines/pegasus/ai/ai_area.cpp

    diff --git a/engines/pegasus/ai/ai_area.cpp b/engines/pegasus/ai/ai_area.cpp
    index 5ac8af8..c6aeda8 100644
    a b  
    2929#include "pegasus/pegasus.h"
    3030#include "pegasus/ai/ai_area.h"
    3131#include "pegasus/items/biochips/aichip.h"
     32#include "pegasus/items/biochips/arthurchip.h"
    3233#include "pegasus/items/biochips/biochipitem.h"
    3334#include "pegasus/items/biochips/opticalchip.h"
    3435#include "pegasus/items/biochips/pegasuschip.h"
    AIArea::AIArea(InputHandler *nextHandler) : InputHandler(nextHandler), _leftArea  
    5051        _middleBiochipTime = 0xffffffff;
    5152        _rightBiochipTime = 0xffffffff;
    5253        _lockCount = 0;
     54        _chattyAI = true;
     55        ((PegasusEngine *)g_engine)->requestToggle(false);
    5356        startIdling();
    5457}
    5558
    void AIArea::activateHotspots() {  
    452455                        case kOpticalBiochip:
    453456                                ((OpticalChip *)currentBiochip)->activateOpticalHotspots();
    454457                                break;
     458                        case kArthurBiochip:
     459                                if (vm->isDVD())
     460                                        ((ArthurChip *)currentBiochip)->activateArthurHotspots();
     461                                break;
    455462                        }
    456463        } else if (_middleAreaOwner == kInventorySignature) {
    457464                InventoryItem *currentItem = ((PegasusEngine *)g_engine)->getCurrentInventoryItem();
    void AIArea::clickInHotspot(const Input &input, const Hotspot *hotspot) {  
    490497                                        handled = true;
    491498                                }
    492499                                break;
     500                        case kArthurBiochip:
     501                                if (vm->isDVD() && (hotspot->getHotspotFlags() & kArthurBiochipSpotFlag) != 0) {
     502                                        ((ArthurChip *)currentBiochip)->clickInArthurHotspot(hotspot->getObjectID());
     503                                        handled = true;
     504                                }
     505                                break;
    493506                        }
    494507                }
    495508        } else if (_middleAreaOwner == kInventorySignature) {
    void AIArea::forceAIUnlocked() {  
    533546        }
    534547}
    535548
     549void AIArea::setChattyAI(bool flag) {
     550        _chattyAI = flag;
     551
     552        if (g_arthurChip)
     553                g_arthurChip->setUpArthurChip();
     554
     555        if (flag) {
     556                playAIMovie(kRightAreaSignature, "Images/AI/Globals/XGLOB01", false, kHintInterruption);
     557        } else {
     558                playAIMovie(kRightAreaSignature, "Images/AI/Globals/XGLOB00", false, kHintInterruption);
     559                if (g_arthurChip)
     560                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB29", kArthurDisabledAI);
     561        }
     562}
     563
    536564void AIArea::checkRules() {
    537565        if (_lockCount == 0 && ((PegasusEngine *)g_engine)->playerAlive())
    538566                for (AIRuleList::iterator it = _AIRules.begin(); it != _AIRules.end(); it++)
  • engines/pegasus/ai/ai_area.h

    diff --git a/engines/pegasus/ai/ai_area.h b/engines/pegasus/ai/ai_area.h
    index 806e6ef..5541eca 100644
    a b public:  
    130130        void unlockAI();
    131131        void forceAIUnlocked();
    132132
     133        bool isChattyAI() { return _chattyAI; }
     134        void setChattyAI(bool);
     135
    133136        void checkMiddleArea();
    134137        void checkRules();
    135138
    protected:  
    163166        AIRuleList _AIRules;
    164167
    165168        uint _lockCount;
     169
     170        bool _chattyAI;
    166171};
    167172
    168173extern AIArea *g_AIArea;
  • new file engines/pegasus/chase.cpp

    diff --git a/engines/pegasus/chase.cpp b/engines/pegasus/chase.cpp
    new file mode 100644
    index 0000000..43f88d3
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#include "pegasus/chase.h"
     27
     28namespace Pegasus {
     29
     30// Notification constants.
     31
     32static const NotificationFlags kChaseNotificationFlags = kChaseEnteredBranchZone |
     33                                                                                                                        kChaseExitedBranchZone |
     34                                                                                                                        kChaseFinished;
     35
     36ChaseInteraction::ChaseInteraction(const InteractionID interactionID, Neighborhood *handler,
     37        const NotificationID notificationID, NotificationManager *manager) : GameInteraction(interactionID, handler),
     38        _chaseNotification(notificationID, manager), _steerPict(kNoDisplayElement), _directionNeeded(false),
     39        _turnDirection(kNoTurn) {
     40
     41        // HACK HACK HACK HACK HACK
     42        // TRIPLE SUPER ULTRA HACK
     43        // This avoids a nasty optimization bug I have been unable to track down
     44        // after days and days of searching. Let's just ship the game already.
     45        setNextHandler(0);
     46
     47        _neighborhoodNotification = handler->getNeighborhoodNotification();
     48}
     49
     50void ChaseInteraction::openInteraction() {
     51        _steerPict.initFromPICTFile("Images/Interface/steer.pict", true);
     52
     53        _chaseNotification.notifyMe(this, kChaseNotificationFlags, kChaseNotificationFlags);
     54
     55        _neighborhoodNotification->notifyMe(this, kDelayCompletedFlag | kSpotSoundCompletedFlag,
     56                                                                                kDelayCompletedFlag | kSpotSoundCompletedFlag);
     57}
     58
     59void ChaseInteraction::closeInteraction() {
     60        _steerPict.hide();
     61        _steerPict.deallocateSurface();
     62
     63        _chaseNotification.cancelNotification(this);
     64
     65        _neighborhoodNotification->cancelNotification(this);
     66}
     67
     68void ChaseInteraction::receiveNotification(Notification *notification, const NotificationFlags flags) {
     69        if (notification == &_chaseNotification)
     70                switch (flags) {
     71                case kChaseEnteredBranchZone:
     72                        _directionNeeded = true;
     73                        showControlsHint();
     74                        setUpBranch();
     75                        break;
     76                case kChaseExitedBranchZone:
     77                        switch (_turnDirection) {
     78                        case kTurnLeft:
     79                                branchLeft();
     80                                break;
     81                        case kTurnRight:
     82                                branchRight();
     83                                break;
     84                        case kNoTurn:
     85                                dontBranch();
     86                                break;
     87                        default:
     88                                break;
     89                        }
     90                        hideControlsHint();
     91                        _turnDirection = kNoTurn;
     92                        _directionNeeded = false;
     93                        break;
     94                case kChaseFinished:
     95                        _owner->requestDeleteCurrentInteraction();
     96                        break;
     97                default:
     98                        break;
     99                }
     100}
     101
     102void ChaseInteraction::handleInput(const Input &input, const Hotspot *cursorSpot) {
     103        if (input.anyDirectionInput()) {
     104                if (_directionNeeded) {
     105                        if (input.leftButtonAnyDown())
     106                                _turnDirection = kTurnLeft;
     107                        else if (input.rightButtonAnyDown())
     108                                _turnDirection = kTurnRight;
     109                }
     110        } else {
     111                this->InputHandler::handleInput(input, cursorSpot);
     112        }
     113}
     114
     115void ChaseInteraction::showControlsHint() {
     116        _steerPict.show();
     117}
     118
     119void ChaseInteraction::hideControlsHint() {
     120        _steerPict.hide();
     121}
     122
     123} // End of namespace Pegasus
  • new file engines/pegasus/chase.h

    diff --git a/engines/pegasus/chase.h b/engines/pegasus/chase.h
    new file mode 100644
    index 0000000..1e9881d
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#ifndef PEGASUS_CHASE_H
     27#define PEGASUS_CHASE_H
     28
     29#include "pegasus/hotspot.h"
     30#include "pegasus/interaction.h"
     31#include "pegasus/notification.h"
     32#include "pegasus/neighborhood/neighborhood.h"
     33
     34namespace Pegasus {
     35 
     36// Notification constants.
     37
     38static const NotificationFlags kChaseEnteredBranchZone = 1;
     39static const NotificationFlags kChaseExitedBranchZone = kChaseEnteredBranchZone << 1;
     40static const NotificationFlags kChaseFinished = kChaseExitedBranchZone << 1;
     41
     42// Time to choose a direction.
     43
     44static const TimeValue kDecisionTime = 600 * 2;
     45
     46class ChaseInteraction : public GameInteraction, public NotificationReceiver {
     47public:
     48        ChaseInteraction(const InteractionID, Neighborhood *, NotificationID, NotificationManager *);
     49        virtual ~ChaseInteraction() {}
     50
     51        virtual void handleInput(const Input &, const Hotspot *);
     52
     53protected:
     54
     55        virtual void openInteraction();
     56        virtual void initInteraction() {}
     57        virtual void closeInteraction();
     58
     59        virtual void receiveNotification(Notification *, const NotificationFlags);
     60
     61        virtual void setUpBranch() {}
     62        virtual void branchLeft() {}
     63        virtual void branchRight() {}
     64        virtual void dontBranch() {}
     65
     66        virtual void showControlsHint();
     67        virtual void hideControlsHint();
     68
     69        Notification _chaseNotification;
     70
     71        Notification *_neighborhoodNotification;
     72
     73        Picture _steerPict;
     74
     75private:
     76
     77        bool _directionNeeded;
     78        TurnDirection _turnDirection;
     79};
     80
     81} // End of namespace Pegasus
     82
     83#endif
  • engines/pegasus/constants.h

    diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h
    index f81d219..76fabe8 100644
    a b static const NotificationID kNoradPressureNotificationID = kNoradFillingStationN  
    379379static const NotificationID kNoradUtilityNotificationID = kNoradPressureNotificationID + 1;
    380380static const NotificationID kNoradElevatorNotificationID = kNoradUtilityNotificationID + 1;
    381381static const NotificationID kNoradSubPlatformNotificationID = kNoradElevatorNotificationID + 1;
    382 static const NotificationID kSubControlNotificationID = kNoradSubPlatformNotificationID + 1;
     382static const NotificationID kNoradSubChaseNotificationID = kNoradSubPlatformNotificationID + 1;
     383static const NotificationID kSubControlNotificationID = kNoradSubChaseNotificationID + 1;
    383384static const NotificationID kNoradGreenBallNotificationID = kSubControlNotificationID + 1;
    384385static const NotificationID kNoradGlobeNotificationID = kNoradGreenBallNotificationID + 1;
    385386static const NotificationID kCaldoriaVidPhoneNotificationID = kNoradGlobeNotificationID + 1;
    386387static const NotificationID kCaldoriaMessagesNotificationID = kCaldoriaVidPhoneNotificationID + 1;
    387388static const NotificationID kCaldoriaBombTimerNotificationID = kCaldoriaMessagesNotificationID + 1;
     389static const NotificationID kMarsTunnelPodNotificationID = kCaldoriaBombTimerNotificationID + 1;
     390static const NotificationID kMarsCanyonChaseNotificationID = kMarsTunnelPodNotificationID + 1;
    388391
    389392// Sent to the shell by fShellNotification.
    390393static const NotificationFlags kGameStartingFlag = 1;
    static const HotSpotID kAISolveSpotID = kAIHint3SpotID + 1;  
    463466static const HotSpotID kAIBriefingSpotID = kAISolveSpotID + 1;
    464467static const HotSpotID kAIScanSpotID = kAIBriefingSpotID + 1;
    465468
    466 static const HotSpotID kPegasusRecallSpotID = kAIScanSpotID + 1;
     469static const HotSpotID kArthurWisdomSpotID = kAIScanSpotID + 1;
     470static const HotSpotID kChattyArthurSpotID = kArthurWisdomSpotID + 1;
     471static const HotSpotID kChattyAISpotID = kChattyArthurSpotID + 1;
     472static const HotSpotID kArthurHeadSpotID = kChattyAISpotID + 1;
     473
     474static const HotSpotID kPegasusRecallSpotID = kArthurHeadSpotID + 1;
    467475
    468476static const HotSpotID kAriesSpotID = kPegasusRecallSpotID + 1;
    469477static const HotSpotID kMercurySpotID = kAriesSpotID + 1;
    static const HotSpotFlags kInfoReturnSpotFlag = kDropBiochipSpotFlag << 1;  
    501509// Biochip and inventory hot spot flags...
    502510
    503511static const HotSpotFlags kAIBiochipSpotFlag = kInfoReturnSpotFlag << 1;
    504 static const HotSpotFlags kPegasusBiochipSpotFlag = kAIBiochipSpotFlag << 1;
     512static const HotSpotFlags kArthurBiochipSpotFlag = kAIBiochipSpotFlag << 1;
     513static const HotSpotFlags kPegasusBiochipSpotFlag = kArthurBiochipSpotFlag << 1;
    505514static const HotSpotFlags kOpticalBiochipSpotFlag = kPegasusBiochipSpotFlag << 1;
    506515static const HotSpotFlags kAirMaskSpotFlag = kOpticalBiochipSpotFlag << 1;
    507516
    static const HotSpotFlags kJMPClickingSpotFlags = kClickSpotFlag |  
    510519                                                                                        kOpenDoorSpotFlag |
    511520                                                                                        kInfoReturnSpotFlag |
    512521                                                                                        kAIBiochipSpotFlag |
     522                                                                                        kArthurBiochipSpotFlag |
    513523                                                                                        kPegasusBiochipSpotFlag |
    514524                                                                                        kOpticalBiochipSpotFlag |
    515525                                                                                        kAirMaskSpotFlag;
    enum {  
    655665        // Mars
    656666        kDeathWrongShuttleLock,
    657667        kDeathArrestedInMars,
     668        kDeathCollidedWithPod,
    658669        kDeathRunOverByPod,
    659670        kDeathDidntGetOutOfWay,
    660671        kDeathReactorBurn,
  • engines/pegasus/cursor.cpp

    diff --git a/engines/pegasus/cursor.cpp b/engines/pegasus/cursor.cpp
    index ad0d2c2..f0976e2 100644
    a b void Cursor::loadCursorImage(CursorInfo &cursorInfo) {  
    160160
    161161        cursorInfo.surface = new Graphics::Surface();
    162162
     163        // The CD version uses (only) lower color cicn images for its cursors
    163164        Common::SeekableReadStream *cicnStream = vm->_resFork->getResource(MKTAG('c', 'i', 'c', 'n'), cursorInfo.tag);
    164165
    165166        if (!cicnStream)
  • engines/pegasus/detection.cpp

    diff --git a/engines/pegasus/detection.cpp b/engines/pegasus/detection.cpp
    old mode 100644
    new mode 100755
    index 721c382..ac234c2
    a b enum {  
    4141
    4242bool PegasusEngine::hasFeature(EngineFeature f) const {
    4343        return
    44                 (f == kSupportsRTL)
    45                 || (f == kSupportsLoadingDuringRuntime)
     44                /* (f == kSupportsRTL)
     45                || */ (f == kSupportsLoadingDuringRuntime)
    4646                || (f == kSupportsSavingDuringRuntime);
    4747}
    4848
    bool PegasusEngine::isWindows() const {  
    6666        return _gameDescription->desc.platform == Common::kPlatformWindows;
    6767}
    6868
     69bool PegasusEngine::isLinux() const {
     70        return _gameDescription->desc.platform == Common::kPlatformLinux;
     71}
     72
    6973} // End of namespace Pegasus
    7074
    7175static const PlainGameDescriptor pegasusGames[] = {
    static const PegasusGameDescription gameDescriptions[] = {  
    9296        {
    9397                {
    9498                        "pegasus",
     99                        "DVD",
     100                        AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2075337),
     101                        Common::EN_ANY,
     102                        Common::kPlatformMacintosh,
     103                        ADGF_MACRESFORK|GF_DVD,
     104                        GUIO0()
     105                },
     106        },
     107       
     108        {
     109                {       "pegasus",
     110                        "DVD",
     111                        AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2075337),
     112                        Common::EN_ANY,
     113                        Common::kPlatformWindows,
     114                        ADGF_MACRESFORK|GF_DVD,
     115                        GUIO0()
     116                },
     117        },
     118
     119        {
     120                {
     121                        "pegasus",
     122                        "DVD",
     123                        AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2075337),
     124                        Common::EN_ANY,
     125                        Common::kPlatformWindows,
     126                        ADGF_MACRESFORK|GF_DVD,
     127                        GUIO0()
     128                },
     129        },
     130
     131        {
     132                {
     133                        "pegasus",
     134                        "DVD",
     135                        AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2075337),
     136                        Common::EN_ANY,
     137                        Common::kPlatformLinux,
     138                        ADGF_MACRESFORK|GF_DVD,
     139                        GUIO0()
     140                },
     141        },
     142
     143        {
     144                {
     145                        "pegasus",
    95146                        "Demo",
    96147                        AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 360129),
    97148                        Common::EN_ANY,
    static const PegasusGameDescription gameDescriptions[] = {  
    113164                },
    114165        },
    115166
    116                 {
     167        {
    117168                {
    118169                        "pegasus",
    119170                        "DVD Demo",
  • engines/pegasus/graphics.cpp

    diff --git a/engines/pegasus/graphics.cpp b/engines/pegasus/graphics.cpp
    index 5475108..fc22bb5 100644
    a b  
    2323 *
    2424 */
    2525
     26#include "common/config-manager.h"
    2627#include "common/events.h"
    2728#include "common/file.h"
    2829#include "common/textconsole.h"
  • engines/pegasus/input.cpp

    diff --git a/engines/pegasus/input.cpp b/engines/pegasus/input.cpp
    index b74e4a4..6ad9905 100644
    a b InputDeviceManager::InputDeviceManager() {  
    6464        _keyMap[Common::KEYCODE_RALT] = false;
    6565        _keyMap[Common::KEYCODE_e] = false;
    6666        _keyMap[Common::KEYCODE_KP_ENTER] = false;
     67        _keyMap[Common::KEYCODE_a] = false;
    6768
    6869        g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 2, false);
    6970        _lastRawBits = kAllUpBits;
    7071        _consoleRequested = false;
     72        _AKeyWasDown = false;
    7173}
    7274
    7375InputDeviceManager::~InputDeviceManager() {
    InputDeviceManager::~InputDeviceManager() {  
    7577}
    7678
    7779void InputDeviceManager::getInput(Input &input, const InputBits filter) {
    78         // Poll for events, but ignore them!
    79         // We'll pick them up in notifyEvent()
     80        // Poll for events, but ignore most of them!
     81        // We'll pick the rest up in notifyEvent()
    8082        // We do that so that any pollEvent() call can update the variables
    8183        // (ie. if one uses enter to access the restore menu, we never receive
    8284        // the key up event, which leads to bad things)
    8385        // This is to closely emulate what the GetKeys() function did on Mac OS
    84         Common::Event event;
    85         while (g_system->getEventManager()->pollEvent(event))
    86                 ;
    8786
    88         // Now create the bitfield
    8987        InputBits currentBits = 0;
    9088
     89        Common::Event event;
     90        while (g_system->getEventManager()->pollEvent(event)) {
     91                switch (event.type) {
     92                case Common::EVENT_WHEELUP:
     93                        currentBits |= (kRawButtonDown << kUpButtonShift);
     94                        break;
     95                case Common::EVENT_WHEELDOWN:
     96                        currentBits |= (kRawButtonDown << kDownButtonShift);
     97                        break;
     98                default:
     99                        break;
     100                }
     101        }
     102
     103        // Now fill in the rest of the bitfield
     104
    91105        if (_keyMap[Common::KEYCODE_UP] || _keyMap[Common::KEYCODE_KP8])
    92106                currentBits |= (kRawButtonDown << kUpButtonShift);
    93107
    void InputDeviceManager::getInput(Input &input, const InputBits filter) {  
    121135        if (_keyMap[Common::KEYCODE_BACKSPACE] || _keyMap[Common::KEYCODE_KP_MULTIPLY])
    122136                currentBits |= (kRawButtonDown << kRightFireButtonShift);
    123137
     138        if (((PegasusEngine *)g_engine)->isDVD()) {
     139                if (_keyMap[Common::KEYCODE_a] && (_keyMap[Common::KEYCODE_LALT] || _keyMap[Common::KEYCODE_RALT]) && !_AKeyWasDown) {
     140                        ((PegasusEngine *)g_engine)->requestToggle();
     141                        _AKeyWasDown = true;
     142                } else if (!_keyMap[Common::KEYCODE_a])
     143                        _AKeyWasDown = false;
     144        }
     145
    124146        // Update mouse button state
    125147        // Note that we don't use EVENT_LBUTTONUP/EVENT_LBUTTONDOWN because
    126148        // they do not show if the button is being held down. We're treating
  • engines/pegasus/input.h

    diff --git a/engines/pegasus/input.h b/engines/pegasus/input.h
    index 3e938fa..e2c814a 100644
    a b protected:  
    5757        Common::HashMap<uint, bool> _keyMap;
    5858        InputBits _lastRawBits;
    5959        bool _consoleRequested;
     60        bool _AKeyWasDown;
    6061};
    6162
    6263enum {
    enum {  
    278279};
    279280
    280281static const InputBits kHintInterruption = kFilterAllInputNoAuto;
    281 static const InputBits kWarningInterruption = kFilterNoInput;
     282static const InputBits kWarningInterruption = kFilterAllInputNoAuto;
    282283static const InputBits kOpticalInterruption = kFilterAllInputNoAuto;
    283284
    284285/*
    public:  
    481482
    482483        static bool isRaiseInventoryInput(const Input &input) { return input.leftFireButtonDown(); }
    483484        static bool isRaiseBiochipsInput(const Input &input) { return input.rightFireButtonDown(); }
    484         static InputBits getItemPanelsInputFilter() { return kFilterLeftFireButton | kFilterRightFireButton; }
     485        static InputBits getItemPanelsInputFilter() { return kFilterFourButton | kFilterLeftFireButton | kFilterRightFireButton; }
    485486
    486487        static bool isToggleAIMiddleInput(const Input &input) { return input.threeButtonDown(); }
    487488
  • engines/pegasus/interface.cpp

    diff --git a/engines/pegasus/interface.cpp b/engines/pegasus/interface.cpp
    index f2429bf..5543672 100644
    a b void Interface::raiseInventoryDrawer(const bool doCallBacks) {  
    398398
    399399        if (((PegasusEngine *)g_engine)->isDVD()) {
    400400                _inventoryCloseSound.stopSound();
     401                _inventoryOpenSound.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
    401402                _inventoryOpenSound.playSound();
    402403        }
    403404}
    void Interface::playEndMessage() {  
    412413
    413414void Interface::raiseInventoryDrawerForMessage() {
    414415        _inventoryPanel.disableLooping();
     416
     417        // The DVD version has a different image for the inventory
     418        // for the end message.
     419        if (((PegasusEngine *)g_engine)->isDVD()) {
     420                _inventoryPanel.setCommPicture();
     421                _inventoryPanel.throwAwayInventoryImage();
     422                _inventoryPanel.initInventoryImage(&_inventoryPush);
     423        }
     424
    415425        raiseInventoryDrawerSync();
    416426}
    417427
    void Interface::lowerInventoryDrawer(const bool doCallBacks) {  
    464474
    465475                if (((PegasusEngine *)g_engine)->isDVD()) {
    466476                        _inventoryOpenSound.stopSound();
     477                        _inventoryCloseSound.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
    467478                        _inventoryCloseSound.playSound();
    468479                }
    469480        }
    void Interface::raiseBiochipDrawer(const bool doCallBacks) {  
    510521
    511522        if (((PegasusEngine *)g_engine)->isDVD()) {
    512523                _biochipCloseSound.stopSound();
     524                _biochipOpenSound.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
    513525                _biochipOpenSound.playSound();
    514526        }
    515527}
  • new file engines/pegasus/items/biochips/arthurchip.cpp

    diff --git a/engines/pegasus/items/biochips/arthurchip.cpp b/engines/pegasus/items/biochips/arthurchip.cpp
    new file mode 100644
    index 0000000..931f1de
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-1997 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#include "pegasus/pegasus.h"
     27#include "pegasus/ai/ai_area.h"
     28#include "pegasus/items/biochips/arthurchip.h"
     29
     30namespace Common {
     31DECLARE_SINGLETON(Pegasus::ArthurManager);
     32}
     33
     34namespace Pegasus {
     35
     36static const char *kArthurWisdomMovies[] = {
     37        "Images/AI/Globals/XGLOBA01",
     38        "Images/AI/Globals/XGLOBA03",
     39        "Images/AI/Globals/XGLOBA06",
     40        "Images/AI/Globals/XGLOBA07",
     41        "Images/AI/Globals/XGLOBA09",
     42        "Images/AI/Globals/XGLOBA17",
     43        "Images/AI/Globals/XGLOBA18",
     44        "Images/AI/Globals/XGLOBA25",
     45        "Images/AI/Globals/XGLOBA26",
     46        "Images/AI/Globals/XGLOBA27",
     47        "Images/AI/Globals/XGLOBA28",
     48        "Images/AI/Globals/XGLOBA30",
     49        "Images/AI/Globals/XGLOBA34",
     50        "Images/AI/Globals/XGLOBA35",
     51        "Images/AI/Globals/XGLOBA43",
     52        "Images/AI/Globals/XGLOBA50",
     53        "Images/AI/Globals/XGLOBA56",
     54        "Images/AI/Globals/XGLOBA59",
     55        "Images/AI/Globals/XGLOBA63",
     56        "Images/AI/Globals/XGLOBB10",
     57        "Images/AI/Globals/XGLOBB11",
     58        "Images/AI/Globals/XGLOBB12",
     59        "Images/AI/Globals/XGLOBB13",
     60        "Images/AI/Globals/XGLOBB14",
     61        "Images/AI/Globals/XGLOBB15",
     62        "Images/AI/Globals/XGLOBB16",
     63        "Images/AI/Globals/XGLOBB17",
     64        "Images/AI/Globals/XGLOBB18",
     65        "Images/AI/Globals/XGLOBB19",
     66        "Images/AI/Globals/XGLOBB20",
     67        "Images/AI/Globals/XGLOBB21",
     68        "Images/AI/Globals/XGLOBB22",
     69        "Images/AI/Globals/XGLOBB23",
     70        "Images/AI/Globals/XGLOBB24",
     71        "Images/AI/Globals/XGLOBB25",
     72        "Images/AI/Globals/XGLOBB26",
     73        "Images/AI/Globals/XGLOBB27",
     74        "Images/AI/Globals/XGLOBB28",
     75        "Images/AI/Globals/XGLOBB29",
     76        "Images/AI/Globals/XGLOBB30",
     77        "Images/AI/Globals/XGLOBB31",
     78        "Images/AI/Globals/XGLOBB32",
     79        "Images/AI/Globals/XGLOBB33",
     80        "Images/AI/Globals/XGLOBB34",
     81        "Images/AI/Globals/XGLOBB35",
     82        "Images/AI/Globals/XGLOBB36",
     83        "Images/AI/Globals/XGLOBB37",
     84        "Images/AI/Globals/XGLOBB38",
     85        "Images/AI/Globals/XGLOBB39",
     86        "Images/AI/Globals/XGLOBB43",
     87        "Images/AI/Globals/XGLOBB44",
     88        "Images/AI/Globals/XGLOBA62"
     89};
     90
     91ArthurChip *g_arthurChip = 0;
     92
     93ArthurChip::ArthurChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
     94                BiochipItem(id, neighborhood, room, direction), _arthurWisdomHotspot(kArthurWisdomSpotID),
     95                _chattyArthurHotspot(kChattyArthurSpotID), _chattyAIHotspot(kChattyAISpotID),
     96                _arthurHeadHotspot(kArthurHeadSpotID) {
     97        _chattyArthur = true;
     98        _lastArthurMovie = "";
     99
     100        _arthurWisdomHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 20, kAIMiddleAreaTop + 27, kAIMiddleAreaLeft + 20 + 161, kAIMiddleAreaTop + 27 + 30));
     101        _arthurWisdomHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
     102        g_allHotspots.push_back(&_arthurWisdomHotspot);
     103
     104        _chattyArthurHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 100, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 100 + 20, kAIMiddleAreaTop + 67 + 20));
     105        _chattyArthurHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
     106        g_allHotspots.push_back(&_chattyArthurHotspot);
     107
     108        _chattyAIHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 130, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 130 + 20, kAIMiddleAreaTop + 67 + 20));
     109        _chattyAIHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
     110        g_allHotspots.push_back(&_chattyAIHotspot);
     111
     112        _arthurHeadHotspot.setArea(Common::Rect(kAIRightAreaLeft, kAIRightAreaTop, kAIRightAreaLeft + kAIRightAreaWidth, kAIRightAreaTop + kAIRightAreaHeight));
     113        _arthurHeadHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
     114        g_allHotspots.push_back(&_arthurHeadHotspot);
     115
     116        setItemState(kArthur000);
     117
     118        g_arthurChip = this;
     119}
     120
     121ArthurChip::~ArthurChip() {
     122        g_arthurChip = NULL;
     123
     124        g_allHotspots.removeOneHotspot(kArthurWisdomSpotID);
     125        g_allHotspots.removeOneHotspot(kChattyArthurSpotID);
     126        g_allHotspots.removeOneHotspot(kChattyAISpotID);
     127        g_allHotspots.removeOneHotspot(kArthurHeadSpotID);
     128}
     129
     130void ArthurChip::setChattyArthur(bool flag) {
     131        _chattyArthur = flag;
     132
     133        setUpArthurChip();
     134
     135        if (flag) {
     136                if (((PegasusEngine *)g_engine)->getRandomBit())
     137                        playArthurMovie("Images/AI/Globals/XGLOBAA1");
     138                else
     139                        playArthurMovie("Images/AI/Globals/XGLOBAA2");
     140        } else {
     141                playArthurMovie("Images/AI/Globals/XGLOBAA0");
     142        }
     143}
     144
     145void ArthurChip::select() {
     146        BiochipItem::select();
     147        setUpArthurChip();
     148}
     149
     150void ArthurChip::setUpArthurChip() {
     151        ItemState state = getItemState();
     152
     153        if (_chattyArthur) {
     154                if (g_AIArea && g_AIArea->isChattyAI()) {
     155                        if (state != kArthur002)
     156                                setItemState(kArthur000);
     157                } else if (state != kArthur102) {
     158                        setItemState(kArthur100);
     159                }
     160        } else {
     161                if (g_AIArea && g_AIArea->isChattyAI()) {
     162                        if (state != kArthur012)
     163                                setItemState(kArthur010);
     164                } else if (state != kArthur112) {
     165                        setItemState(kArthur110);
     166                }
     167        }
     168}
     169
     170void ArthurChip::activateArthurHotspots() {
     171        _arthurWisdomHotspot.setActive();
     172        _chattyArthurHotspot.setActive();
     173        _chattyAIHotspot.setActive();
     174        _arthurHeadHotspot.setActive();
     175}
     176
     177void ArthurChip::clickInArthurHotspot(HotSpotID id) {
     178        ItemState state, newState;
     179
     180        if (id == kArthurHeadSpotID) {
     181                if (_lastArthurMovie != "")
     182                        playArthurMovie(_lastArthurMovie);
     183                return;
     184        }
     185       
     186        newState = state = getItemState();
     187        switch (state) {
     188        case kArthur000:
     189                switch (id) {
     190                case kArthurWisdomSpotID:
     191                        newState = kArthur002;
     192                        break;
     193                case kChattyArthurSpotID:
     194                        newState = kArthur010;
     195                        break;
     196                case kChattyAISpotID:
     197                        newState = kArthur100;
     198                        break;
     199                }
     200                break;
     201        case kArthur010:
     202                switch (id) {
     203                case kArthurWisdomSpotID:
     204                        newState = kArthur012;
     205                        break;
     206                case kChattyArthurSpotID:
     207                        newState = kArthur000;
     208                        break;
     209                case kChattyAISpotID:
     210                        newState = kArthur110;
     211                        break;
     212                }
     213                break;
     214        case kArthur100:
     215                switch (id) {
     216                case kArthurWisdomSpotID:
     217                        newState = kArthur102;
     218                        break;
     219                case kChattyArthurSpotID:
     220                        newState = kArthur110;
     221                        break;
     222                case kChattyAISpotID:
     223                        newState = kArthur010;
     224                        break;
     225                }
     226                break;
     227        case kArthur110:
     228                switch (id) {
     229                case kArthurWisdomSpotID:
     230                        newState = kArthur112;
     231                        break;
     232                case kChattyArthurSpotID:
     233                        newState = kArthur100;
     234                        break;
     235                case kChattyAISpotID:
     236                        newState = kArthur010;
     237                        break;
     238                }
     239                break;
     240        }
     241        setItemState(newState);
     242        switch (id) {
     243        case kArthurWisdomSpotID:
     244                playArthurMovie(kArthurWisdomMovies[((PegasusEngine *)g_engine)->getRandomNumber((
     245                                                sizeof(kArthurWisdomMovies) / sizeof(const char *)) - 1)]);
     246                break;
     247        case kChattyArthurSpotID:
     248                setChattyArthur(!_chattyArthur);
     249                break;
     250        case kChattyAISpotID:
     251                if (g_AIArea)
     252                        g_AIArea->setChattyAI(!g_AIArea->isChattyAI());
     253                break;
     254        }
     255       
     256        setItemState(state);
     257}
     258
     259void ArthurChip::playArthurMovie(const Common::String &movieName) {
     260        if (g_AIArea) {
     261                g_AIArea->playAIMovie(kRightAreaSignature, movieName, false, kHintInterruption);
     262                if (movieName != "Images/AI/Globals/XGLOB00" &&
     263                        movieName != "Images/AI/Globals/XGLOB01" &&
     264                        movieName != "Images/AI/Globals/XGLOBAA0" &&
     265                        movieName != "Images/AI/Globals/XGLOBAA1" &&
     266                        movieName != "Images/AI/Globals/XGLOBAA2")
     267                        _lastArthurMovie = movieName;
     268        }
     269}
     270
     271bool ArthurChip::playArthurMovieForEvent(const Common::String &movieName, ArthurEvent event) {
     272        if (((PegasusEngine *)g_engine)->isDVD() && ((PegasusEngine *)g_engine)->playerHasItemID(kArthurBiochip) &&
     273                isChattyArthur() && !Arthur._arthurFlags.getFlag(event)) {
     274                Arthur._arthurFlags.setFlag(event, true);
     275                playArthurMovie(movieName);
     276                return true;
     277        } else {
     278                return false;
     279        }
     280}
     281
     282void ArthurManager::resetArthurState() {
     283        bool savedGameFlag = _arthurFlags.getFlag(kArthurLoadedSavedGame);
     284        _arthurFlags.clearAllFlags();
     285        _arthurFlags.setFlag(kArthurLoadedSavedGame, savedGameFlag);
     286}
     287
     288} // End of namespace Pegasus
  • new file engines/pegasus/items/biochips/arthurchip.h

    diff --git a/engines/pegasus/items/biochips/arthurchip.h b/engines/pegasus/items/biochips/arthurchip.h
    new file mode 100644
    index 0000000..4c4a580
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-1997 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#ifndef PEGASUS_ITEMS_BIOCHIPS_ARTHURCHIP_H
     27#define PEGASUS_ITEMS_BIOCHIPS_ARTHURCHIP_H
     28
     29#include "pegasus/hotspot.h"
     30#include "pegasus/util.h"
     31#include "pegasus/items/biochips/biochipitem.h"
     32
     33namespace Pegasus {
     34
     35enum ArthurEvent {
     36        kArthurLoadedSavedGame,
     37        kArthurAttemptedLockedDoor,
     38        kArthurAttemptedLockedDoorAgain,
     39        kArthurDestroyedInventoryItem,
     40        kArthurDisabledAI,
     41
     42        kArthurCaldoriaFinishedJoyride,
     43        kArthurCaldoriaSelectedStickyBuns,
     44        kArthurCaldoriaCreatedCornbread,
     45        kArthurCaldoriaDrankOJ,
     46        kArthurCaldoriaZoomedToLaundry,
     47        kArthurCaldoriaReachedToilet,
     48        kArthurCaldoriaReadPaper,
     49        kArthurCaldoriaChoseAgencyHairStyle,
     50        kArthurCaldoriaSawVacantApartment,
     51        kArthurCaldoriaLookThroughTelescope,
     52        kArthurCaldoriaRoofDoor,
     53        kArthurCaldoriaUsedCardBomb,
     54        kArthurCaldoriaBlownDoor,
     55        kArthurCaldoriaSawVoiceAnalysis,
     56        kArthurCaldoriaStunningSinclair,
     57        kArthurCaldoriaSeeRoofBomb,
     58        kArthurCaldoriaDisarmedNuke,
     59
     60        kArthurTSAEnteredCave,
     61        kArthurTSASawAgent3,
     62        kArthurTSASawBust,
     63        kArthurTSAReachedJunction,
     64        kArthurTSAClickedRobot1,
     65        kArthurTSAClickedRobot2,
     66        kArthurTSAOpenTBPMonitor,
     67        kArthurTSASawJourneymanKey,
     68        kArthurTSASawBiochips,
     69        kArthurTSAUsedPegasus,
     70        kArthurTSAConfinedByBaldwin,
     71        kArthurTSARedirectedRobots,
     72        kArthurTSAUsedTurbolift,
     73        kArthurTSASawFirstOpMemMovie,
     74        kArthurTSAInPegasusNoVideo,
     75        kArthurTSASawBaldwinSayGo,
     76        kArthurTSALeaving,
     77
     78        kArthurGoToPrehistoric,
     79       
     80        kArthurPrehistoricReachedJunction,
     81        kArthurPrehistoricSawBreaker,
     82        kArthurPrehistoricBreakerThrown,
     83        kArthurPrehistoricAtCliffEdge,
     84        kArthurPrehistoricSawEggs,
     85        kArthurPrehistoricZoomedToVault,
     86        kArthurPrehistoricAttemptedBridge,
     87        kArthurPrehistoricExtendedBridge,
     88        kArthurPrehistoricCrossedBridge,
     89        kArthurPrehistoricUnlockedVault,
     90
     91        kArthurMarsReadyForKiosk,
     92        kArthurMarsLookedAtGuards,
     93        kArthurMarsZoomedToKeyCard,
     94        kArthurMarsTurnedOnTransport,
     95        kArthurMarsCantFillMask,
     96        kArthurMarsSawWelcomeVideos,
     97        kArthurMarsRobotThrownPlayerWithMask,
     98        kArthurMarsLeftPodNoCrowBar,
     99        kArthurMarsLookAtEmptyTracks,
     100        kArthurMarsEnteredReactor,
     101        kArthurMarsSawLockedPanel,
     102        kArthurMarsSawLockedPanelNoNitrogen,
     103        kArthurMarsUsedLiquidNitrogen,
     104        kArthurMarsFoundCardBomb,
     105        kArthurMarsSolvedReactorGame,
     106        kArthurMarsDeactivatedCardBomb,
     107        kArthurMarsExitedReactorWithCardBomb,
     108        kArthurMarsInAirlockNoOxygen,
     109        kArthurMarsMazeReachedJunction,
     110        kArthurMarsOxygen50Warning,
     111        kArthurMarsOxygen25Warning,
     112        kArthurMarsOxygen5Warning,
     113        kArthurMarsFoundBuckets,
     114        kArthurMarsApproachedBuckets,
     115        kArthurMarsEnteredGearRoom,
     116        kArthurMarsLookAtGears,
     117        kArthurMarsExitedGearRoom,
     118        kArthurMarsFoundNoShuttlePresent,
     119        kArthurMarsEnteredShuttle,
     120        kArthurMarsFoundDeadRobot,
     121        kArthurMarsRobotHeadOpen,
     122
     123        kArthurWSCRemovedDart,
     124        kArthurWSCPoisonedDuringGame,
     125        kArthurWSCFailedMolecule,
     126        kArthurWSCDesignedAntidote,
     127        kArthurWSCSawAresHologram,
     128        kArthurWSCLookAtMorphExperiment,
     129        kArthurWSCStartMorphExperiment,
     130        kArthurWSCSawMorphExperiment,
     131        kArthurWSCLeftLabNoKeyOrCanisters,
     132        kArthurWSCAtOppositeDoor,
     133        kArthurWSCReadyForMap,
     134        kArthurWSCAttemptedLockedDoor,
     135        kArthurWSCSawSinclairDoor,
     136        kArthurWSCSawSinclairDoorNoKey,
     137        kArthurWSCAttemptedSinclairDoorNoKey,
     138        kArthurWSCZoomedToSnake,
     139        kArthurWSCActivatedComputer,
     140        kArthurWSCZoomedToSinclairMessages,
     141        kArthurWSCPlayedEasterEggMessage,
     142        kArthurWSCGotMachineGun,
     143        kArthurWSCSeenNerd,
     144        kArthurWSCSawBrokenDoor,
     145        kArthurWSCSawBrokenDoorNoCrowBar,
     146        kArthurWSCUsedCrowBar,
     147        kArthurWSCDidPlasmaDodge,
     148        kArthurWSCEnteredAuditorium,
     149        kArthurWSCSawSinclairLecture,
     150        kArthurWSCEnteredPassage,
     151        kArthurWSCInPassage,
     152        kArthurWSCExitedPassage,
     153        kArthurWSCSawCatwalkDoor,
     154        kArthurWSCRobotHeadOpen,
     155
     156        kArthurNoradAtSecurityMonitor,
     157        kArthurNoradSawFillingStation,
     158        kArthurNoradSawIntakeWarning,
     159        kArthurNoradDidntFillCanisters,
     160        kArthurNoradSawUnconsciousOperator,
     161        kArthurNoradAttemptedLockedDoor,
     162        kArthurNoradAttemptedLockedDoorAgain,
     163        kArthurNoradReachedPressureDoor,
     164        kArthurNoradSawSubMessage,
     165        kArthurNoradSawClawMonitor,
     166        kArthurNoradPlayedWithClaw,
     167        kArthurNoradEnteredSub,
     168        kArthurNoradExitedSub,
     169        kArthurNoradApproachedDamagedDoor,
     170        kArthurNoradAtRetScanNoBiochip,
     171        kArthurNoradStartGlobeGame,
     172        kArthurNoradSelectedIncorrectSilo,
     173        kArthurNoradFinishedGlobeGame,
     174        kArthurNoradThreatenedByRobot,
     175        kArthurNoradBeatRobotWithClaw,
     176        kArthurNoradRobotHeadOpen,
     177       
     178        kNumArthurFlags
     179};
     180
     181class ArthurChip : public BiochipItem {
     182public:
     183        ArthurChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
     184        virtual ~ArthurChip();
     185
     186        bool isChattyArthur() { return _chattyArthur; }
     187        void setChattyArthur(bool);
     188
     189        void select();
     190
     191        void setUpArthurChip();
     192        void activateArthurHotspots();
     193        void clickInArthurHotspot(HotSpotID);
     194        void playArthurMovie(const Common::String &);
     195        bool playArthurMovieForEvent(const Common::String &, ArthurEvent event);
     196
     197protected:
     198        Hotspot _arthurWisdomHotspot;
     199        Hotspot _chattyArthurHotspot;
     200        Hotspot _chattyAIHotspot;
     201        Hotspot _arthurHeadHotspot;
     202        bool _chattyArthur;
     203        Common::String _lastArthurMovie;
     204};
     205
     206class ArthurManager : public Common::Singleton<ArthurManager> {
     207public:
     208        ArthurManager() { resetArthurState(); }
     209
     210        void resetArthurState();
     211
     212protected:
     213        friend class Common::Singleton<SingletonBaseType>;
     214        friend class ArthurChip;
     215
     216private:
     217        FlagsArray<byte, kNumArthurFlags> _arthurFlags;
     218};
     219
     220extern ArthurChip *g_arthurChip;
     221
     222} // End of namespace Pegasus
     223
     224#define Arthur (::Pegasus::ArthurManager::instance())
     225
     226#endif
  • engines/pegasus/items/biochips/opticalchip.cpp

    diff --git a/engines/pegasus/items/biochips/opticalchip.cpp b/engines/pegasus/items/biochips/opticalchip.cpp
    index 7b8858e..05121ac 100644
    a b void OpticalChip::playOpMemMovie(HotSpotID id) {  
    127127        Common::String movieName;
    128128        switch (id) {
    129129        case kAriesSpotID:
    130                 movieName = "Images/AI/Globals/OMAI";
     130                // WORKAROUND: The original CD release played the ares video even
     131                // when you destroyed the shuttle. For the DVD release, we have
     132                // some new videos that can be played instead to workaround a plot
     133                // loophole.
     134                if (!((PegasusEngine *)g_engine)->isDVD() || _opticalFlags.getFlag(kOpticalAriesExposed))
     135                        movieName = "Images/AI/Globals/OMAI";
     136                else if (_itemOwnerID == kPlayerID)
     137                        movieName = "Images/AI/Globals/OMN1";
     138                else
     139                        movieName = "Images/AI/Globals/OMN0";
    131140                break;
    132141        case kMercurySpotID:
    133142                movieName = "Images/AI/Globals/OMMI";
  • engines/pegasus/items/inventory/airmask.cpp

    diff --git a/engines/pegasus/items/inventory/airmask.cpp b/engines/pegasus/items/inventory/airmask.cpp
    index c65dd36..26912bb 100644
    a b void AirMask::useIdleTime() {  
    164164
    165165void AirMask::refillAirMask() {
    166166        switch (getItemState()) {
    167                 case kAirMaskEmptyOff:
    168                 case kAirMaskLowOff:
    169                         setItemState(kAirMaskFullOff);
    170                         break;
    171                 case kAirMaskEmptyFilter:
    172                 case kAirMaskLowFilter:
    173                         setItemState(kAirMaskFullFilter);
    174                         break;
    175                 case kAirMaskLowOn:
    176                         setItemState(kAirMaskFullOn);
    177                         break;
     167        case kAirMaskEmptyOff:
     168        case kAirMaskLowOff:
     169                setItemState(kAirMaskFullOff);
     170                break;
     171        case kAirMaskEmptyFilter:
     172        case kAirMaskLowFilter:
     173                setItemState(kAirMaskFullFilter);
     174                break;
     175        case kAirMaskLowOn:
     176                setItemState(kAirMaskFullOn);
     177                break;
    178178        }
    179179
    180180        if (_oxygenTimer.isFuseLit()) {
  • engines/pegasus/items/inventorypicture.cpp

    diff --git a/engines/pegasus/items/inventorypicture.cpp b/engines/pegasus/items/inventorypicture.cpp
    index fc812fa..99b9ad8 100644
    a b void InventoryItemsPicture::deactivateInventoryPicture() {  
    318318        }
    319319}
    320320
     321void InventoryItemsPicture::setCommPicture() {
     322        _pictName = "Images/Items/Inventory/Comm Panel";
     323}
     324
    321325void InventoryItemsPicture::playEndMessage(DisplayElement *pushElement) {
    322326        PegasusEngine *vm = (PegasusEngine *)g_engine;
    323327
    void InventoryItemsPicture::playEndMessage(DisplayElement *pushElement) {  
    326330        _shouldDrawHighlight = false;
    327331        endMessage.shareSurface(this);
    328332        endMessage.initFromMovieFile("Images/Caldoria/A56 Congrats");
     333        endMessage.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
    329334        endMessage.moveMovieBoxTo(kFinalMessageLeft - kInventoryPushLeft, kFinalMessageTop - kInventoryPushTop);
    330335        endMessage.setTriggeredElement(pushElement);
    331336        endMessage.start();
  • engines/pegasus/items/inventorypicture.h

    diff --git a/engines/pegasus/items/inventorypicture.h b/engines/pegasus/items/inventorypicture.h
    index 9eba25b..1c89f50 100644
    a b public:  
    9898
    9999        void disableLooping() { _isLooping = false; }
    100100
     101        void setCommPicture();
    101102        void playEndMessage(DisplayElement *);
    102103
    103104protected:
  • engines/pegasus/items/item.h

    diff --git a/engines/pegasus/items/item.h b/engines/pegasus/items/item.h
    index a1451b2..1b0e7c0 100644
    a b static const ItemID kArgonPickup = 24;  
    118118// Biochips.
    119119
    120120static const ItemID kAIBiochip = 0;
     121static const ItemID kArthurBiochip = 1;
    121122static const ItemID kInterfaceBiochip = 1;
    122123static const ItemID kMapBiochip = 2;
    123124static const ItemID kOpticalBiochip = 3;
    static const ItemState kFlashlightOn = 115;  
    248249static const ItemState kNitrogenEmpty = 116;
    249250static const ItemState kNitrogenFull = 117;
    250251static const ItemState kFullGlass = 118;
     252static const ItemState kArthur000 = 119;
     253static const ItemState kArthur002 = 120;
     254static const ItemState kArthur010 = 121;
     255static const ItemState kArthur012 = 122;
     256static const ItemState kArthur100 = 123;
     257static const ItemState kArthur102 = 124;
     258static const ItemState kArthur110 = 125;
     259static const ItemState kArthur112 = 126;
    251260
    252261// Extra IDs.
    253262
  • engines/pegasus/menu.cpp

    diff --git a/engines/pegasus/menu.cpp b/engines/pegasus/menu.cpp
    index e55c006..0897f2a 100644
    a b  
    2323 *
    2424 */
    2525
     26#include "common/file.h"
     27
    2628#include "pegasus/gamestate.h"
    2729#include "pegasus/menu.h"
    2830#include "pegasus/pegasus.h"
    MainMenu::MainMenu() : GameMenu(kMainMenuID), _menuBackground(0), _overviewButto  
    155157                else
    156158                        _menuBackground.initFromPICTFile("Images/Demo/DemoMenu.pict");
    157159        } else {
    158                 _menuBackground.initFromPICTFile("Images/Main Menu/MainMenu.mac");
     160                if (((PegasusEngine *)g_engine)->isDVD())
     161                        _menuBackground.initFromPICTFile("Images/Main Menu/MainMenu_hq.mac");
     162                else
     163                        _menuBackground.initFromPICTFile("Images/Main Menu/MainMenu.mac");
    159164        }
    160165        _menuBackground.setDisplayOrder(0);
    161166        _menuBackground.startDisplaying();
    static const CoordType kCreditsMainMenuSelectTop = 408;  
    444449
    445450static const TimeValue kCoreTeamTime = 0;
    446451static const TimeValue kSupportTeamTime = 1920;
    447 static const TimeValue kOriginalTeamTime = 3000;
    448 static const TimeValue kTalentTime = 4440;
    449 static const TimeValue kOtherTitlesTime = 4680;
     452static const TimeValue kOriginalTeamCDTime = 3000;
     453static const TimeValue kOriginalTeamDVDTime = 3240;
     454static const TimeValue kTalentCDTime = 4440;
     455static const TimeValue kTalentDVDTime = 4680;
     456static const TimeValue kOtherTitlesCDTime = 4680;
     457static const TimeValue kOtherTitlesDVDTime = 4920;
    450458
    451459static const TimeValue kFrameIncrement = 120; // Three frames...
    452460
    static const TimeValue kFrameIncrement = 120; // Three frames...  
    454462CreditsMenu::CreditsMenu() : GameMenu(kCreditsMenuID), _menuBackground(0), _creditsMovie(0),
    455463                _mainMenuButton(0), _largeSelect(0), _smallSelect(0) {
    456464
    457         _menuBackground.initFromPICTFile("Images/Credits/CredScrn.pict");
     465        if (((PegasusEngine *)g_engine)->isDVD())
     466                _menuBackground.initFromPICTFile("Images/Credits/CredScrnScummVM.pict");
     467        else
     468                _menuBackground.initFromPICTFile("Images/Credits/CredScrn.pict");
    458469        _menuBackground.setDisplayOrder(0);
    459470        _menuBackground.startDisplaying();
    460471        _menuBackground.show();
    461472
    462         _creditsMovie.initFromMovieFile("Images/Credits/Credits.movie");
     473        if (((PegasusEngine *)g_engine)->isDVD())
     474                _creditsMovie.initFromMovieFile("Images/Credits/Credits_scummVM.movie");
     475        else
     476                _creditsMovie.initFromMovieFile("Images/Credits/Credits.movie");
    463477        _creditsMovie.setDisplayOrder(1);
    464478        _creditsMovie.moveElementTo(kCreditsMovieLeft, kCreditsMovieTop);
    465479        _creditsMovie.startDisplaying();
    CreditsMenu::CreditsMenu() : GameMenu(kCreditsMenuID), _menuBackground(0), _cred  
    484498        _menuSelection = -1;
    485499
    486500        newMenuSelection(kCreditsMenuCoreTeam);
     501
     502        if (((PegasusEngine *)g_engine)->isDVD()) {
     503                _menuLoop.attachFader(&_menuFader);
     504                _menuLoop.initFromAIFFFile("Sounds/Credits.aiff");
     505        }
     506}
     507
     508CreditsMenu::~CreditsMenu() {
     509        if (_menuLoop.isPlaying())
     510                stopCreditsMenuLoop();
     511}
     512
     513void CreditsMenu::startCreditsMenuLoop() {
     514        if (((PegasusEngine *)g_engine)->isDVD()) {
     515                FaderMoveSpec spec;
     516
     517                _menuLoop.loopSound();
     518                spec.makeTwoKnotFaderSpec(30, 0, 0, 30, 255);
     519
     520                _menuFader.startFader(spec);
     521        }
     522}
     523
     524void CreditsMenu::stopCreditsMenuLoop() {
     525        if (((PegasusEngine *)g_engine)->isDVD()) {
     526                FaderMoveSpec spec;
     527       
     528                spec.makeTwoKnotFaderSpec(30, 0, 255, 30, 0);
     529                _menuFader.startFaderSync(spec);
     530                _menuLoop.stopSound();
     531        }
    487532}
    488533
    489534// Assumes the new selection is never more than one away from the old...
    void CreditsMenu::newMenuSelection(const int newSelection) {  
    493538                case kCreditsMenuCoreTeam:
    494539                        _smallSelect.moveElementTo(kCoreTeamSelectLeft, kCoreTeamSelectTop);
    495540                        _creditsMovie.setTime(kCoreTeamTime);
    496                         _creditsMovie.redrawMovieWorld();
    497541                        break;
    498542                case kCreditsMenuSupportTeam:
    499543                        _smallSelect.moveElementTo(kSupportTeamSelectLeft, kSupportTeamSelectTop);
    500544                        _creditsMovie.setTime(kSupportTeamTime);
    501                         _creditsMovie.redrawMovieWorld();
    502545                        break;
    503546                case kCreditsMenuOriginalTeam:
    504547                        _smallSelect.moveElementTo(kOriginalTeamSelectLeft, kOriginalTeamSelectTop);
    505                         _creditsMovie.setTime(kOriginalTeamTime);
    506                         _creditsMovie.redrawMovieWorld();
     548                        if (((PegasusEngine *)g_engine)->isDVD())
     549                                _creditsMovie.setTime(kOriginalTeamDVDTime);
     550                        else
     551                                _creditsMovie.setTime(kOriginalTeamCDTime);
    507552                        break;
    508553                case kCreditsMenuTalent:
    509554                        _smallSelect.moveElementTo(kTalentSelectLeft, kTalentSelectTop);
    510                         _creditsMovie.setTime(kTalentTime);
    511                         _creditsMovie.redrawMovieWorld();
     555                        if (((PegasusEngine *)g_engine)->isDVD())
     556                                _creditsMovie.setTime(kTalentDVDTime);
     557                        else
     558                                _creditsMovie.setTime(kTalentCDTime);
    512559                        break;
    513560                case kCreditsMenuOtherTitles:
    514561                        _smallSelect.moveElementTo(kOtherTitlesSelectLeft, kOtherTitlesSelectTop);
    515562                        _smallSelect.show();
    516563                        _largeSelect.hide();
    517                         _creditsMovie.setTime(kOtherTitlesTime);
    518                         _creditsMovie.redrawMovieWorld();
     564                        if (((PegasusEngine *)g_engine)->isDVD())
     565                                _creditsMovie.setTime(kOtherTitlesDVDTime);
     566                        else
     567                                _creditsMovie.setTime(kOtherTitlesCDTime);
    519568                        break;
    520569                case kCreditsMenuMainMenu:
    521570                        _smallSelect.hide();
    522571                        _largeSelect.show();
    523572                        break;
    524573                }
     574                _creditsMovie.redrawMovieWorld();
    525575
    526576                _menuSelection = newSelection;
    527577        }
    528578}
    529579
    530580void CreditsMenu::newMovieTime(const TimeValue newTime) {
     581        // The DVD credits have an extra frame in the support team section
     582        bool isDVD = ((PegasusEngine *)g_engine)->isDVD();
     583
    531584        if (newTime < kSupportTeamTime) {
    532585                _smallSelect.moveElementTo(kCoreTeamSelectLeft, kCoreTeamSelectTop);
    533586                _menuSelection = kCreditsMenuCoreTeam;
    534         } else if (newTime < kOriginalTeamTime) {
     587        } else if ((isDVD && newTime < kOriginalTeamDVDTime) || (!isDVD && newTime < kOriginalTeamCDTime)) {
    535588                _smallSelect.moveElementTo(kSupportTeamSelectLeft, kSupportTeamSelectTop);
    536589                _menuSelection = kCreditsMenuSupportTeam;
    537         } else if (newTime < kTalentTime) {
     590        } else if ((isDVD && newTime < kTalentDVDTime) || (!isDVD && newTime < kTalentCDTime)) {
    538591                _smallSelect.moveElementTo(kOriginalTeamSelectLeft, kOriginalTeamSelectTop);
    539592                _menuSelection = kCreditsMenuOriginalTeam;
    540         } else if (newTime < kOtherTitlesTime) {
     593        } else if ((isDVD && newTime < kOtherTitlesDVDTime) || (!isDVD && newTime < kOtherTitlesCDTime)) {
    541594                _smallSelect.moveElementTo(kTalentSelectLeft, kTalentSelectTop);
    542595                _smallSelect.show();
    543596                _largeSelect.hide();
    DeathMenu::DeathMenu(const DeathReason deathReason) : GameMenu(kDeathMenuID), _d  
    664717                        "dAunmade", "dAbombed", "dAshot", "dAassass", "dAnuked",
    665718                        "dTunmade", "dTshot", "dPfall", "dPdino", "dPstuck",
    666719                        "dNchoke", "dNcaught", "dNcaught", "dNsub", "dNrobot1",
    667                         "dNrobot2", "dMfall", "dMcaught", "dMtracks", "dMrobot",
    668                         "dMtoast", "dMexplo1", "dMexplo2", "dMchoke1", "dMchoke2",
    669                         "dMdroid", "dMfall", "dMgears", "dMshutt1", "dMshutt2",
    670                         "dWpoison", "dWcaught", "dWplasma", "dWshot", "dAfinale"
     720                        "dNrobot2", "dMfall", "dMcaught", "dMcollision", "dMtracks",
     721                        "dMrobot", "dMtoast", "dMexplo1", "dMexplo2", "dMchoke1",
     722                        "dMchoke2", "dMdroid", "dMshaft", "dMgears", "dMshutt1",
     723                        "dMshutt2", "dWpoison", "dWcaught", "dWplasma", "dWshot",
     724                        "dAfinale"
    671725                };
    672726
    673727                imageName += fileNames[deathReason - 1];
    DeathMenu::DeathMenu(const DeathReason deathReason) : GameMenu(kDeathMenuID), _d  
    735789                _largeSelect.setDisplayOrder(2);
    736790                _largeSelect.startDisplaying();
    737791        } else {
    738                 _triumphSound.initFromQuickTime("Sounds/Caldoria/Galactic Triumph");
     792                if (vm->isDVD()) // Updated file for the DVD version
     793                        _triumphSound.initFromAIFFFile("Sounds/Caldoria/Galactic Triumph.44K.aiff");
     794                else
     795                        _triumphSound.initFromQuickTime("Sounds/Caldoria/Galactic Triumph");
    739796                _triumphSound.playSound();
    740797        }
    741798
    void DeathMenu::drawAllScores() {  
    864921        case kDeathRobotSubControlRoom:
    865922        case kDeathWrongShuttleLock:
    866923        case kDeathArrestedInMars:
     924        case kDeathCollidedWithPod:
    867925        case kDeathRunOverByPod:
    868926        case kDeathDidntGetOutOfWay:
    869927        case kDeathReactorBurn:
  • engines/pegasus/menu.h

    diff --git a/engines/pegasus/menu.h b/engines/pegasus/menu.h
    index 288b846..c0a27ef 100644
    a b protected:  
    9797class CreditsMenu : public GameMenu {
    9898public:
    9999        CreditsMenu();
    100         virtual ~CreditsMenu() {}
     100        virtual ~CreditsMenu();
    101101
    102102        virtual void handleInput(const Input &input, const Hotspot *);
     103        void startCreditsMenuLoop();
     104        void stopCreditsMenuLoop();
    103105
    104106protected:
    105107        void newMenuSelection(const int);
    protected:  
    111113        Picture _mainMenuButton;
    112114        Picture _largeSelect;
    113115        Picture _smallSelect;
     116
     117        Sound _menuLoop;
     118        SoundFader _menuFader;
    114119};
    115120
    116121class DeathMenu : public GameMenu {
  • engines/pegasus/module.mk

    diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk
    index cb44a04..2dd5b87 100644
    a b  
    11MODULE := engines/pegasus
    22
    33MODULE_OBJS = \
     4        chase.o \
    45        compass.o \
    56        console.o \
    67        cursor.o \
    MODULE_OBJS = \  
    3334        items/itemdragger.o \
    3435        items/itemlist.o \
    3536        items/biochips/aichip.o \
     37        items/biochips/arthurchip.o \
    3638        items/biochips/biochipitem.o \
    3739        items/biochips/mapchip.o \
    3840        items/biochips/mapimage.o \
    MODULE_OBJS = \  
    5860        neighborhood/caldoria/caldoriabomb.o \
    5961        neighborhood/caldoria/caldoriamessages.o \
    6062        neighborhood/caldoria/caldoriamirror.o \
     63        neighborhood/mars/canyonchase.o \
    6164        neighborhood/mars/energybeam.o \
    6265        neighborhood/mars/gravitoncannon.o \
    6366        neighborhood/mars/hermite.o \
    MODULE_OBJS = \  
    7174        neighborhood/mars/spacechase3d.o \
    7275        neighborhood/mars/spacejunk.o \
    7376        neighborhood/mars/tractorbeam.o \
     77        neighborhood/mars/tunnelpod.o \
    7478        neighborhood/norad/norad.o \
    7579        neighborhood/norad/noradelevator.o \
    7680        neighborhood/norad/pressuredoor.o \
    MODULE_OBJS = \  
    8286        neighborhood/norad/alpha/noradalpha.o \
    8387        neighborhood/norad/alpha/panorama.o \
    8488        neighborhood/norad/alpha/panoramascroll.o \
     89        neighborhood/norad/alpha/subchase.o \
    8590        neighborhood/norad/delta/globegame.o \
    8691        neighborhood/norad/delta/noraddelta.o \
    8792        neighborhood/prehistoric/prehistoric.o \
  • engines/pegasus/neighborhood/caldoria/caldoria.cpp

    diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.cpp b/engines/pegasus/neighborhood/caldoria/caldoria.cpp
    index 0707a83..0cb7f22 100644
    a b  
    2525
    2626#include "common/system.h"
    2727#include "video/qt_decoder.h"
     28#include "video/theora_decoder.h"
    2829
    2930#include "pegasus/cursor.h"
    3031#include "pegasus/energymonitor.h"
     
    3233#include "pegasus/interface.h"
    3334#include "pegasus/pegasus.h"
    3435#include "pegasus/ai/ai_area.h"
     36#include "pegasus/items/biochips/arthurchip.h"
    3537#include "pegasus/items/biochips/biochipitem.h"
    3638#include "pegasus/neighborhood/caldoria/caldoria.h"
    3739#include "pegasus/neighborhood/caldoria/caldoria4dsystem.h"
    static const int16 kDrawersAngle = -30;  
    4850static const int16 kCaldoria53Angle = 45;
    4951static const int16 kCaldoria55Angle = -45;
    5052
     53static const ExtraID kCreateCornbread = 1000;
     54static const ExtraID kWashingMachineZoomIn = 1001;
     55static const ExtraID kWashingMachineLoop = 1002;
     56static const ExtraID kWashingMachineZoomOut = 1003;
     57
     58static const HotSpotID kCaldoriaLaundryZoomInHotSpotID = 10000;
     59static const HotSpotID kCaldoriaLaundryZoomOutHotSpotID = 10001;
     60static const HotSpotID kCaldoriaCornbreadHotSpotID = 10002;
     61
    5162static const TimeValue kSinclairInterruptionTime1 = 2955;
    5263static const TimeValue kSinclairInterruptionTime2 = 6835;
    5364static const TimeValue kSinclairInterruptionTime3 = 9835;
    static const TimeValue kSinclairInterruptionTime4 = 12555;  
    5667static const InputBits kPullbackInterruptFilter = kFilterAllInput;
    5768static const InputBits kRecalibrationInterruptFilter = kFilterAllInput;
    5869
     70static const TimeValue kCaldoriaLaundryIntro1In = 0;
     71static const TimeValue kCaldoriaLaundryIntro1Out = 2645;
     72
     73static const TimeValue kCaldoriaLaundryIntro2In = 2645;
     74static const TimeValue kCaldoriaLaundryIntro2Out = 4933;
     75
    5976static const TimeValue kCaldoriaReplicatorIntroIn = 4933;
    6077static const TimeValue kCaldoriaReplicatorIntroOut = 6557;
    6178
    static const TimeValue kCaldoriaNobodyHomeOut = 21469;  
    92109static const TimeValue kCaldoriaNoOtherFloorIn = 21469;
    93110static const TimeValue kCaldoriaNoOtherFloorOut = 28013;
    94111
    95 static const TimeValue kCaldoria4DInstructionsIn = 28013;
    96 static const TimeValue kCaldoria4DInstructionsOut = 29730;
    97 
    98112static const TimeValue kCaldoriaDrinkOJIn = 33910;
    99113static const TimeValue kCaldoriaDrinkOJOut = 35846;
    100114
    void SinclairCallBack::callBack() {  
    159173}
    160174
    161175Caldoria::Caldoria(InputHandler* nextHandler, PegasusEngine *owner)
    162                 : Neighborhood(nextHandler, owner, "Caldoria", kCaldoriaID), _sinclairInterrupt(this) {
     176                : Neighborhood(nextHandler, owner, "Caldoria", kCaldoriaID), _extraMovie(kNoDisplayElement),
     177                _laundryZoomInSpot(kCaldoriaLaundryZoomInHotSpotID), _laundryZoomOutSpot(kCaldoriaLaundryZoomOutHotSpotID),
     178                _cornbreadSpot(kCaldoriaCornbreadHotSpotID), _sinclairInterrupt(this), _lookingAtLaundry(false) {
    163179        setIsItemTaken(kKeyCard);
    164180        setIsItemTaken(kOrangeJuiceGlassEmpty);
    165181        GameState.setTakenItemID(kOrangeJuiceGlassFull, GameState.isTakenItemID(kOrangeJuiceGlassEmpty));
    Caldoria::Caldoria(InputHandler* nextHandler, PegasusEngine *owner)  
    169185
    170186Caldoria::~Caldoria() {
    171187        _sinclairInterrupt.releaseCallBack();
     188        if (_vm->isDVD()) {
     189                _vm->getAllHotspots().remove(&_laundryZoomInSpot);
     190                _vm->getAllHotspots().remove(&_laundryZoomOutSpot);
     191                _vm->getAllHotspots().remove(&_cornbreadSpot);
     192        }
    172193}
    173194
    174195void Caldoria::init() {
    175196        Neighborhood::init();
    176197
     198        if (_vm->isDVD()) {
     199                _laundryZoomInSpot.setArea(Common::Rect(384, 120, 576, 320));
     200                _laundryZoomInSpot.setHotspotFlags(kNeighborhoodSpotFlag | kZoomInSpotFlag);
     201                _vm->getAllHotspots().push_back(&_laundryZoomInSpot);
     202
     203                _laundryZoomOutSpot.setArea(Common::Rect(64, 64, 576, 320));
     204                _laundryZoomOutSpot.setHotspotFlags(kNeighborhoodSpotFlag | kZoomOutSpotFlag);
     205                _vm->getAllHotspots().push_back(&_laundryZoomOutSpot);
     206
     207                _cornbreadSpot.setArea(Common::Rect(270, 233, 381, 298));
     208                _cornbreadSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
     209                _vm->getAllHotspots().push_back(&_cornbreadSpot);
     210        }
     211
    177212        // We need this notification flag as well.
    178213        _neighborhoodNotification.notifyMe(this, kSinclairLoopDoneFlag, kSinclairLoopDoneFlag);
    179214
     215        _extraMovieCallBack.setNotification(&_neighborhoodNotification);
     216
    180217        _sinclairInterrupt.initCallBack(&_navMovie, kCallBackAtTime);
    181218
    182219        forceStridingStop(kCaldoria55, kSouth, kAltCaldoriaSinclairDown);
    void Caldoria::start() {  
    187224        g_energyMonitor->stopEnergyDraining();
    188225
    189226        if (!GameState.getCaldoriaSeenPullback()) {
     227                Input input;
     228                Common::String wakeModeMoviePath;
     229                InputDevice.getInput(input, kPullbackInterruptFilter);
     230                if (_vm->isDVD() && JMPPPInput::isEasterEggModifierInput(input)) {
     231                        wakeModeMoviePath = "Images/Caldoria/A00WM";
     232                } else {
     233                        wakeModeMoviePath = "Images/Caldoria/A00WN";
     234                }
     235
    190236                _vm->_gfx->doFadeOutSync(kOneSecond * kFifteenTicksPerSecond, kFifteenTicksPerSecond);
    191237
    192                 g_system->delayMillis(2 * 1000);
     238                Video::VideoDecoder *pullbackMovie = 0;
     239                uint16 pullbackX, pullbackY;
    193240
    194                 Video::VideoDecoder *pullbackMovie = new Video::QuickTimeDecoder();
     241#ifdef USE_THEORADEC
     242                if (_vm->isDVD()) {
     243                        // Updated larger version
     244                        pullbackMovie = new Video::TheoraDecoder();
     245
     246                        if (!pullbackMovie->loadFile("Images/Caldoria/Pullback.ogg")) {
     247                                delete pullbackMovie;
     248                                pullbackMovie = 0;
     249                        }
     250                }
     251#endif
     252               
     253                if (!pullbackMovie) {
     254                        pullbackMovie = new Video::QuickTimeDecoder();
    195255
    196                 if (!pullbackMovie->loadFile("Images/Caldoria/Pullback.movie"))
    197                         error("Could not load pullback movie");
     256                        if (!pullbackMovie->loadFile("Images/Caldoria/Pullback.movie"))
     257                                error("Could not load Pullback.movie");
     258                }
     259               
     260                if (_vm->isDVD()) {
     261                        uint16 newHeight = (uint16)((640.0f / (float)pullbackMovie->getWidth()) * (float)pullbackMovie->getHeight());
     262                        pullbackX = 0;
     263                        pullbackY = (480 - newHeight) / 2;
     264                } else {
     265                        pullbackX = 80;
     266                        pullbackY = 112;
     267                }
    198268
    199269                // Draw the first frame so we can fade to it
    200270                const Graphics::Surface *frame = pullbackMovie->decodeNextFrame();
    201271                assert(frame);
    202272                assert(frame->format == g_system->getScreenFormat());
    203                 g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 64, 112, frame->w, frame->h);
     273                g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, pullbackX, pullbackY, frame->w, frame->h);
    204274                _vm->_gfx->doFadeInSync(kTwoSeconds * kFifteenTicksPerSecond, kFifteenTicksPerSecond);
    205275
    206276                bool saveAllowed = _vm->swapSaveAllowed(false);
    207277                bool openAllowed = _vm->swapLoadAllowed(false);
    208278
    209279                bool skipped = false;
    210                 Input input;
    211280
    212281                pullbackMovie->start();
    213282
    void Caldoria::start() {  
    216285                                frame = pullbackMovie->decodeNextFrame();
    217286
    218287                                if (frame) {
    219                                         g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 64, 112, frame->w, frame->h);
     288                                        g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, pullbackX, pullbackY, frame->w, frame->h);
    220289                                        g_system->updateScreen();
    221290                                }
    222291                        }
    223292
    224293                        InputDevice.getInput(input, kPullbackInterruptFilter);
    225                         if (input.anyInput() || _vm->saveRequested() || _vm->loadRequested()) {
     294                        if ((input.anyInput() || _vm->saveRequested() || _vm->loadRequested()) && !GameState.getEasterEgg()) {
    226295                                skipped = true;
    227296                                break;
    228297                        }
    void Caldoria::start() {  
    241310                ExtraTable::Entry entry;
    242311
    243312                if (!skipped) {
    244                         _vm->_gfx->doFadeOutSync(kThreeSeconds * kFifteenTicksPerSecond, kFifteenTicksPerSecond, false);
    245                         g_system->delayMillis(3 * 1000 / 2);
    246                         getExtraEntry(kCaldoria00WakeUp1, entry);
    247                         _navMovie.setTime(entry.movieStart);
    248                         _navMovie.redrawMovieWorld();
    249                         _navMovie.show();
    250                         _vm->refreshDisplay();
    251                         _vm->_gfx->doFadeInSync(kOneSecond * kFifteenTicksPerSecond, kFifteenTicksPerSecond, false);
     313                        if (_vm->isDVD()) {
     314                                Video::VideoDecoder* wakeModeMovie = 0;
     315#ifdef USE_THEORADEC
     316                                wakeModeMovie = new Video::TheoraDecoder();
     317                                if (!wakeModeMovie->loadFile(wakeModeMoviePath + ".ogg")) {
     318                                        delete wakeModeMovie;
     319                                        wakeModeMovie = 0;
     320                                }
     321#endif
     322                                if (!wakeModeMovie) {
     323                                        wakeModeMovie = new Video::QuickTimeDecoder();
     324                                        if (!wakeModeMovie->loadFile(wakeModeMoviePath + ".movie"))
     325                                                error("Could not load Jonny Ego movie");
     326                                }
     327
     328                                wakeModeMovie->start();
     329
     330                                while (!_vm->shouldQuit() && !wakeModeMovie->endOfVideo()) {
     331                                        if (wakeModeMovie->needsUpdate()) {
     332                                                frame = wakeModeMovie->decodeNextFrame();
     333
     334                                                if (frame) {
     335                                                        g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
     336                                                        g_system->updateScreen();
     337                                                }
     338                                        }
     339
     340                                        InputDevice.getInput(input, kPullbackInterruptFilter);
     341                                        if ((input.anyInput() || _vm->saveRequested() || _vm->loadRequested()) && !GameState.getEasterEgg()) {
     342                                                skipped = true;
     343                                                break;
     344                                        }
     345
     346                                        g_system->delayMillis(10);
     347                                }
     348
     349                                delete wakeModeMovie;
     350
     351                                if (_vm->shouldQuit())
     352                                        return;
     353                        } else {
     354                                _vm->_gfx->doFadeOutSync(kThreeSeconds * kFifteenTicksPerSecond, kFifteenTicksPerSecond, false);
     355                                g_system->delayMillis(3 * 1000 / 2);
     356                                getExtraEntry(kCaldoria00WakeUp1, entry);
     357                                _navMovie.setTime(entry.movieStart);
     358                                _navMovie.redrawMovieWorld();
     359                                _navMovie.show();
     360                                _vm->refreshDisplay();
     361                                _vm->_gfx->doFadeInSync(kOneSecond * kFifteenTicksPerSecond, kFifteenTicksPerSecond, false);
     362                        }
    252363                } else {
    253364                        getExtraEntry(kCaldoria00WakeUp1, entry);
    254365                        _navMovie.setTime(entry.movieStart);
    void Caldoria::start() {  
    262373        Neighborhood::start();
    263374}
    264375
     376void Caldoria::throwAwayInterface() {
     377        Neighborhood::throwAwayInterface();
     378        if (_vm->isDVD()) {
     379                _vm->getAllHotspots().remove(&_laundryZoomInSpot);
     380                _vm->getAllHotspots().remove(&_laundryZoomOutSpot);
     381                _vm->getAllHotspots().remove(&_cornbreadSpot);
     382        }
     383}
     384
    265385void Caldoria::flushGameState() {
    266386        GameState.setCaldoriaFuseTimeLimit(_utilityFuse.getTimeRemaining());
    267387}
    void Caldoria::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec  
    686806void Caldoria::loadAmbientLoops() {
    687807        RoomID room = GameState.getCurrentRoom();
    688808
    689         if (room == kCaldoria00 && GameState.getCaldoriaWokenUp())
    690                 loadLoopSound1("Sounds/Caldoria/Apartment Music.AIFF", 0x100 / 4);
    691         else if (room >= kCaldoria01 && room <= kCaldoria14)
    692                 loadLoopSound1("Sounds/Caldoria/Apartment Music.AIFF", 0x100 / 4);
    693         else if (room == kCaldoria27 || room == kCaldoria28 || room == kCaldoria45)
    694                 loadLoopSound1("Sounds/Caldoria/Elevator Loop.AIFF", 0x100 / 5);
    695         else if (room == kCaldoria44)
    696                 loadLoopSound1("Sounds/Caldoria/TSA Hum Loop.AIFF");
    697         else if (room >= kCaldoria15 && room <= kCaldoria48)
    698                 loadLoopSound1("Sounds/Caldoria/Industrial Nuage.aiff", 2 * 0x100 / 3);
    699         else if (room >= kCaldoria49 && room <= kCaldoria56)
    700                 loadLoopSound1("Sounds/Caldoria/A50NLB00.22K.AIFF", 0x100 / 4);
     809        if (_vm->isDVD()) {
     810                // Updated sounds in the DVD version
     811                if (room == kCaldoria00 && GameState.getCaldoriaWokenUp())
     812                        loadLoopSound1("Sounds/Caldoria/Apartment Music.32K.aiff", 0x100 / 4);
     813                else if (room >= kCaldoria01 && room <= kCaldoria14)
     814                        loadLoopSound1("Sounds/Caldoria/Apartment Music.32K.aiff", 0x100 / 4);
     815                else if (room == kCaldoria27 || room == kCaldoria28 || room == kCaldoria45)
     816                        loadLoopSound1("Sounds/Caldoria/Elevator Loop.32K.aiff", 0x100 / 5);
     817                else if (room == kCaldoria44)
     818                        loadLoopSound1("Sounds/Caldoria/TSA Hum Loop.44K.aiff");
     819                else if (room >= kCaldoria15 && room <= kCaldoria48)
     820                        loadLoopSound1("Sounds/Caldoria/Industrial Nuage.44K.aiff", 2 * 0x100 / 3);
     821                else if (room >= kCaldoria49 && room <= kCaldoria56)
     822                        loadLoopSound1("Sounds/Caldoria/A50NLB00.32K.AIFF", 0x100 / 4);
     823        } else {
     824                if (room == kCaldoria00 && GameState.getCaldoriaWokenUp())
     825                        loadLoopSound1("Sounds/Caldoria/Apartment Music.AIFF", 0x100 / 4);
     826                else if (room >= kCaldoria01 && room <= kCaldoria14)
     827                        loadLoopSound1("Sounds/Caldoria/Apartment Music.AIFF", 0x100 / 4);
     828                else if (room == kCaldoria27 || room == kCaldoria28 || room == kCaldoria45)
     829                        loadLoopSound1("Sounds/Caldoria/Elevator Loop.AIFF", 0x100 / 5);
     830                else if (room == kCaldoria44)
     831                        loadLoopSound1("Sounds/Caldoria/TSA Hum Loop.AIFF");
     832                else if (room >= kCaldoria15 && room <= kCaldoria48)
     833                        loadLoopSound1("Sounds/Caldoria/Industrial Nuage.aiff", 2 * 0x100 / 3);
     834                else if (room >= kCaldoria49 && room <= kCaldoria56)
     835                        loadLoopSound1("Sounds/Caldoria/A50NLB00.22K.AIFF", 0x100 / 4);
     836        }
    701837}
    702838
    703839void Caldoria::checkContinuePoint(const RoomID room, const DirectionConstant direction) {
    void Caldoria::checkContinuePoint(const RoomID room, const DirectionConstant dir  
    718854
    719855void Caldoria::spotCompleted() {
    720856        Neighborhood::spotCompleted();
    721         if (GameState.getCurrentRoom() == kCaldoriaBinoculars)
     857        switch (GameState.getCurrentRoom()) {
     858        case kCaldoriaBinoculars:
    722859                startExtraSequence(kBinocularsZoomInOnShip, kExtraCompletedFlag, kFilterNoInput);
     860                break;
     861        case kCaldoriaToilet:
     862                if (g_arthurChip)
     863                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA47", kArthurCaldoriaReadPaper);
     864                break;
     865        }
    723866}
    724867
    725868void Caldoria::arriveAt(const RoomID room, const DirectionConstant direction) {
    void Caldoria::arriveAt(const RoomID room, const DirectionConstant direction) {  
    741884
    742885        Neighborhood::arriveAt(room, direction);
    743886        Input dummy;
     887        Sound flushSound;
    744888
    745889        switch (room) {
    746890        case kCaldoria00:
    void Caldoria::arriveAt(const RoomID room, const DirectionConstant direction) {  
    757901        case kCaldoria09:
    758902                _lastExtra = 0xffffffff;
    759903                break;
     904        case kCaldoria10:
     905                if (_vm->isDVD() && direction == kWest) {
     906                        _vm->_cursor->hide();
     907                        flushSound.initFromAIFFFile("Sounds/Caldoria/Apartment Toilet.32K.aiff");
     908                        flushSound.setVolume(_vm->getSoundFXLevel());
     909                        flushSound.playSound();
     910                        while (flushSound.isPlaying() && !_vm->shouldQuit()) {
     911                                InputDevice.getInput(dummy, kFilterNoInput);
     912
     913                                _vm->checkCallBacks();
     914                                _vm->refreshDisplay();
     915                                _vm->_system->delayMillis(10);
     916                        }
     917                        if (_vm->shouldQuit())
     918                                return;
     919                        _vm->_cursor->hideUntilMoved();
     920                } else if (direction == kEast) {
     921                        if (g_arthurChip)
     922                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA42", kArthurCaldoriaReachedToilet);
     923                }
     924                break;
    760925        case kCaldoriaToilet:
    761926                GameState.setScoringReadPaper(true);
    762927                break;
    void Caldoria::arriveAt(const RoomID room, const DirectionConstant direction) {  
    812977        case kCaldoria49:
    813978                arriveAtCaldoria49();
    814979                break;
     980        case kCaldoria48:
     981                if (direction == kNorth && !GameState.getCaldoriaDoorBombed() && GameState.isTakenItemID(kCardBomb) && g_arthurChip)
     982                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA12", kArthurCaldoriaRoofDoor);           
     983                break;
    815984        case kCaldoria53:
    816985                if (direction == kEast && !GameState.getCaldoriaSinclairShot())
    817986                        zoomToSinclair();
    void Caldoria::arriveAt(const RoomID room, const DirectionConstant direction) {  
    8391008void Caldoria::doAIRecalibration() {
    8401009        GameState.setCaldoriaDidRecalibration(true);
    8411010
    842         if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB1", true, kRecalibrationInterruptFilter))
    843                 return;
     1011        Input input;
     1012        InputDevice.getInput(input, kPullbackInterruptFilter);
     1013        if (_vm->isDVD() && JMPPPInput::isEasterEggModifierInput(input)) {
     1014                Video::VideoDecoder *video = 0;
    8441015
    845         g_interface->calibrateEnergyBar();
    846         if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB4", true, kRecalibrationInterruptFilter))
    847                 return;
     1016                _vm->_cursor->hide();
     1017
     1018#ifdef USE_THEORADEC
     1019                video = new Video::TheoraDecoder();
     1020                if (!video->loadFile("Images/Caldoria/A00EA.ogg")) {
     1021                        delete video;
     1022                        video = 0;
     1023                }
     1024#endif
     1025
     1026                if (!video) {
     1027                        video = new Video::QuickTimeDecoder();
     1028                        if (!video->loadFile("Images/Caldoria/A00EA.movie"))
     1029                                error("Could not load Month-O-Matic video");
     1030                }
     1031
     1032                video->setVolume(MIN<uint>(_vm->getSoundFXLevel(), 0xFF));
     1033                video->start();
     1034
     1035                while (!_vm->shouldQuit() && !video->endOfVideo()) {
     1036                        if (video->needsUpdate()) {
     1037                                const Graphics::Surface *frame = video->decodeNextFrame();
     1038
     1039                                if (frame) {
     1040                                        g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, kNavAreaLeft, kNavAreaTop, frame->w, frame->h);
     1041                                        g_system->updateScreen();
     1042                                }
     1043                        }
     1044
     1045                        Common::Event event;
     1046                        while (g_system->getEventManager()->pollEvent(event))
     1047                                ;
     1048
     1049                        g_system->delayMillis(10);
     1050                }
     1051
     1052                delete video;
     1053
     1054                if (_vm->shouldQuit())
     1055                        return;
     1056               
     1057                arriveAt(kCaldoria01, kEast);
     1058        } else if (g_AIArea->isChattyAI()) {
     1059                if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB1", true, kRecalibrationInterruptFilter))
     1060                        return;
     1061
     1062                g_interface->calibrateEnergyBar();
     1063                if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB4", true, kRecalibrationInterruptFilter))
     1064                        return;
     1065
     1066                g_interface->raiseInventoryDrawerSync();
     1067                if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB6", true, kRecalibrationInterruptFilter)) {
     1068                        g_interface->lowerInventoryDrawerSync();
     1069                        return;
     1070                }
    8481071
    849         g_interface->raiseInventoryDrawerSync();
    850         if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB6", true, kRecalibrationInterruptFilter)) {
    8511072                g_interface->lowerInventoryDrawerSync();
    852                 return;
    853         }
     1073                g_interface->raiseBiochipDrawerSync();
    8541074
    855         g_interface->lowerInventoryDrawerSync();
    856         g_interface->raiseBiochipDrawerSync();
     1075                if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB5", true, kRecalibrationInterruptFilter)) {
     1076                        g_interface->lowerBiochipDrawerSync();
     1077                        return;
     1078                }
    8571079
    858         if (!g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB5", true, kRecalibrationInterruptFilter)) {
    8591080                g_interface->lowerBiochipDrawerSync();
    860                 return;
    861         }
    862 
    863         g_interface->lowerBiochipDrawerSync();
    8641081
    865         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB8", false, kRecalibrationInterruptFilter);
     1082                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Caldoria/XA01EB8", false, kRecalibrationInterruptFilter);
     1083        }
    8661084}
    8671085
    8681086void Caldoria::arriveAtCaldoria00() {
    void Caldoria::setUpRoofTop() {  
    9851203        }
    9861204}
    9871205
     1206void Caldoria::leftButton(const Input &input) {
     1207        if (!(GameState.getCurrentRoomAndView() == MakeRoomView(kCaldoria11, kWest) && _lookingAtLaundry))
     1208                Neighborhood::leftButton(input);
     1209}
     1210
     1211void Caldoria::rightButton(const Input &input) {
     1212        if (!(GameState.getCurrentRoomAndView() == MakeRoomView(kCaldoria11, kWest) && _lookingAtLaundry))
     1213                Neighborhood::rightButton(input);
     1214}
     1215
    9881216void Caldoria::downButton(const Input &input) {
    9891217        switch (GameState.getCurrentRoomAndView()) {
    9901218        case MakeRoomView(kCaldoria01, kEast):
    9911219                GameState.setCaldoriaWokenUp(true);
    9921220                startExtraSequence(kCaldoria00SitDown, kExtraCompletedFlag, kFilterNoInput);
    9931221                break;
     1222        case MakeRoomView(kCaldoria11, kWest):
     1223                if (_lookingAtLaundry)
     1224                        startExtraSequence(kWashingMachineZoomOut, kExtraCompletedFlag, kFilterNoInput);
     1225                break;
    9941226        default:
    9951227                Neighborhood::downButton(input);
    9961228                break;
    void Caldoria::turnTo(const DirectionConstant direction) {  
    10261258        case kCaldoria09:
    10271259                _lastExtra = 0xffffffff;
    10281260                break;
     1261        case kCaldoria10:
     1262                if (direction == kEast && g_arthurChip)
     1263                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA42", kArthurCaldoriaReachedToilet);
     1264                break;
    10291265        case kCaldoria11:
    10301266                if (direction == kEast && !GameState.getCaldoriaSeenMessages())
    10311267                        loopCroppedMovie("Images/Caldoria/A11 Message Machine Loop", kCaldoria11MessageLoopLeft, kCaldoria11MessageLoopTop);
    void Caldoria::turnTo(const DirectionConstant direction) {  
    10511287                        closeCroppedMovie();
    10521288                break;
    10531289        case kCaldoria48:
    1054                 if (direction == kNorth && !GameState.getCaldoriaDoorBombed())
     1290                if (direction == kNorth && !GameState.getCaldoriaDoorBombed()) {
    10551291                        setCurrentActivation(kActivateRoofSlotEmpty);
     1292                        if (GameState.isTakenItemID(kCardBomb) && g_arthurChip)
     1293                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA12", kArthurCaldoriaRoofDoor);
     1294                }
    10561295                break;
    10571296        case kCaldoria53:
    10581297                if (GameState.getCurrentDirection() == kEast && !GameState.getCaldoriaSinclairShot())
    void Caldoria::zoomTo(const Hotspot *zoomOutSpot) {  
    10851324        // that doesn't involve the ClickInHotSpot function.
    10861325        _zoomOutSpot = zoomOutSpot;
    10871326
    1088         if (zoomOutSpot->getObjectID() == kCaldoriaDrawersOutSpotID) {
     1327        if (_vm->isDVD() && zoomOutSpot->getObjectID() == kCaldoriaReplicatorOutSpotID) {
     1328                GameState.setEasterEgg(false);
     1329                Neighborhood::zoomTo(zoomOutSpot);
     1330        } else if (zoomOutSpot->getObjectID() == kCaldoriaDrawersOutSpotID) {
    10891331                if (_privateFlags.getFlag(kCaloriaPrivateLeftDrawerOpenFlag)) {
    10901332                        _privateFlags.setFlag(kCaloriaPrivateLeftDrawerOpenFlag, false);
    10911333                        startExtraSequence(kLeftDrawerClose, kExtraCompletedFlag, kFilterNoInput);
    void Caldoria::zoomToSinclair() {  
    11221364        startExtraSequence(kCa53EastZoomToSinclair, kExtraCompletedFlag, kFilterAllInput);
    11231365}
    11241366
     1367void Caldoria::startExtraSequence(const ExtraID extraID, const NotificationFlags flags, const InputBits interruptionFilter) {
     1368        short left = kNavAreaLeft, top = kNavAreaTop;
     1369        DisplayOrder displayOrder = kNavMovieOrder + 1;
     1370        TimeValue segmentStart = 0, segmentStop = 0;
     1371        bool loopSequence = false;
     1372        Common::Rect pushBounds;
     1373        NotificationFlags extraFlags;
     1374
     1375        switch (extraID) {
     1376        case kCreateCornbread:
     1377        case kWashingMachineZoomIn:
     1378        case kWashingMachineLoop:
     1379        case kWashingMachineZoomOut:
     1380                _turnPush.getBounds(pushBounds);
     1381               
     1382                switch (extraID) {
     1383                case kCreateCornbread:
     1384                        _extraMovie.initFromMovieFile("Images/Caldoria/A12RC.movie");
     1385                        left = pushBounds.left;
     1386                        top = pushBounds.top;
     1387                        displayOrder = kNavMovieOrder + 1;
     1388                        segmentStart = 0;
     1389                        segmentStop = _extraMovie.getDuration();
     1390                        loopSequence = false;
     1391                        break;
     1392                case kWashingMachineZoomIn:
     1393                        _extraMovie.initFromMovieFile("Images/Caldoria/A11WAS.movie");
     1394                        left = pushBounds.left;
     1395                        top = pushBounds.top;
     1396                        displayOrder = kNavMovieOrder + 1;
     1397                        segmentStart = 0;
     1398                        segmentStop = 5480;
     1399                        loopSequence = false;
     1400                        break;
     1401                case kWashingMachineLoop:
     1402                        // The washing machine movie will already be loaded after zooming in
     1403                        left = pushBounds.left;
     1404                        top = pushBounds.top;
     1405                        displayOrder = kNavMovieOrder + 1;
     1406                        segmentStart = 5480;
     1407                        segmentStop = 9880;
     1408                        loopSequence = true;
     1409                        break;
     1410                case kWashingMachineZoomOut:
     1411                        // The washing machine movie will still be loaded after looping
     1412                        left = pushBounds.left;
     1413                        top = pushBounds.top;
     1414                        displayOrder = kNavMovieOrder + 1;
     1415                        segmentStart = 9880;
     1416                        segmentStop = 11200;
     1417                        loopSequence = false;
     1418                        break;
     1419                default:
     1420                        break;
     1421                }
     1422               
     1423                _lastExtra = extraID;
     1424                _turnPush.hide();
     1425               
     1426                if (!loopSequence && g_AIArea)
     1427                        g_AIArea->lockAIOut();
     1428               
     1429                extraFlags = flags;
     1430                _interruptionFilter = interruptionFilter;
     1431                // Stop the nav movie before doing anything else
     1432                _navMovie.stop();
     1433                _navMovie.stopDisplaying();
     1434               
     1435                _extraMovie.setVolume(_vm->getSoundFXLevel());
     1436                _extraMovie.moveElementTo(left, top);
     1437                _extraMovie.setDisplayOrder(displayOrder);
     1438                _extraMovie.startDisplaying();
     1439                _extraMovie.show();
     1440                _extraMovie.setFlags(0);
     1441                _extraMovie.setSegment(segmentStart, segmentStop);
     1442                _extraMovie.setTime(segmentStart);
     1443                if (loopSequence)
     1444                        _extraMovie.setFlags(kLoopTimeBase);
     1445                else
     1446                        extraFlags |= kNeighborhoodMovieCompletedFlag;
     1447                _extraMovieCallBack.cancelCallBack();
     1448                _extraMovieCallBack.initCallBack(&_extraMovie, kCallBackAtExtremes);
     1449                if (extraFlags != 0) {
     1450                        _extraMovieCallBack.setCallBackFlag(extraFlags);
     1451                        _extraMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     1452                }
     1453                _extraMovie.start();
     1454                break;
     1455        default:
     1456                Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
     1457                break;
     1458        }
     1459}
     1460
    11251461void Caldoria::receiveNotification(Notification *notification, const NotificationFlags flags) {
    11261462        Neighborhood::receiveNotification(notification, flags);
    11271463
    void Caldoria::receiveNotification(Notification *notification, const Notificatio  
    11581494                        }
    11591495                        break;
    11601496                case kCreateOrangeJuice:
     1497                        GameState.setCaldoriaMadeOJ(true);
    11611498                        setCurrentActivation(kActivateOJOnThePad);
    1162                         requestSpotSound(kCaldoriaReplicatorOJChoiceIn, kCaldoriaReplicatorOJChoiceOut, kFilterNoInput, 0);
     1499                        GameState.setEasterEgg(false);
     1500                        break;
     1501                case kCreateCornbread:
     1502                        _extraMovie.moveElementTo(0, 0);
     1503                        _vm->_gfx->setCurSurface(_navMovie.getSurface());
     1504                        _extraMovie.copyToCurrentPort();
     1505                        _vm->_gfx->setCurSurface(_vm->_gfx->getWorkArea());
     1506                        _extraMovie.stopDisplaying();
     1507                        _extraMovie.releaseMovie();
     1508                        _navMovie.startDisplaying();
     1509                        GameState.setEasterEgg(true);
     1510                        if (g_arthurChip)
     1511                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB39", kArthurCaldoriaCreatedCornbread);
     1512                        break;
     1513                case kWashingMachineZoomIn:
     1514                        _lookingAtLaundry = true;
     1515                        startExtraSequence(kWashingMachineLoop, kExtraCompletedFlag, kFilterAllInput);
     1516                        break;
     1517                case kWashingMachineZoomOut:
     1518                        _extraMovie.stopDisplaying();
     1519                        _extraMovie.releaseMovie();
     1520                        _navMovie.startDisplaying();
     1521                        _lookingAtLaundry = false;
    11631522                        break;
    11641523                case kCaldoria00SitDown:
    11651524                        arriveAt(kCaldoria00, kEast);
    void Caldoria::receiveNotification(Notification *notification, const Notificatio  
    12021561                case kCa48NorthExplosion:
    12031562                        // Current biochip must be the shield if we got here.
    12041563                        _vm->getCurrentBiochip()->setItemState(kShieldNormal);
     1564                        if (g_arthurChip) {
     1565                                if (_vm->getRandomBit())
     1566                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA41", kArthurCaldoriaBlownDoor);
     1567                                else
     1568                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB42", kArthurCaldoriaBlownDoor);
     1569                        }                                                               
    12051570                        break;
    12061571                case kBinocularsZoomInOnShip:
    12071572                        setCurrentActivation(kActivateFocusedOnShip);
     1573                        if (g_arthurChip)
     1574                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA03", kArthurCaldoriaLookThroughTelescope);
    12081575                        break;
    12091576                case kCa49NorthVoiceAnalysis:
    12101577                        _utilityFuse.primeFuse(kSinclairShootsTimeLimit);
    12111578                        _utilityFuse.setFunctor(new Common::Functor0Mem<void, Caldoria>(this, &Caldoria::sinclairTimerExpired));
    12121579                        _utilityFuse.lightFuse();
    12131580                        GameState.setCaldoriaSawVoiceAnalysis(true);
     1581                        if (_vm->isDVD() && g_AIArea)
     1582                                g_AIArea->checkRules();
     1583                        if (g_arthurChip)
     1584                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA20", kArthurCaldoriaSawVoiceAnalysis);
    12141585                        break;
    12151586                case kCa53EastZoomToSinclair:
    12161587                        if (GameState.getCaldoriaSinclairShot()) {
    void Caldoria::receiveNotification(Notification *notification, const Notificatio  
    12341605                }
    12351606        } else if ((flags & kSpotSoundCompletedFlag) != 0) {
    12361607                switch (GameState.getCurrentRoom()) {
     1608                case kCaldoria11:
     1609                        if (g_arthurChip)
     1610                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA46", kArthurCaldoriaZoomedToLaundry);
     1611                        break;
    12371612                case kCaldoria20:
    12381613                case kCaldoria21:
    12391614                case kCaldoria26:
    void Caldoria::receiveNotification(Notification *notification, const Notificatio  
    12411616                case kCaldoria34:
    12421617                case kCaldoria35:
    12431618                        updateViewFrame();
     1619                        if ((GameState.getCurrentRoom() == kCaldoria34 || GameState.getCurrentRoom() == kCaldoria35) && g_arthurChip)
     1620                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA44", kArthurCaldoriaSawVacantApartment);
    12441621                        break;
    12451622                case kCaldoria27:
    12461623                case kCaldoria28:
    void Caldoria::receiveNotification(Notification *notification, const Notificatio  
    12481625                        updateElevatorMovie();
    12491626                        break;
    12501627                case kCaldoriaReplicator:
    1251                         emptyOJGlass();
     1628                        if (_spotSounds.getStart() == kCaldoriaReplicatorWrongChoiceIn) {
     1629                                if (g_arthurChip)
     1630                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA16", kArthurCaldoriaSelectedStickyBuns);
     1631                        } else {
     1632                                emptyOJGlass();
     1633                                if (g_arthurChip)
     1634                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA45", kArthurCaldoriaDrankOJ);
     1635                        }
    12521636                        break;
    12531637                }
    12541638        } else if ((flags & kSinclairLoopDoneFlag) != 0) {
    void Caldoria::activateHotspots() {  
    13131697        case kCaldoriaReplicator:
    13141698                if (GameState.getCaldoriaMadeOJ())
    13151699                        _vm->getAllHotspots().deactivateOneHotspot(kCaldoriaMakeOJSpotID);
     1700                if (GameState.getEasterEgg())
     1701                        _vm->getAllHotspots().activateOneHotspot(kCaldoriaCornbreadHotSpotID);
     1702                break;
     1703        case kCaldoria11:
     1704                if (_vm->isDVD() && GameState.getCurrentDirection() == kWest) {
     1705                        if (_lookingAtLaundry)
     1706                                _vm->getAllHotspots().activateOneHotspot(kCaldoriaLaundryZoomOutHotSpotID);
     1707                        else
     1708                                _vm->getAllHotspots().activateOneHotspot(kCaldoriaLaundryZoomInHotSpotID);
     1709                }
    13161710                break;
    13171711        case kCaldoria27:
    13181712                if (GameState.isCurrentDoorOpen()) {
    void Caldoria::clickInHotspot(const Input &input, const Hotspot *spot) {  
    14051799                startExtraSequence(kRightDrawerCloseNoKeys, kExtraCompletedFlag, kFilterNoInput);
    14061800                break;
    14071801        case kCaldoriaMakeStickyBunsSpotID:
    1408                 requestSpotSound(kCaldoriaReplicatorWrongChoiceIn, kCaldoriaReplicatorWrongChoiceOut, kFilterNoInput, 0);
     1802                requestSpotSound(kCaldoriaReplicatorWrongChoiceIn, kCaldoriaReplicatorWrongChoiceOut, kFilterNoInput, kSpotSoundCompletedFlag);
    14091803                break;
    14101804        case kCaldoriaMakeOJSpotID:
    1411                 GameState.setCaldoriaMadeOJ(true);
    1412                 startExtraSequence(kCreateOrangeJuice, kExtraCompletedFlag, kFilterNoInput);
     1805                if (_vm->isDVD() && JMPPPInput::isEasterEggModifierInput(input)) {
     1806                        startExtraSequence(kCreateCornbread, kExtraCompletedFlag, kFilterNoInput);
     1807                } else {
     1808                        requestSpotSound(kCaldoriaReplicatorOJChoiceIn, kCaldoriaReplicatorOJChoiceOut, kFilterNoInput, 0);
     1809                        requestExtraSequence(kCreateOrangeJuice, kExtraCompletedFlag, kFilterNoInput);
     1810                }
     1811                break;
     1812        case kCaldoriaCornbreadHotSpotID:
     1813                doArthurJoyride();
     1814                break;
     1815        case kCaldoriaLaundryZoomInHotSpotID:
     1816                if (_vm->isDVD()) {
     1817                        startExtraSequence(kWashingMachineZoomIn, kExtraCompletedFlag, kFilterNoInput);
     1818                        requestDelay(30, 10, kFilterNoInput, kDelayCompletedFlag);
     1819                        requestSpotSound(kCaldoriaLaundryIntro1In, kCaldoriaLaundryIntro2Out, kFilterNoInput, kSpotSoundCompletedFlag);
     1820                }
     1821                break;
     1822        case kCaldoriaLaundryZoomOutHotSpotID:
     1823                startExtraSequence(kWashingMachineZoomOut, kExtraCompletedFlag, kFilterNoInput);
    14131824                break;
    14141825        case kCaBedroomVidPhoneActivationSpotID:
    14151826                newInteraction(kCaldoriaMessagesInteractionID);
    void Caldoria::clickInHotspot(const Input &input, const Hotspot *spot) {  
    14911902
    14921903void Caldoria::clickOnDoorbell(const HotSpotID doorBellSpotID) {
    14931904        uint32 extra;
     1905        Sound doorbellSound;
    14941906        ExtraTable::Entry entry;
     1907        Input input;
    14951908
    14961909        switch (doorBellSpotID) {
    14971910        case kCaldoria20DoorbellSpotID:
     1911                if (_vm->isDVD())
     1912                        doorbellSound.initFromAIFFFile("Sounds/Caldoria/AH5.AIFF");
    14981913                extra = kCaldoria20Doorbell;
    14991914                break;
    15001915        case kCaldoria21DoorbellSpotID:
     1916                if (_vm->isDVD())
     1917                        doorbellSound.initFromAIFFFile("Sounds/Caldoria/AH4.AIFF");
    15011918                extra = kCaldoria21Doorbell;
    15021919                break;
    15031920        case kCaldoria26DoorbellSpotID:
     1921                if (_vm->isDVD())
     1922                        doorbellSound.initFromAIFFFile("Sounds/Caldoria/AH3.AIFF");
    15041923                extra = kCaldoria26Doorbell;
    15051924                break;
    15061925        case kCaldoria29DoorbellSpotID:
     1926                if (_vm->isDVD())
     1927                        doorbellSound.initFromAIFFFile("Sounds/Caldoria/AH1.AIFF");
    15071928                extra = kCaldoria29Doorbell;
    15081929                break;
    15091930        case kCaldoria34DoorbellSpotID:
    void Caldoria::clickOnDoorbell(const HotSpotID doorBellSpotID) {  
    15181939
    15191940        getExtraEntry(extra, entry);
    15201941        showViewFrame(entry.movieStart);
    1521         requestSpotSound(kCaldoriaNobodyHomeIn, kCaldoriaNobodyHomeOut, kFilterNoInput, kSpotSoundCompletedFlag);
     1942        if (_vm->isDVD() && doorBellSpotID != kCaldoria34DoorbellSpotID && doorBellSpotID != kCaldoria35DoorbellSpotID) {
     1943                _vm->_cursor->hide();
     1944                doorbellSound.setVolume(_vm->getSoundFXLevel());
     1945                doorbellSound.playSound();
     1946                while (doorbellSound.isPlaying() && !_vm->shouldQuit()) {
     1947                        InputDevice.getInput(input, kFilterNoInput);
     1948
     1949                        _vm->checkCallBacks();
     1950                        _vm->refreshDisplay();
     1951                        _vm->_system->delayMillis(10);
     1952                }
     1953                if (_vm->shouldQuit())
     1954                        return;
     1955                _vm->_cursor->hideUntilMoved();
     1956                updateViewFrame();
     1957        } else {
     1958                requestSpotSound(kCaldoriaNobodyHomeIn, kCaldoriaNobodyHomeOut, kFilterNoInput, kSpotSoundCompletedFlag);
     1959        }
     1960}
     1961
     1962void Caldoria::cantMoveThatWay(CanOpenDoorReason reason) {
     1963        switch (reason) {
     1964        case kCantMoveDoorClosed:
     1965        case kCantMoveDoorLocked:
     1966                openDoor();
     1967                break;
     1968        case kCantMoveBlocked:
     1969                switch (GameState.getCurrentRoomAndView()) {
     1970                case MakeRoomView(kCaldoria20, kWest):
     1971                case MakeRoomView(kCaldoria21, kEast):
     1972                case MakeRoomView(kCaldoria26, kSouth):
     1973                case MakeRoomView(kCaldoria29, kSouth):
     1974                case MakeRoomView(kCaldoria34, kWest):
     1975                case MakeRoomView(kCaldoria35, kEast):
     1976                        cantOpenDoor(kCantOpenLocked);
     1977                        break;
     1978                default:
     1979                        zoomUpOrBump();
     1980                        break;
     1981                }
     1982                break;
     1983        default:
     1984                bumpIntoWall();
     1985                break;
     1986        }
    15221987}
    15231988
    15241989CanOpenDoorReason Caldoria::canOpenDoor(DoorTable::Entry &entry) {
    void Caldoria::pickedUpItem(Item *item) {  
    16062071}
    16072072
    16082073void Caldoria::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {
     2074        Input input;
     2075        Sound cardBombVoice;
     2076
    16092077        switch (item->getObjectID()) {
    16102078        case kKeyCard:
    16112079                Neighborhood::dropItemIntoRoom(item, dropSpot);
    void Caldoria::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {  
    16292097                _utilityFuse.lightFuse();
    16302098                GameState.setCaldoriaFuseTimeLimit(kCardBombCountDownTime);
    16312099                loopCroppedMovie("Images/Caldoria/A48 Bomb Loop", kCaldoria48CardBombLoopLeft, kCaldoria48CardBombLoopTop);
     2100                if (_vm->isDVD()) {
     2101                        InputDevice.getInput(input, kFilterAllInput);
     2102                        if (JMPPPInput::isEasterEggModifierInput(input))
     2103                                cardBombVoice.initFromAIFFFile("Sounds/Caldoria/Card Bomb.Geno.aiff");
     2104                        else
     2105                                cardBombVoice.initFromAIFFFile("Sounds/Caldoria/Card Bomb.44K.aiff");
     2106                        cardBombVoice.playSound();
     2107                        while (cardBombVoice.isPlaying() && !_vm->shouldQuit()) {
     2108                                InputDevice.getInput(input, kFilterNoInput);
     2109
     2110                                _vm->checkCallBacks();
     2111                                _vm->refreshDisplay();
     2112                                _vm->_system->delayMillis(10);
     2113                        }
     2114                        if (_vm->shouldQuit())
     2115                                return;
     2116                }
    16322117                GameState.setScoringUsedCardBomb(true);
     2118                if (g_arthurChip)
     2119                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA19", kArthurCaldoriaUsedCardBomb);
    16332120                break;
    16342121        case kStunGun:
    16352122                GameState.setCaldoriaGunAimed(true);
    void Caldoria::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {  
    16402127                _gunSprite->moveElementTo(kCaldoriaGunSpriteLeft, kCaldoriaGunSpriteTop);
    16412128                _gunSprite->startDisplaying();
    16422129                _gunSprite->show();
     2130                if (g_arthurChip)
     2131                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA17", kArthurCaldoriaStunningSinclair);
    16432132                break;
    16442133        default:
    16452134                Neighborhood::dropItemIntoRoom(item, dropSpot);
    void Caldoria::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {  
    16472136        }
    16482137}
    16492138
     2139void Caldoria::playMissingFloorSound() {
     2140        Input input;
     2141        Sound elevatorVoice;
     2142
     2143        InputDevice.getInput(input, kFilterAllInput);
     2144        if (_vm->isDVD() && JMPPPInput::isEasterEggModifierInput(input)) {
     2145                _vm->_cursor->hide();
     2146                elevatorVoice.initFromAIFFFile("Sounds/Caldoria/Elevator Denied.32K.aiff");
     2147                elevatorVoice.setVolume(_vm->getSoundFXLevel());
     2148                elevatorVoice.playSound();
     2149                while (elevatorVoice.isPlaying() && !_vm->shouldQuit()) {
     2150                        InputDevice.getInput(input, kFilterNoInput);
     2151
     2152                        _vm->checkCallBacks();
     2153                        _vm->refreshDisplay();
     2154                        _vm->_system->delayMillis(10);
     2155                }
     2156                if (_vm->shouldQuit())
     2157                        return;
     2158                _vm->_cursor->hideUntilMoved();
     2159                updateElevatorMovie();
     2160        } else {
     2161                requestSpotSound(kCaldoriaNoOtherFloorIn,
     2162                                                        kCaldoriaNoOtherFloorOut,
     2163                                                        kFilterNoInput,
     2164                                                        kSpotSoundCompletedFlag);
     2165        }
     2166}
     2167
    16502168void Caldoria::takeElevator(uint startFloor, uint endFloor) {
    16512169        _croppedMovie.stop();
    16522170        _croppedMovie.setSegment(0, _croppedMovie.getDuration());
    void Caldoria::takeElevator(uint startFloor, uint endFloor) {  
    16602178                case 2:
    16612179                        _croppedMovie.setTime(k1To2Time);
    16622180                        _croppedMovie.redrawMovieWorld();
    1663                         requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag);
     2181                        playMissingFloorSound();
    16642182                        break;
    16652183                case 3:
    16662184                        _croppedMovie.setTime(k1To3Time);
    16672185                        _croppedMovie.redrawMovieWorld();
    1668                         requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag);
     2186                        playMissingFloorSound();
    16692187                        break;
    16702188                case 4:
    16712189                        _croppedMovie.setSegment(k1To4Start, k1To4Stop);
    void Caldoria::takeElevator(uint startFloor, uint endFloor) {  
    16922210                case 2:
    16932211                        _croppedMovie.setTime(k4To2Time);
    16942212                        _croppedMovie.redrawMovieWorld();
    1695                         requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag);
     2213                        playMissingFloorSound();
    16962214                        break;
    16972215                case 3:
    16982216                        _croppedMovie.setTime(k4To3Time);
    16992217                        _croppedMovie.redrawMovieWorld();
    1700                         requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag);
     2218                        playMissingFloorSound();
    17012219                        break;
    17022220                case 4:
    17032221                        // Do nothing.
    void Caldoria::takeElevator(uint startFloor, uint endFloor) {  
    17212239                case 2:
    17222240                        _croppedMovie.setTime(k5To2Time);
    17232241                        _croppedMovie.redrawMovieWorld();
    1724                         requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag);
     2242                        playMissingFloorSound();
    17252243                        break;
    17262244                case 3:
    17272245                        _croppedMovie.setTime(k5To3Time);
    17282246                        _croppedMovie.redrawMovieWorld();
    1729                         requestSpotSound(kCaldoriaNoOtherDestinationIn, kCaldoriaNoOtherDestinationOut, kFilterNoInput, kSpotSoundCompletedFlag);
     2247                        playMissingFloorSound();
    17302248                        break;
    17312249                case 4:
    17322250                        _croppedMovie.setSegment(k5To4Start, k5To4Stop);
    Common::String Caldoria::getSoundSpotsName() {  
    19842502        return "Sounds/Caldoria/Caldoria Spots";
    19852503}
    19862504
     2505void Caldoria::doArthurJoyride() {
     2506        Video::VideoDecoder *video = 0;
     2507        BiochipItem *item;
     2508
     2509        setNextHandler(_vm);
     2510        throwAwayInterface();
     2511        loadLoopSound1("");
     2512
     2513        _vm->_cursor->hide();
     2514
     2515#ifdef USE_THEORADEC
     2516        video = new Video::TheoraDecoder();
     2517        if (!video->loadFile("Images/Caldoria/A12RD.ogg")) {
     2518                delete video;
     2519                video = 0;
     2520        }
     2521#endif
     2522
     2523        if (!video) {
     2524                video = new Video::QuickTimeDecoder();
     2525                if (!video->loadFile("Images/Caldoria/A12RD.movie"))
     2526                        error("Could not load joyride video");
     2527        }
     2528
     2529        video->setVolume(MIN<uint>(_vm->getSoundFXLevel(), 0xFF));
     2530        video->start();
     2531
     2532        while (!_vm->shouldQuit() && !video->endOfVideo()) {
     2533                if (video->needsUpdate()) {
     2534                        const Graphics::Surface *frame = video->decodeNextFrame();
     2535
     2536                        if (frame) {
     2537                                g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
     2538                                g_system->updateScreen();
     2539                        }
     2540                }
     2541
     2542                Common::Event event;
     2543                while (g_system->getEventManager()->pollEvent(event))
     2544                        ;
     2545
     2546                g_system->delayMillis(10);
     2547        }
     2548
     2549        delete video;
     2550
     2551        if (_vm->shouldQuit())
     2552                return;
     2553
     2554        reinstateMonocleInterface();
     2555        loadAmbientLoops();
     2556        updateViewFrame();
     2557        if (!_vm->playerHasItemID(kArthurBiochip)) {
     2558                item = (BiochipItem *)_vm->getAllItems().findItemByID(kArthurBiochip);
     2559                _vm->addItemToBiochips(item);
     2560                if (g_arthurChip)
     2561                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA06", kArthurCaldoriaFinishedJoyride);
     2562        }
     2563        g_interface->setCurrentBiochipID(kArthurBiochip);
     2564        GameState.setEasterEgg(false);
     2565}
     2566
    19872567} // End of namespace Pegasus
  • engines/pegasus/neighborhood/caldoria/caldoria.h

    diff --git a/engines/pegasus/neighborhood/caldoria/caldoria.h b/engines/pegasus/neighborhood/caldoria/caldoria.h
    index 3d6a155..982789f 100644
    a b static const HotSpotID kCaldoriaRoofElevatorSpotID = 5065;  
    195195static const HotSpotID kCaldoriaRoofDoorSpotID = 5066;
    196196static const HotSpotID kCaldoriaRoofCardDropSpotID = 5067;
    197197static const HotSpotID kCaldoria53EastSinclairTargetSpotID = 5068;
     198static const HotSpotID kCaldoriaCornbread = 5069;
    198199
    199200// Extra sequence IDs.
    200201
    static const DisplayElementID kCaldoriaUtilityID = kCaldoriaMessagesID + 1;  
    383384static const DisplayElementID kCaldoriaBombGridID = kCaldoriaUtilityID + 1;
    384385static const DisplayElementID kCaldoriaBombTimerID = kCaldoriaBombGridID + 1;
    385386
     387static const TimeValue kCaldoria4DInstructionsIn = 28013;
     388static const TimeValue kCaldoria4DInstructionsOut = 29730;
     389
    386390static const TimeValue kCaldoria4DBlankChoiceIn = 29730;
    387391static const TimeValue kCaldoria4DBlankChoiceOut = 33910;
    388392
    protected:  
    445449
    446450        void init();
    447451        void start();
     452        void throwAwayInterface();
    448453
    449454        void setUpRoofTop();
    450455
    protected:  
    472477        void arriveAtCaldoriaDeath();
    473478        void turnTo(const DirectionConstant);
    474479        void zoomTo(const Hotspot *);
     480        void leftButton(const Input &);
     481        void rightButton(const Input &);
    475482        void downButton(const Input &);
     483        void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits);
    476484        void receiveNotification(Notification *, const NotificationFlags);
    477485        InputBits getInputFilter();
    478486        void activateHotspots();
    protected:  
    483491
    484492        Hotspot *getItemScreenSpot(Item *, DisplayElement *);
    485493        void dropItemIntoRoom(Item *, Hotspot *);
     494        void playMissingFloorSound();
    486495        void takeElevator(uint, uint);
    487496        void updateElevatorMovie();
    488497        void openElevatorMovie();
    protected:  
    495504        void zoomToSinclair();
    496505        void playEndMessage();
    497506        void checkInterruptSinclair();
     507        void doArthurJoyride();
    498508
     509        void cantMoveThatWay(CanMoveForwardReason);
    499510        CanOpenDoorReason canOpenDoor(DoorTable::Entry &);
    500511        void doorOpened();
    501512
    protected:  
    505516
    506517        const Hotspot *_zoomOutSpot;
    507518
     519        Hotspot _laundryZoomInSpot;
     520        Hotspot _laundryZoomOutSpot;
     521        Hotspot _cornbreadSpot;
     522
     523        Movie _extraMovie;
     524        NotificationCallBack _extraMovieCallBack;
     525
     526        bool _lookingAtLaundry;
     527
    508528        FuseFunction _utilityFuse;
    509529
    510530        long _sinclairLoopCount;
  • engines/pegasus/neighborhood/caldoria/caldoria4dsystem.cpp

    diff --git a/engines/pegasus/neighborhood/caldoria/caldoria4dsystem.cpp b/engines/pegasus/neighborhood/caldoria/caldoria4dsystem.cpp
    index 0494753..a4b0276 100644
    a b void Caldoria4DSystem::useIdleTime() {  
    210210void Caldoria4DSystem::initInteraction() {
    211211        setSpritesMovie();
    212212
    213         _owner->loadLoopSound1("Sounds/Caldoria/Rock.aiff");
     213        playSound("Rock");
     214        _owner->playSpotSoundSync(kCaldoria4DInstructionsIn, kCaldoria4DInstructionsOut);
    214215        loopExtra(k4DIslandLoop);
    215216}
    216217
    void Caldoria4DSystem::handleInput(const Input &input, const Hotspot *cursorSpot  
    243244
    244245void Caldoria4DSystem::activateHotspots() {
    245246        GameInteraction::activateHotspots();
    246         if (_whichMenu == k4DAudioMenu)
    247                 g_allHotspots.activateOneHotspot(kCa4DChoice4SpotID);
     247        g_allHotspots.activateOneHotspot(kCa4DChoice4SpotID);
    248248}
    249249
    250250void Caldoria4DSystem::clickInHotspot(const Input &input, const Hotspot *spot) {
    void Caldoria4DSystem::makeRockChoice() {  
    335335        if (_audioChoice != k4DRockChoice) {
    336336                _audioChoice = k4DRockChoice;
    337337                setSpritesMovie();
    338                 _owner->loadLoopSound1("Sounds/Caldoria/Rock.aiff");
     338                playSound("Rock");
    339339        }
    340340}
    341341
    void Caldoria4DSystem::makeOrchestralChoice() {  
    343343        if (_audioChoice != k4DOrchestralChoice) {
    344344                _audioChoice = k4DOrchestralChoice;
    345345                setSpritesMovie();
    346                 _owner->loadLoopSound1("Sounds/Caldoria/Orchestral.aiff");
     346                playSound("Orchestral");
    347347        }
    348348}
    349349
    void Caldoria4DSystem::makeRhythmsChoice() {  
    351351        if (_audioChoice != k4DRhythmsChoice) {
    352352                _audioChoice = k4DRhythmsChoice;
    353353                setSpritesMovie();
    354                 _owner->loadLoopSound1("Sounds/Caldoria/Rhythms.aiff");
     354                playSound("Rhythms");
    355355        }
    356356}
    357357
    void Caldoria4DSystem::makeAcousticChoice() {  
    359359        if (_audioChoice != k4DAcousticChoice) {
    360360                _audioChoice = k4DAcousticChoice;
    361361                setSpritesMovie();
    362                 _owner->loadLoopSound1("Sounds/Caldoria/Acoustic.aiff");
     362                playSound("Acoustic");
    363363        }
    364364}
    365365
    void Caldoria4DSystem::shutDown4DSystem() {  
    367367        _whichMenu = k4DShuttingDown;
    368368}
    369369
     370void Caldoria4DSystem::playSound(const Common::String &baseFileName) {
     371        Common::String fileName = "Sounds/Caldoria/" + baseFileName;
     372
     373        // Updated DVD files
     374        if (((PegasusEngine *)g_engine)->isDVD())
     375                fileName += ".44K";
     376
     377        _owner->loadLoopSound1(fileName + ".aiff");
     378}
     379
    370380} // End of namespace Pegasus
  • engines/pegasus/neighborhood/caldoria/caldoria4dsystem.h

    diff --git a/engines/pegasus/neighborhood/caldoria/caldoria4dsystem.h b/engines/pegasus/neighborhood/caldoria/caldoria4dsystem.h
    index 1c5fa44..0d57d7c 100644
    a b protected:  
    6363        void useIdleTime();
    6464        void loopExtra(const ExtraID);
    6565
     66        void playSound(const Common::String &baseFileName);
     67
    6668        Movie _4DSpritesMovie;
    6769        TimeScale _4DSpritesScale;
    6870        uint _whichMenu;
  • engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp

    diff --git a/engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp b/engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp
    index abf34d3..adfd77d 100644
    a b  
    2525
    2626#include "pegasus/gamestate.h"
    2727#include "pegasus/pegasus.h"
     28#include "pegasus/items/biochips/arthurchip.h"
    2829#include "pegasus/neighborhood/caldoria/caldoria.h"
    2930#include "pegasus/neighborhood/caldoria/caldoriabomb.h"
    3031
    static const uint32 kOnTime3 = kOffTime2 + kFlashOnTime;  
    4849static const uint32 kOffTime3 = kOnTime3 + kFlashOffTime;
    4950static const uint32 kOnTime4 = kOffTime3 + kFlashOnTime;
    5051
    51 static const HotSpotID kVertextHotSpotBaseID = 10000;
     52// Bomb hotspots start at 20000 since the extra Caldoria hotspots start at 10000.
     53// Assigning these vice versa causes a hotspot in level 4 to never activate for some reason.
     54static const HotSpotID kVertextHotSpotBaseID = 20000;
    5255
    5356static const CoordType kVertextHotSpotWidth = 24;
    5457static const CoordType kVertextHotSpotHeight = 24;
    void CaldoriaBomb::receiveNotification(Notification *notification, const Notific  
    12351238                        _currentLevel = 0;
    12361239                        _lastVertex = -1;
    12371240                        startBombAmbient("Sounds/Caldoria/BmbLoop1.22K.AIFF");
     1241                        if (g_arthurChip) {
     1242                                if (((PegasusEngine *)g_engine)->getRandomBit())
     1243                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA14", kArthurCaldoriaSeeRoofBomb);
     1244                                else
     1245                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB28", kArthurCaldoriaSeeRoofBomb);
     1246                        }
    12381247                        break;
    12391248                case kCaldoria56BombStage2:
    12401249                case kCaldoria56BombStage3:
    void CaldoriaBomb::handleInput(const Input &input, const Hotspot *hotspot) {  
    14121421                                _grid.hide();
    14131422                                _timer.hide();
    14141423                                _owner->startExtraSequence(kCaldoria56BombStage7, kExtraCompletedFlag, kFilterNoInput);
     1424                                if (g_arthurChip)
     1425                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA02", kArthurCaldoriaDisarmedNuke);
    14151426                                break;
    14161427                        }
    14171428                }
  • engines/pegasus/neighborhood/caldoria/caldoriamirror.cpp

    diff --git a/engines/pegasus/neighborhood/caldoria/caldoriamirror.cpp b/engines/pegasus/neighborhood/caldoria/caldoriamirror.cpp
    index ff4d181..9f487cb 100644
    a b  
    2525
    2626#include "pegasus/gamestate.h"
    2727#include "pegasus/pegasus.h"
     28#include "pegasus/items/biochips/arthurchip.h"
    2829#include "pegasus/neighborhood/neighborhood.h"
    2930#include "pegasus/neighborhood/caldoria/caldoria.h"
    3031#include "pegasus/neighborhood/caldoria/caldoriamirror.h"
    void CaldoriaMirror::openInteraction() {  
    4243void CaldoriaMirror::initInteraction() {
    4344        _owner->setCurrentActivation(kActivateMirrorReady);
    4445        _owner->startExtraSequence(kCaBathroomGreeting, kExtraCompletedFlag, kFilterNoInput);
     46        // The original made the player click to start each of the following sequences,
     47        // which was unnecessary, so it is automated here.
     48        _owner->startExtraSequenceSync(kCaBathroomGreeting, kFilterNoInput);
     49        _owner->startExtraSequenceSync(kCaBathroomBodyFat, kFilterNoInput);
     50        _owner->startExtraSequence(kCaBathroomStylistIntro, kExtraCompletedFlag, kFilterNoInput);
    4551}
    4652
    4753void CaldoriaMirror::closeInteraction() {
    void CaldoriaMirror::activateHotspots() {  
    7985
    8086void CaldoriaMirror::clickInHotspot(const Input &input, const Hotspot *spot) {
    8187        switch (spot->getObjectID()) {
    82         case kCaBathroomMirrorSpotID:
    83                 switch (_owner->getLastExtra()) {
    84                 case kCaBathroomGreeting:
    85                         _owner->startExtraSequence(kCaBathroomBodyFat, kExtraCompletedFlag, kFilterNoInput);
    86                         break;
    87                 case kCaBathroomBodyFat:
    88                         _owner->startExtraSequence(kCaBathroomStylistIntro, kExtraCompletedFlag, kFilterNoInput);
    89                         break;
    90                 case kCaBathroomRetrothrash:
    91                         _owner->startExtraSequence(kCaBathroomRetrothrashReturn, kExtraCompletedFlag, kFilterNoInput);
    92                         break;
    93                 case kCaBathroomGeoWave:
    94                         _owner->startExtraSequence(kCaBathroomGeoWaveReturn, kExtraCompletedFlag, kFilterNoInput);
    95                         break;
    96                 }
    97                 break;
     88        // The original made the player click through several interstitial screens before
     89        // reaching the hairstyle menu, which was unnecessary, so it's skipped here.
    9890        case kCaHairStyle1SpotID:
    99                 _owner->startExtraSequence(kCaBathroomRetrothrash, kExtraCompletedFlag, kFilterNoInput);
     91                _owner->startExtraSequenceSync(kCaBathroomRetrothrash, kFilterNoInput);
     92                _owner->startExtraSequence(kCaBathroomRetrothrashReturn, kExtraCompletedFlag, kFilterNoInput);
    10093                break;
    10194        case kCaHairStyle2SpotID:
    10295                _owner->startExtraSequence(kCaBathroomAgencyStandard, kExtraCompletedFlag, kFilterNoInput);
    10396                break;
    10497        case kCaHairStyle3SpotID:
    105                 _owner->startExtraSequence(kCaBathroomGeoWave, kExtraCompletedFlag, kFilterNoInput);
     98                _owner->startExtraSequenceSync(kCaBathroomGeoWave, kFilterNoInput);
     99                _owner->startExtraSequence(kCaBathroomGeoWaveReturn, kExtraCompletedFlag, kFilterNoInput);
    106100                break;
    107101        default:
    108102                GameInteraction::clickInHotspot(input, spot);
    void CaldoriaMirror::receiveNotification(Notification *, const NotificationFlags  
    126120                _owner->requestDeleteCurrentInteraction();
    127121                GameState.setScoringFixedHair(true);
    128122                GameState.setCaldoriaDoneHygiene(true);
     123                if (g_arthurChip)
     124                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA43", kArthurCaldoriaChoseAgencyHairStyle);
    129125                break;
    130126        }
    131 
    132         allowInput(true);
    133127}
    134128
    135129} // End of namespace Pegasus
  • new file engines/pegasus/neighborhood/mars/canyonchase.cpp

    diff --git a/engines/pegasus/neighborhood/mars/canyonchase.cpp b/engines/pegasus/neighborhood/mars/canyonchase.cpp
    new file mode 100644
    index 0000000..4435998
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#include "pegasus/pegasus.h"
     27#include "pegasus/neighborhood/mars/canyonchase.h"
     28#include "pegasus/neighborhood/mars/mars.h"
     29
     30namespace Pegasus {
     31
     32// Segment start and end points.
     33
     34static const TimeValue kPrepStart = 0;
     35static const TimeValue kPrepEnd = 3000;
     36static const TimeValue kLaunchStart = kPrepEnd;
     37static const TimeValue kLaunchEnd = 6640;
     38static const TimeValue kBranch1Start = kLaunchEnd;
     39static const TimeValue kBranch1End = 22240;
     40static const TimeValue kBranch2Start = kBranch1End;
     41static const TimeValue kBranch2End = 28440;
     42static const TimeValue kBranch3Start = kBranch2End;
     43static const TimeValue kBranch3End = 38640;
     44static const TimeValue kBranch4Start = kBranch3End;
     45static const TimeValue kBranch4End = 43880;
     46static const TimeValue kBranch5Start = kBranch4End;
     47static const TimeValue kBranch5End = 58680;
     48static const TimeValue kExitStart = kBranch5End;
     49static const TimeValue kExitEnd = 66480;
     50static const TimeValue kExitLoopPoint = 66200;
     51static const TimeValue kExitGenoPoint = 62560;
     52
     53// Death start and end points.
     54
     55static const TimeValue kDeath1Start = 0;
     56static const TimeValue kDeath1End = 2400;
     57static const TimeValue kDeath2Start = kDeath1End;
     58static const TimeValue kDeath2End = 4720;
     59static const TimeValue kDeath3Start = kDeath2End;
     60static const TimeValue kDeath3End = 7120;
     61static const TimeValue kDeath4Start = kDeath3End;
     62static const TimeValue kDeath4End = 9280;
     63static const TimeValue kDeath5Start = kDeath4End;
     64static const TimeValue kDeath5End = 12000;
     65
     66// Chase state.
     67
     68enum {
     69        kCanyonLaunch,
     70        kCanyonBranch1Left,
     71        kCanyonBranch1Right,
     72        kCanyonBranch2Left,
     73        kCanyonBranch2Right,
     74        kCanyonBranch3Left,
     75        kCanyonBranch4Left,
     76        kCanyonBranch4Right,
     77        kCanyonBranch5Left,
     78        kCanyonBranch5Right,
     79        kCanyonExit,
     80        kCanyonLoop
     81};
     82
     83void MusicTimerEvent::fire() {
     84        canyonChase->musicTimerExpired(*this);
     85}
     86
     87CanyonChase::CanyonChase(Neighborhood *handler) : ChaseInteraction(kMarsCanyonChaseInteractionID, handler,
     88                                                        kMarsCanyonChaseNotificationID, (PegasusEngine *)g_engine), _canyonMovie1(kNoDisplayElement),
     89                                                        _canyonMovie2(kNoDisplayElement), _deathMovie(kNoDisplayElement), _genoMovie(kNoDisplayElement) {
     90        _currentMovie = NULL;
     91        _currentCallBack = NULL;
     92}
     93
     94void CanyonChase::startCanyonMusicLoop(void) {
     95        FaderMoveSpec spec;
     96
     97        _musicLoop.loopSound();
     98        spec.makeTwoKnotFaderSpec(10, 0, 0, 1, 255);
     99        _musicFader.startFader(spec);
     100}
     101
     102void CanyonChase::stopCanyonMusicLoop(const long ticks) {
     103        FaderMoveSpec spec;
     104
     105        spec.makeTwoKnotFaderSpec(10, 0, 255, ticks, 0);
     106        _musicFader.startFader(spec);
     107}
     108
     109void CanyonChase::openInteraction() {   
     110        _canyonMovie1.initFromMovieFile("Images/Mars/Canyon_hq1.mov");
     111        _canyonMovie1.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     112        _canyonMovie1.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
     113        _canyonMovie1.setDisplayOrder(kShuttleMonitorOrder);
     114
     115        _canyon1CallBack.setNotification(&_chaseNotification);
     116        _canyon1CallBack.initCallBack(&_canyonMovie1, kCallBackAtExtremes);
     117        _canyon1CallBack.setCallBackFlag(kChaseEnteredBranchZone);
     118        _canyon1CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     119
     120        _canyonMovie2.initFromMovieFile("Images/Mars/Canyon_hq2.mov");
     121        _canyonMovie2.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     122        _canyonMovie2.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
     123        _canyonMovie2.setDisplayOrder(kShuttleMonitorOrder);
     124
     125        _canyon2CallBack.setNotification(&_chaseNotification);
     126        _canyon2CallBack.initCallBack(&_canyonMovie2, kCallBackAtExtremes);
     127        _canyon2CallBack.setCallBackFlag(kChaseEnteredBranchZone);
     128        _canyon2CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     129
     130        _deathMovie.initFromMovieFile("Images/Mars/Canyon_hqD.mov");
     131        _deathMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     132        _deathMovie.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
     133        _deathMovie.setDisplayOrder(kShuttleMonitorOrder);
     134
     135        _deathCallBack.setNotification(&_chaseNotification);
     136        _deathCallBack.initCallBack(&_deathMovie, kCallBackAtExtremes);
     137        _deathCallBack.setCallBackFlag(kChaseFinished);
     138        _deathCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     139
     140        _musicLoop.attachFader(&_musicFader);
     141        _musicLoop.initFromAIFFFile("Sounds/Mars/Canyon Loop.44K.16.AIFF");
     142        _musicFader.setMasterVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     143
     144        ChaseInteraction::openInteraction();
     145
     146        _steerPict.setDisplayOrder(kShuttleMonitorOrder + 1);
     147        _steerPict.moveElementTo(kShuttleSteerLeft, kShuttleSteerTop);
     148}
     149
     150void CanyonChase::initInteraction() {
     151        _steerPict.startDisplaying();
     152
     153        // Launch branch is identical in both movies
     154        _canyonState = kCanyonLaunch;
     155        _canyonMovie1.setSegment(kLaunchStart, kLaunchEnd - kDecisionTime);
     156        _canyonMovie1.setTime(kLaunchStart);
     157        switchTo(_canyonMovie1, _canyon1CallBack);
     158        startCanyonMusicLoop();
     159        ChaseInteraction::initInteraction();
     160}
     161
     162void CanyonChase::closeInteraction() {
     163        _canyonMovie1.stop();
     164        _canyonMovie1.stopDisplaying();
     165        _canyonMovie1.releaseMovie();
     166        _canyon1CallBack.releaseCallBack();
     167
     168        _canyonMovie2.stop();
     169        _canyonMovie2.stopDisplaying();
     170        _canyonMovie2.releaseMovie();
     171        _canyon2CallBack.releaseCallBack();
     172
     173        _deathMovie.stop();
     174        _deathMovie.stopDisplaying();
     175        _deathMovie.releaseMovie();
     176        _deathCallBack.releaseCallBack();
     177
     178        _genoMovie.stop();
     179        _genoMovie.stopDisplaying();
     180        _genoMovie.releaseMovie();
     181        _genoCallBack.releaseCallBack();
     182
     183        ChaseInteraction::closeInteraction();
     184}
     185
     186void CanyonChase::receiveNotification(Notification *notification, const NotificationFlags flags) {
     187        Input input;
     188
     189        if (notification == &_chaseNotification && flags == kChaseFinished) {
     190                if (_canyonState == kCanyonLoop) {
     191                        // Swallow the notification if we loop back to the beginning
     192                        InputDevice.getInput(input, kFilterAllInput);
     193                        if (JMPPPInput::isEasterEggModifierInput(input)) {
     194                                stopCanyonMusicLoop(15);
     195                                doGenoChase();
     196                        } else {
     197                                _canyonMovie2.setSegment(kExitGenoPoint, kExitLoopPoint - kDecisionTime);
     198                                _canyonMovie2.setTime(kExitGenoPoint);
     199                                switchTo(_canyonMovie2, _canyon2CallBack);
     200                                _canyon2CallBack.setCallBackFlag(kChaseEnteredBranchZone);
     201                                _canyon2CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     202                                _canyonState = kCanyonLaunch;
     203                        }
     204                        return;
     205                } else if (_canyonState != kCanyonExit) {
     206                        // We died
     207                        ((Mars *)_owner)->die(kDeathRanIntoCanyonWall);
     208                }
     209        }
     210        ChaseInteraction::receiveNotification(notification, flags);
     211}
     212
     213void CanyonChase::setUpBranch() {
     214        TimeValue branchStart, branchEnd;
     215
     216        branchStart = 0;
     217        branchEnd = 0;
     218        switch (_canyonState) {
     219        case kCanyonLaunch:
     220        case kCanyonExit:
     221                branchStart = kLaunchEnd - kDecisionTime;
     222                branchEnd = kLaunchEnd;
     223                break;
     224        case kCanyonBranch1Left:
     225        case kCanyonBranch1Right:
     226                branchStart = kBranch1End - kDecisionTime;
     227                branchEnd = kBranch1End;
     228                break;
     229        case kCanyonBranch2Left:
     230        case kCanyonBranch2Right:
     231                branchStart = kBranch2End - kDecisionTime;
     232                branchEnd = kBranch2End;
     233                break;
     234        case kCanyonBranch3Left:
     235                branchStart = kBranch3End - kDecisionTime;
     236                branchEnd = kBranch3End;
     237                break;
     238        case kCanyonBranch4Left:
     239        case kCanyonBranch4Right:
     240                branchStart = kBranch4End - kDecisionTime;
     241                branchEnd = kBranch4End;
     242                break;
     243        case kCanyonBranch5Left:
     244        case kCanyonBranch5Right:
     245                branchStart = kBranch5End - kDecisionTime;
     246                branchEnd = kBranch5End;
     247                break;
     248        default:
     249                break;
     250        }
     251
     252        _currentMovie->setSegment(branchStart, branchEnd);
     253        // Need to call SetTime here in case we loop
     254        _currentMovie->setTime(branchStart);
     255
     256        _currentCallBack->setCallBackFlag(kChaseExitedBranchZone);
     257        _currentCallBack->scheduleCallBack(kTriggerAtStop, 0, 0);
     258}
     259
     260void CanyonChase::branchLeft() {
     261        TimeValue branchStart, branchEnd;
     262        Movie *movie;
     263        NotificationCallBack *callBack;
     264
     265        branchStart = 0;
     266        branchEnd = 0;
     267        switch (_canyonState) {
     268        case kCanyonLaunch:
     269                branchStart = kBranch1Start;
     270                branchEnd = kBranch1End - kDecisionTime;
     271                _canyonState = kCanyonBranch1Left;
     272                break;
     273        case kCanyonBranch1Left:
     274        case kCanyonBranch1Right:
     275                branchStart = kBranch2Start;
     276                branchEnd = kBranch2End - kDecisionTime;
     277                _canyonState = kCanyonBranch2Left;
     278                break;
     279        case kCanyonBranch2Left:
     280        case kCanyonBranch2Right:
     281                branchStart = kBranch3Start;
     282                branchEnd = kBranch3End - kDecisionTime;
     283                _canyonState = kCanyonBranch3Left;
     284                break;
     285        case kCanyonBranch3Left:
     286                branchStart = kBranch4Start;
     287                branchEnd = kBranch4End - kDecisionTime;
     288                _canyonState = kCanyonBranch4Left;
     289                break;
     290        case kCanyonBranch4Left:
     291        case kCanyonBranch4Right:
     292                branchStart = kBranch5Start;
     293                branchEnd = kBranch5End - kDecisionTime;
     294                _canyonState = kCanyonBranch5Left;
     295                break;
     296        case kCanyonBranch5Left:
     297        case kCanyonBranch5Right:
     298                dontBranch();
     299                return;
     300        default:
     301                break;
     302        }
     303
     304        // Left branches are in hq2 (except exit)
     305        // Segment 5 branches are switched
     306        if (_canyonState == kCanyonBranch5Left || _canyonState == kCanyonBranch5Right) {
     307                movie = &_canyonMovie1;
     308                callBack = &_canyon1CallBack;
     309        } else {
     310                movie = &_canyonMovie2;
     311                callBack = &_canyon2CallBack;
     312        }
     313
     314        movie->setSegment(branchStart, branchEnd);
     315        movie->setTime(branchStart);
     316
     317        switchTo(*movie, *callBack);
     318
     319        callBack->setCallBackFlag(kChaseEnteredBranchZone);
     320        callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
     321}
     322
     323void CanyonChase::branchRight() {
     324        TimeValue branchStart, branchEnd;
     325        NotificationFlags flag;
     326        Movie *movie;
     327        NotificationCallBack *callBack;
     328
     329        branchStart = 0;
     330        branchEnd = 0;
     331        flag = 0;
     332        switch (_canyonState) {
     333        case kCanyonLaunch:
     334                branchStart = kBranch1Start;
     335                branchEnd = kBranch1End - kDecisionTime;
     336                _canyonState = kCanyonBranch1Right;
     337                flag = kChaseEnteredBranchZone;
     338                break;
     339        case kCanyonBranch1Left:
     340        case kCanyonBranch1Right:
     341                branchStart = kBranch2Start;
     342                branchEnd = kBranch2End - kDecisionTime;
     343                _canyonState = kCanyonBranch2Right;
     344                flag = kChaseEnteredBranchZone;
     345                break;
     346        case kCanyonBranch2Left:
     347        case kCanyonBranch2Right:
     348                dontBranch();
     349                return;
     350        case kCanyonBranch3Left:
     351                branchStart = kBranch4Start;
     352                branchEnd = kBranch4End - kDecisionTime;
     353                _canyonState = kCanyonBranch4Right;
     354                flag = kChaseEnteredBranchZone;
     355                break;
     356        case kCanyonBranch4Left:
     357        case kCanyonBranch4Right:
     358                branchStart = kBranch5Start;
     359                branchEnd = kBranch5End - kDecisionTime;
     360                _canyonState = kCanyonBranch5Right;
     361                flag = kChaseEnteredBranchZone;
     362                break;
     363        case kCanyonBranch5Left:
     364        case kCanyonBranch5Right:
     365                // Exit loop branch is in hq2
     366                branchStart = kExitStart;
     367                branchEnd = kExitEnd;
     368                _canyonState = kCanyonExit;
     369                flag = kChaseFinished;
     370                startMusicTimer(kCanyonChaseStart + kCanyonChaseExitedTime - kExitStart, kMovieTicksPerSecond,
     371                                                kCanyonExited);
     372                break;
     373        default:
     374                break;
     375        }
     376
     377        // Right branches are in hq1 (except exit)
     378        // Segment 5 branches are switched
     379        if (_canyonState == kCanyonBranch5Left || _canyonState == kCanyonBranch5Right) {
     380                movie = &_canyonMovie2;
     381                callBack = &_canyon2CallBack;
     382        } else {
     383                movie = &_canyonMovie1;
     384                callBack = &_canyon1CallBack;
     385        }
     386
     387        movie->setSegment(branchStart, branchEnd);
     388        movie->setTime(branchStart);
     389
     390        switchTo(*movie, *callBack);
     391
     392        callBack->setCallBackFlag(flag);
     393        callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
     394}
     395
     396void CanyonChase::dontBranch() {
     397        TimeValue branchStart, branchEnd;
     398
     399        branchStart = 0;
     400        branchEnd = 0;
     401        switch (_canyonState) {
     402        case kCanyonLaunch:
     403                branchStart = kDeath1Start;
     404                branchEnd = kDeath1End;
     405                break;
     406        case kCanyonBranch1Left:
     407        case kCanyonBranch1Right:
     408                branchStart = kDeath2Start;
     409                branchEnd = kDeath2End;
     410                break;
     411        case kCanyonBranch2Left:
     412        case kCanyonBranch2Right:
     413                branchStart = kDeath3Start;
     414                branchEnd = kDeath3End;
     415                break;
     416        case kCanyonBranch3Left:
     417                branchStart = kDeath4Start;
     418                branchEnd = kDeath4End;
     419                break;
     420        case kCanyonBranch4Left:
     421        case kCanyonBranch4Right:
     422                branchStart = kDeath5Start;
     423                branchEnd = kDeath5End;
     424                break;
     425        case kCanyonBranch5Left:
     426        case kCanyonBranch5Right:
     427                _canyonMovie2.setSegment(kExitStart, kExitGenoPoint);
     428                _canyonMovie2.setTime(kExitStart);
     429                switchTo(_canyonMovie2, _canyon2CallBack);
     430                _canyon2CallBack.setCallBackFlag(kChaseFinished);
     431                _canyon2CallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     432                _canyonState = kCanyonLoop;
     433                return;
     434        default:
     435                break;
     436        }
     437
     438        _deathMovie.setSegment(branchStart, branchEnd);
     439        _deathMovie.setTime(branchStart);
     440
     441        switchTo(_deathMovie, _deathCallBack);
     442
     443        startMusicTimer(10, 10, kCanyonRanIntoWall);
     444}
     445
     446void CanyonChase::showControlsHint() {
     447        ((Mars *)_owner)->_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftKeypadHintTime);
     448        ((Mars *)_owner)->_lowerLeftShuttleMovie.redrawMovieWorld();
     449        ChaseInteraction::showControlsHint();
     450}
     451
     452void CanyonChase::hideControlsHint() {
     453        ((Mars *)_owner)->_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftCollisionTime);
     454        ((Mars *)_owner)->_lowerLeftShuttleMovie.redrawMovieWorld();
     455        ChaseInteraction::hideControlsHint();
     456}
     457
     458void CanyonChase::switchTo(Movie &movie, NotificationCallBack &callBack) {
     459        if (_currentMovie != &movie) {
     460                if (_currentMovie != NULL) {
     461                        _currentMovie->stop();
     462                        _currentMovie->hide();
     463                        _currentMovie->stopDisplaying();
     464                }
     465
     466                _currentMovie = &movie;
     467
     468                _currentMovie->startDisplaying();
     469                _currentMovie->show();
     470                _currentMovie->start();
     471        }
     472
     473        if (_currentCallBack != &callBack) {
     474                _currentCallBack = &callBack;
     475        }
     476}
     477
     478void CanyonChase::startMusicTimer(TimeValue time, TimeScale scale, MusicTimerCode code) {
     479        _musicFuse.primeFuse(time, scale);
     480        _musicEvent.canyonChase = this;
     481        _musicEvent.theEvent = code;
     482        _musicFuse.setFunctor(new Common::Functor0Mem<void, MusicTimerEvent>(&_musicEvent, &MusicTimerEvent::fire));
     483        _musicFuse.lightFuse();
     484}
     485
     486void CanyonChase::musicTimerExpired(MusicTimerEvent &event) {
     487        FaderMoveSpec spec;
     488
     489        switch (event.theEvent) {
     490        case kCanyonRanIntoWall:
     491                stopCanyonMusicLoop(5);
     492                break;
     493        case kCanyonExited:
     494                spec.makeTwoKnotFaderSpec(20, 0, 255, 5, 160);
     495                _musicFader.startFader(spec);
     496                startMusicTimer(kCanyonChaseFadedTime, kMovieTicksPerSecond, kCanyonFaded);
     497                break;
     498        case kCanyonFaded:
     499                spec.makeTwoKnotFaderSpec(10, 0, 160, 30, 0);
     500                _musicFader.startFader(spec);
     501                ((Mars *)_owner)->startMarsTimer(kLaunchTubeDVDReachedTime, kMovieTicksPerSecond,
     502                                                                                        kMarsLaunchTubeReached);
     503                break;
     504        default:
     505                break;
     506        }
     507}
     508
     509void CanyonChase::doGenoChase() {
     510        _genoMovie.initFromMovieFile("Images/Mars/Canyon_hqG.mov");
     511        _genoMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     512        _genoMovie.moveElementTo(kShuttleWindowLeft, kShuttleWindowTop);
     513        _genoMovie.setDisplayOrder(kShuttleMonitorOrder);
     514        _genoMovie.startDisplaying();
     515        _genoMovie.show();
     516        _genoMovie.start();
     517
     518        _genoCallBack.setNotification(&_chaseNotification);
     519        _genoCallBack.initCallBack(&_genoMovie, kCallBackAtExtremes);
     520        _genoCallBack.setCallBackFlag(kChaseFinished);
     521        _genoCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     522
     523        _canyonState = kCanyonExit;
     524
     525        ((Mars *)_owner)->startMarsTimer(_genoMovie.getDuration() - 5 * kMovieTicksPerSecond,
     526                                                                                kMovieTicksPerSecond, kMarsLaunchTubeReached);
     527}
     528
     529} // End of namespace Pegasus
  • new file engines/pegasus/neighborhood/mars/canyonchase.h

    diff --git a/engines/pegasus/neighborhood/mars/canyonchase.h b/engines/pegasus/neighborhood/mars/canyonchase.h
    new file mode 100644
    index 0000000..5b40c64
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#ifndef PEGASUS_NEIGHBORHOOD_MARS_CANYONCHASE_H
     27#define PEGASUS_NEIGHBORHOOD_MARS_CANYONCHASE_H
     28
     29#include "pegasus/chase.h"
     30#include "pegasus/fader.h"
     31#include "pegasus/movie.h"
     32#include "pegasus/sound.h"
     33
     34namespace Pegasus {
     35
     36class CanyonChase;
     37class Mars;
     38
     39enum MusicTimerCode {
     40        kCanyonRanIntoWall,
     41        kCanyonExited,
     42        kCanyonFaded
     43};
     44
     45struct MusicTimerEvent {
     46        CanyonChase *canyonChase;
     47        MusicTimerCode theEvent;
     48
     49        void fire();
     50};
     51
     52class CanyonChase : public ChaseInteraction {
     53friend class Mars;
     54friend struct MusicTimerEvent;
     55public:
     56
     57        CanyonChase(Neighborhood *);
     58        virtual ~CanyonChase() {}
     59
     60protected:
     61
     62        void startCanyonMusicLoop();
     63        void stopCanyonMusicLoop(const long);
     64
     65        void openInteraction();
     66        void initInteraction();
     67        void closeInteraction();
     68
     69        void receiveNotification(Notification *, const NotificationFlags);
     70
     71        void setUpBranch();
     72        void branchLeft();
     73        void branchRight();
     74        void dontBranch();
     75
     76        void showControlsHint();
     77        void hideControlsHint();
     78
     79        void switchTo(Movie &, NotificationCallBack &);
     80        void startMusicTimer(TimeValue, TimeScale, MusicTimerCode);
     81        void musicTimerExpired(MusicTimerEvent &);
     82        void doGenoChase();
     83
     84        Movie _canyonMovie1;
     85        Movie _canyonMovie2;
     86        Movie _deathMovie;
     87        Movie _genoMovie;
     88        NotificationCallBack _canyon1CallBack; 
     89        NotificationCallBack _canyon2CallBack;
     90        NotificationCallBack _deathCallBack;
     91        NotificationCallBack _genoCallBack;
     92        Sound _musicLoop;
     93        SoundFader _musicFader;
     94        FuseFunction _musicFuse;
     95
     96        MusicTimerEvent _musicEvent;
     97
     98        Movie *_currentMovie;
     99        NotificationCallBack *_currentCallBack;
     100        short _canyonState;
     101};
     102
     103} // End of namespace Pegasus
     104
     105#endif
  • engines/pegasus/neighborhood/mars/constants.h

    diff --git a/engines/pegasus/neighborhood/mars/constants.h b/engines/pegasus/neighborhood/mars/constants.h
    index 82a7f03..f6c1724 100644
    a b namespace Pegasus {  
    3232
    3333// Element Coordinates
    3434
     35static const CoordType kPodScreenLeft = kNavAreaLeft + 88;
     36static const CoordType kPodScreenTop = kNavAreaTop + 204;
     37
     38static const CoordType kPodSteerLeft = kNavAreaLeft + 212;
     39static const CoordType kPodSteerTop = kNavAreaTop + 232;
     40
    3541static const CoordType kUndoHiliteLeft = kNavAreaLeft + 140;
    3642static const CoordType kUndoHiliteTop = kNavAreaTop + 36;
    3743
    static const CoordType kShuttleEnergyTop = 60;  
    99105static const CoordType kShuttleEnergyWidth = 252;
    100106static const CoordType kShuttleEnergyHeight = 22;
    101107
     108static const CoordType kShuttleSteerLeft = kShuttleWindowLeft + 136;
     109static const CoordType kShuttleSteerTop = kShuttleWindowTop + 196;
     110
    102111static const CoordType kPlanetStartLeft = kShuttleWindowLeft;
    103112static const CoordType kPlanetStartTop = kShuttleWindowTop + kShuttleWindowHeight;
    104113
    static const TimeValue kShuttleSwingStart = 0;  
    130139static const TimeValue kShuttleSwingStop = 5 * 600;
    131140
    132141static const TimeValue kCanyonChaseStart = kShuttleSwingStop;
    133 static const TimeValue kCanyonChaseStop = 60 * 600 + 43 * 600 + 14 * 40;
    134 
    135 static const TimeValue kLaunchTubeReachedTime = 60 * 600 + 38 * 600 - kCanyonChaseStart;
    136 static const TimeValue kCanyonChaseFinishedTime = kCanyonChaseStop - kCanyonChaseStart -
    137                                                                                         kLaunchTubeReachedTime;
     142static const TimeValue kCanyonChaseCDStop = 60 * 600 + 43 * 600 + 14 * 40;
     143static const TimeValue kCanyonChaseDVDStop = 60 * 600 + 50 * 600 + 12 * 40;
     144
     145static const TimeValue kCanyonChaseExitedTime = 60 * 600 + 40 * 600 + 13 * 40 - kCanyonChaseStart;
     146static const TimeValue kCanyonChaseFadedTime = 60 * 600 + 43 * 600 + 6 * 40 - kCanyonChaseStart -
     147                                                                                        kCanyonChaseExitedTime;
     148
     149static const TimeValue kLaunchTubeCDReachedTime = 60 * 600 + 38 * 600 - kCanyonChaseStart;
     150static const TimeValue kLaunchTubeDVDReachedTime = 60 * 600 + 45 * 600 - kCanyonChaseStart -
     151                                                                                        kCanyonChaseExitedTime - kCanyonChaseFadedTime;
     152static const TimeValue kCanyonChaseCDFinishedTime = kCanyonChaseCDStop - kCanyonChaseStart -
     153                                                                                        kLaunchTubeCDReachedTime;
     154static const TimeValue kCanyonChaseDVDFinishedTime = kCanyonChaseDVDStop - kCanyonChaseStart -
     155                                                                                        kCanyonChaseExitedTime - kCanyonChaseFadedTime -
     156                                                                                        kLaunchTubeDVDReachedTime;
    138157
    139158// Left shuttle.
    140159
    static const TimeValue kShuttleLowerLeftTubeTime = 40;  
    183202
    184203static const TimeValue kShuttleLowerLeftAutopilotTime = 80;
    185204
     205static const TimeValue kShuttleLowerLeftKeypadHintTime = 120;
     206
    186207// Lower Right shuttle.
    187208
    188209static const TimeValue kShuttleLowerRightOffTime = 0;
    static const ExtraID kMarsMaze184WestLoop = 109;  
    929950static const ExtraID kMarsMaze184WestDeath = 110;
    930951static const ExtraID kMars200DeathInBucket = 111;
    931952
     953// Mars interactions.
     954
     955static const InteractionID kMarsTunnelPodInteractionID = 0;
     956static const InteractionID kMarsCanyonChaseInteractionID = 1;
     957
    932958static const ResIDType kReactorUndoHilitePICTID = 900;
    933959
    934960static const int16 kMars52Compass = 90;
  • engines/pegasus/neighborhood/mars/mars.cpp

    diff --git a/engines/pegasus/neighborhood/mars/mars.cpp b/engines/pegasus/neighborhood/mars/mars.cpp
    index 435bcd4..55e0ddc 100644
    a b  
    2525
    2626#include "common/events.h"
    2727#include "video/qt_decoder.h"
     28#include "video/theora_decoder.h"
    2829
    2930#include "pegasus/cursor.h"
    3031#include "pegasus/energymonitor.h"
    3132#include "pegasus/gamestate.h"
    3233#include "pegasus/pegasus.h"
    3334#include "pegasus/ai/ai_area.h"
     35#include "pegasus/items/biochips/arthurchip.h"
    3436#include "pegasus/items/biochips/opticalchip.h"
    3537#include "pegasus/items/biochips/shieldchip.h"
    3638#include "pegasus/items/inventory/airmask.h"
     39#include "pegasus/neighborhood/mars/canyonchase.h"
    3740#include "pegasus/neighborhood/mars/mars.h"
     41#include "pegasus/neighborhood/mars/tunnelpod.h"
    3842
    3943namespace Pegasus {
    4044
    static const int16 kMarsShieldPanelOffsetAngle = 22;  
    4448
    4549static const CanMoveForwardReason kCantMoveRobotBlocking = kCantMoveLastReason + 1;
    4650
     51static const ExtraID kMarsRobotBobSlow = 1000;
     52static const ExtraID kMarsRobotGenoSlow = 1001;
     53
    4754static const NotificationFlags kTimeForCanyonChaseFlag = kLastNeighborhoodNotificationFlag << 1;
    4855static const NotificationFlags kExplosionFinishedFlag = kTimeForCanyonChaseFlag << 1;
    4956static const NotificationFlags kTimeToTransportFlag = kExplosionFinishedFlag << 1;
    static const NotificationFlags kMarsNotificationFlags = kTimeForCanyonChaseFlag  
    5259                                                                                                        kExplosionFinishedFlag |
    5360                                                                                                        kTimeToTransportFlag;
    5461
     62static const TimeValue kBucketClimbInTime = 1393980;
     63static const TimeValue kBucketSeeGearRoomTime = 2240;
     64static const TimeValue kBucketClimbOutTime = 1340;
     65
     66static const TimeValue kPodCautionDisplayedTime = 1631;
     67static const TimeValue kPodCautionDismissedTime = 3889;
     68
    5569static const TimeValue kLittleExplosionStart = 0 * 40;
    5670static const TimeValue kLittleExplosionStop = 24 * 40;
    5771
    void MarsTimerEvent::fire() {  
    90104}
    91105
    92106Mars::Mars(InputHandler *nextHandler, PegasusEngine *owner) : Neighborhood(nextHandler, owner, "Mars", kMarsID),
    93                 _guessObject(kNoDisplayElement), _undoPict(kNoDisplayElement), _guessHistory(kNoDisplayElement),
    94                 _choiceHighlight(kNoDisplayElement), _shuttleInterface1(kNoDisplayElement), _shuttleInterface2(kNoDisplayElement),
    95                 _shuttleInterface3(kNoDisplayElement), _shuttleInterface4(kNoDisplayElement), _canyonChaseMovie(kNoDisplayElement),
    96                 _leftShuttleMovie(kNoDisplayElement), _rightShuttleMovie(kNoDisplayElement), _lowerLeftShuttleMovie(kNoDisplayElement),
    97                 _lowerRightShuttleMovie(kNoDisplayElement), _centerShuttleMovie(kNoDisplayElement),
    98                 _upperLeftShuttleMovie(kNoDisplayElement), _upperRightShuttleMovie(kNoDisplayElement),
    99                 _leftDamageShuttleMovie(kNoDisplayElement), _rightDamageShuttleMovie(kNoDisplayElement), _explosions(kNoDisplayElement),
    100                 _planetMovie(kNoDisplayElement), _junk(kNoDisplayElement), _energyChoiceSpot(kShuttleEnergySpotID),
    101                 _gravitonChoiceSpot(kShuttleGravitonSpotID), _tractorChoiceSpot(kShuttleTractorSpotID),
    102                 _shuttleViewSpot(kShuttleViewSpotID), _shuttleTransportSpot(kShuttleTransportSpotID) {
     107                _extraMovie(kNoDisplayElement), _podSteerMovie(kNoDisplayElement), _guessObject(kNoDisplayElement),
     108                _undoPict(kNoDisplayElement), _guessHistory(kNoDisplayElement), _choiceHighlight(kNoDisplayElement),
     109                _shuttleInterface1(kNoDisplayElement), _shuttleInterface2(kNoDisplayElement),
     110                _shuttleInterface3(kNoDisplayElement), _shuttleInterface4(kNoDisplayElement),
     111                _canyonChaseMovie(kNoDisplayElement), _leftShuttleMovie(kNoDisplayElement), _rightShuttleMovie(kNoDisplayElement),
     112                _lowerLeftShuttleMovie(kNoDisplayElement), _lowerRightShuttleMovie(kNoDisplayElement),
     113                _centerShuttleMovie(kNoDisplayElement), _upperLeftShuttleMovie(kNoDisplayElement),
     114                _upperRightShuttleMovie(kNoDisplayElement), _leftDamageShuttleMovie(kNoDisplayElement),
     115                _rightDamageShuttleMovie(kNoDisplayElement), _explosions(kNoDisplayElement), _planetMovie(kNoDisplayElement),
     116                _junk(kNoDisplayElement), _energyChoiceSpot(kShuttleEnergySpotID), _gravitonChoiceSpot(kShuttleGravitonSpotID),
     117                _tractorChoiceSpot(kShuttleTractorSpotID), _shuttleViewSpot(kShuttleViewSpotID),
     118                _shuttleTransportSpot(kShuttleTransportSpotID) {
    103119        _noAirFuse.setFunctor(new Common::Functor0Mem<void, Mars>(this, &Mars::airStageExpired));
    104120        setIsItemTaken(kMarsCard);
    105121        setIsItemTaken(kAirMask);
    void Mars::init() {  
    126142
    127143        _neighborhoodNotification.notifyMe(this, kMarsNotificationFlags, kMarsNotificationFlags);
    128144
     145        _extraMovieCallBack.setNotification(&_neighborhoodNotification);
     146
    129147        _explosionCallBack.setNotification(&_neighborhoodNotification);
    130148        _explosionCallBack.setCallBackFlag(kExplosionFinishedFlag);
    131149
    132150        _weaponSelection = kNoWeapon;
    133151}
    134152
     153GameInteraction *Mars::makeInteraction(const InteractionID interactionID) {
     154        switch (interactionID) {
     155        case kMarsTunnelPodInteractionID:
     156                return new TunnelPod(this);
     157        case kMarsCanyonChaseInteractionID:
     158                return new CanyonChase(this);
     159        default:
     160                return NULL;
     161        }
     162}
     163
    135164void Mars::flushGameState() {
    136165        g_energyMonitor->saveCurrentEnergyValue();
    137166}
    void Mars::start() {  
    144173        Neighborhood::start();
    145174}
    146175
     176class ArthurOxygen50Action : public AIPlayMessageAction {
     177public:
     178        ArthurOxygen50Action();
     179
     180        virtual void performAIAction(AIRule *);
     181};
     182
     183ArthurOxygen50Action::ArthurOxygen50Action() : AIPlayMessageAction("Images/AI/Mars/XMMAZB1", false, kWarningInterruption) {
     184}
     185
     186void ArthurOxygen50Action::performAIAction(AIRule *rule) {
     187        if (GameState.isTakenItemID(kArthurBiochip) && g_arthurChip && g_arthurChip->isChattyArthur())
     188                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA84", kArthurMarsOxygen50Warning);
     189        else
     190                AIPlayMessageAction::performAIAction(rule);
     191}
     192
     193class ArthurOxygen25Action : public AIPlayMessageAction {
     194public:
     195        ArthurOxygen25Action();
     196
     197        virtual void performAIAction(AIRule *);
     198};
     199
     200ArthurOxygen25Action::ArthurOxygen25Action() : AIPlayMessageAction("Images/AI/Mars/XMMAZB2", false, kWarningInterruption) {
     201}
     202
     203void ArthurOxygen25Action::performAIAction(AIRule *rule) {
     204        if (GameState.isTakenItemID(kArthurBiochip) && g_arthurChip && g_arthurChip->isChattyArthur()) {
     205                if (((PegasusEngine *)g_engine)->getRandomBit())
     206                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA85", kArthurMarsOxygen25Warning);
     207                else
     208                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA87", kArthurMarsOxygen25Warning);
     209        } else {
     210                AIPlayMessageAction::performAIAction(rule);
     211        }
     212}
     213
     214class ArthurOxygen5Action : public AIPlayMessageAction {
     215public:
     216        ArthurOxygen5Action();
     217
     218        virtual void performAIAction(AIRule *);
     219};
     220
     221ArthurOxygen5Action::ArthurOxygen5Action() : AIPlayMessageAction("Images/AI/Mars/XMMAZB3", false, kWarningInterruption) {
     222}
     223
     224void ArthurOxygen5Action::performAIAction(AIRule *rule) {
     225        if (GameState.isTakenItemID(kArthurBiochip) && g_arthurChip && g_arthurChip->isChattyArthur()) {
     226                if (((PegasusEngine *)g_engine)->getRandomBit())
     227                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA86", kArthurMarsOxygen5Warning);
     228                else
     229                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA88", kArthurMarsOxygen5Warning);
     230        } else {
     231                AIPlayMessageAction::performAIAction(rule);
     232        }
     233}
     234
    147235class AirMaskCondition : public AICondition {
    148236public:
    149237        AirMaskCondition(const uint32);
    void Mars::setUpAIRules() {  
    210298                g_AIArea->addAIRule(rule);
    211299
    212300                AirMaskCondition *airMask50Condition = new AirMaskCondition(50);
    213                 messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB1", false);
     301                if (_vm->isDVD())
     302                        messageAction = new ArthurOxygen50Action();
     303                else
     304                        messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB1", false);
    214305                AIRule *rule50 = new AIRule(airMask50Condition, messageAction);
    215306
    216307                AirMaskCondition *airMask25Condition = new AirMaskCondition(25);
    217308                AICompoundAction *compound = new AICompoundAction();
    218                 messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB2", false);
     309                if (_vm->isDVD())
     310                        messageAction = new ArthurOxygen25Action();
     311                else
     312                        messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB2", false);
    219313                compound->addAction(messageAction);
    220314                deactivate = new AIDeactivateRuleAction(rule50);
    221315                compound->addAction(deactivate);
    void Mars::setUpAIRules() {  
    223317
    224318                AirMaskCondition *airMask5Condition = new AirMaskCondition(5);
    225319                compound = new AICompoundAction;
    226                 messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB3", false);
     320                if (_vm->isDVD())
     321                        messageAction = new ArthurOxygen5Action();
     322                else
     323                        messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB3", false);
    227324                compound->addAction(messageAction);
    228325                deactivate = new AIDeactivateRuleAction(rule50);
    229326                compound->addAction(deactivate);
    void Mars::cantMoveThatWay(CanMoveForwardReason reason) {  
    396493}
    397494
    398495void Mars::moveForward() {
    399         if (GameState.getCurrentRoom() == kMars02 || (GameState.getCurrentRoom() >= kMars05 && GameState.getCurrentRoom() <= kMars08))
     496        if (GameState.getCurrentRoom() == kMars02 || (GameState.getCurrentRoom() >= kMars05 && GameState.getCurrentRoom() <= kMars08)) {
    400497                loadLoopSound2("");
     498        } else if (_vm->isDVD()) {
     499                Movie movie(kNoDisplayElement);
     500                Input input;
     501
     502                if (!GameState.isTakenItemID(kCardBomb) &&
     503                        GameState.getCurrentRoom() == kMars60 &&
     504                        GameState.getCurrentDirection() == kWest) {
     505                        loadLoopSound1("");
     506                        loadLoopSound2("");
     507                        movie.initFromMovieFile("Images/Mars/MMbomb.mov");
     508                        movie.setVolume(_vm->getSoundFXLevel());
     509                        movie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     510                        movie.setDisplayOrder(kNavMovieOrder + 1);
     511                        movie.startDisplaying();
     512                        movie.show();
     513                        movie.start();
     514
     515                        while (movie.isRunning() && !_vm->shouldQuit()) {
     516                                InputDevice.getInput(input, kFilterNoInput);
     517
     518                                _vm->checkCallBacks();
     519                                _vm->refreshDisplay();
     520                                _vm->_system->delayMillis(10);
     521                        }
     522
     523                        if (_vm->shouldQuit())
     524                                return;
     525
     526                        movie.moveElementTo(0, 0);
     527                        _vm->_gfx->setCurSurface(_navMovie.getSurface());
     528                        movie.copyToCurrentPort();
     529                        _vm->_gfx->setCurSurface(_vm->_gfx->getWorkArea());
     530
     531                        movie.hide();
     532                        movie.stopDisplaying();
     533                        movie.releaseMovie();
     534
     535                        didntFindBomb();
     536                        return;
     537                } else if (!GameState.getWalkthroughMode() &&
     538                                        GameState.getCurrentRoom() == kMarsMaze200 &&
     539                                        GameState.getCurrentDirection() == kWest) {
     540                        ExitTable::Entry exitEntry;
     541                        Common::Rect pushBounds;
     542                        bool leavingBucket;
     543
     544                        // Fall down the shaft immediately if we miss the climb-in
     545                        if (_navMovie.getTime() >= kBucketClimbInTime) {
     546                                _navMovie.stop();
     547
     548                                movie.initFromMovieFile("Images/Mars/MMfall.mov");
     549                                movie.setVolume(_vm->getSoundFXLevel());
     550                                movie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     551                                movie.setDisplayOrder(kNavMovieOrder + 1);
     552                                movie.startDisplaying();
     553                                movie.show();
     554                                movie.start();
     555
     556                                while (movie.isRunning() && !_vm->shouldQuit()) {
     557                                        InputDevice.getInput(input, kFilterNoInput);
     558
     559                                        _vm->checkCallBacks();
     560                                        _vm->refreshDisplay();
     561                                        _vm->_system->delayMillis(10);
     562                                }
     563
     564                                if (_vm->shouldQuit())
     565                                        return;
     566
     567                                movie.moveElementTo(0, 0);
     568                                _vm->_gfx->setCurSurface(_navMovie.getSurface());
     569                                movie.copyToCurrentPort();
     570                                _vm->_gfx->setCurSurface(_vm->_gfx->getWorkArea());
     571
     572                                movie.hide();
     573                                movie.stopDisplaying();
     574                                movie.releaseMovie();
     575
     576                                die(kDeathMissedOreBucket);
     577                                return;
     578                        }
     579                       
     580                        canMoveForward(exitEntry);
     581
     582                        leavingBucket = false;
     583                        _navMovie.stop();
     584                        _turnPush.getBounds(pushBounds);
     585                        _navMovie.moveElementTo(pushBounds.left, pushBounds.top);
     586                        _navMovie.show();
     587                        _navMovie.setFlags(0);
     588
     589                        // Set segment so we can skip ahead as needed
     590                        // Ride up the shaft but don't try to get out
     591                        _navMovie.setSegment(exitEntry.movieStart, exitEntry.movieEnd - kBucketClimbOutTime);
     592                        _navMovie.setTime(exitEntry.movieStart);
     593                        _navMovie.start();
     594                        while (_navMovie.isRunning() && _navMovie.getTime() < exitEntry.movieEnd - kBucketSeeGearRoomTime) {
     595                                InputDevice.getInput(input, kFilterAllDirections);
     596
     597                                if (input.upButtonDown() ||
     598                                        input.downButtonDown() ||
     599                                        input.leftButtonDown() ||
     600                                        input.rightButtonDown()) {
     601                                        _navMovie.stop();
     602                                        _vm->getDeathSound().initFromAIFFFile("Sounds/Mars/Mars Maze Fall.AIFF");
     603                                        _vm->getDeathSound().setVolume(_vm->getSoundFXLevel());
     604                                        _vm->getDeathSound().playSound();
     605                                        die(kDeathMissedOreBucket);
     606                                        return;
     607                                }
     608
     609                                _vm->checkCallBacks();
     610                                _vm->refreshDisplay();
     611                                g_system->delayMillis(10);
     612                        }
     613
     614                        // We can see the gear room at this point so it's safe to try to get out
     615                        _navMovie.setTime(exitEntry.movieEnd - kBucketSeeGearRoomTime);
     616                        while (_navMovie.isRunning()) {
     617                                InputDevice.getInput(input, kFilterAllDirections);
     618
     619                                if (input.upButtonAnyDown()) {
     620                                        leavingBucket = true;
     621                                } else if (input.anyDirectionInput()) {
     622                                        _navMovie.stop();
     623                                        _vm->getDeathSound().initFromAIFFFile("Sounds/Mars/Mars Maze Fall.AIFF");
     624                                        _vm->getDeathSound().setVolume(_vm->getSoundFXLevel());
     625                                        _vm->getDeathSound().playSound();
     626                                        die(kDeathMissedOreBucket);
     627                                        return;
     628                                }
     629
     630                                _vm->checkCallBacks();
     631                                _vm->refreshDisplay();
     632                                g_system->delayMillis(10);
     633                        }
     634                        _navMovie.stop();
     635
     636                        if (leavingBucket) {
     637                                exitEntry.movieStart = exitEntry.movieEnd - kBucketClimbOutTime;
     638                                startExitMovie(exitEntry);
     639                        } else {
     640                                playDeathExtra(kMars200DeathInBucket, kDeathDidntLeaveBucket);
     641                        }
     642                        return;
     643                }
     644        }
    401645
    402646        Neighborhood::moveForward();
    403647}
    void Mars::checkAirlockDoors() {  
    709953        }
    710954}
    711955
     956void Mars::startDoorOpenMovie(const TimeValue startTime, const TimeValue stopTime) {
     957        Movie movie(kNoDisplayElement);
     958        Input input;
     959
     960        if (_vm->isDVD() && GameState.getCurrentRoomAndView() == MakeRoomView(kMars18, kNorth) &&
     961                GameState.getMarsPodAtUpperPlatform()) {
     962                movie.initFromMovieFile("Images/Mars/M45DF.movie");
     963                movie.setVolume(_vm->getSoundFXLevel());
     964                movie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     965                movie.setDisplayOrder(kNavMovieOrder + 1);
     966                movie.startDisplaying();
     967                movie.show();
     968                movie.start();
     969
     970                while (movie.isRunning() && !_vm->shouldQuit()) {
     971                        InputDevice.getInput(input, kFilterNoInput);
     972
     973                        _vm->checkCallBacks();
     974                        _vm->refreshDisplay();
     975                        _vm->_system->delayMillis(10);
     976                }
     977
     978                if (_vm->shouldQuit())
     979                        return;
     980
     981                movie.moveElementTo(0, 0);
     982                _vm->_gfx->setCurSurface(_navMovie.getSurface());
     983                movie.copyToCurrentPort();
     984                _vm->_gfx->setCurSurface(_vm->_gfx->getWorkArea());
     985
     986                movie.hide();
     987                movie.stopDisplaying();
     988                movie.releaseMovie();
     989
     990                Neighborhood::doorOpened();
     991        } else {
     992                Neighborhood::startDoorOpenMovie(startTime, stopTime);
     993        }
     994}
     995
     996void Mars::startExitMovie(const ExitTable::Entry &exitEntry) {
     997        Movie movie(kNoDisplayElement);
     998        Input input;
     999
     1000        if (_vm->isDVD() && GameState.getCurrentRoomAndView() == MakeRoomView(kMars18, kNorth) &&
     1001                GameState.getMarsPodAtUpperPlatform()) {
     1002                movie.initFromMovieFile("Images/Mars/M45DG.movie");
     1003                movie.setVolume(_vm->getSoundFXLevel());
     1004                movie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     1005                movie.setDisplayOrder(kNavMovieOrder + 1);
     1006                movie.startDisplaying();
     1007                movie.show();
     1008                movie.start();
     1009
     1010                while (movie.isRunning() && !_vm->shouldQuit()) {
     1011                        InputDevice.getInput(input, kFilterNoInput);
     1012
     1013                        _vm->checkCallBacks();
     1014                        _vm->refreshDisplay();
     1015                        _vm->_system->delayMillis(10);
     1016                }
     1017
     1018                if (_vm->shouldQuit())
     1019                        return;
     1020
     1021                movie.moveElementTo(0, 0);
     1022                _vm->_gfx->setCurSurface(_navMovie.getSurface());
     1023                movie.copyToCurrentPort();
     1024                _vm->_gfx->setCurSurface(_vm->_gfx->getWorkArea());
     1025
     1026                movie.hide();
     1027                movie.stopDisplaying();
     1028                movie.releaseMovie();
     1029
     1030                arriveAt(kMars32, kNorth);
     1031        } else {
     1032                Neighborhood::startExitMovie(exitEntry);
     1033        }
     1034        if (GameState.getCurrentRoomAndView() == MakeRoomView(kMars43, kEast) && g_arthurChip)
     1035                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA07", kArthurMarsEnteredShuttle);
     1036}
     1037
    7121038int16 Mars::getStaticCompassAngle(const RoomID room, const DirectionConstant dir) {
    7131039        int16 angle = Neighborhood::getStaticCompassAngle(room, dir);
    7141040
    void Mars::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &co  
    8771203}
    8781204
    8791205void Mars::loadAmbientLoops() {
     1206        // Don't load an ambient loop if we died in a chase sequence
     1207        if (_vm->getEnergyDeathReason() == kDeathRanIntoCanyonWall || _vm->getEnergyDeathReason() == kDeathCollidedWithPod)
     1208                return;
     1209
    8801210        RoomID room = GameState.getCurrentRoom();
    8811211
    8821212        if ((room >= kMars0A && room <= kMars21) || (room >= kMars41 && room <= kMars43)) {
    883                 if (GameState.getMarsSeenTimeStream())
    884                         loadLoopSound1("Sounds/Mars/Gantry Ambient.22K.8.AIFF");
     1213                if (GameState.getMarsSeenTimeStream()) {
     1214                        if (_vm->isDVD()) // Updated for the DVD version
     1215                                loadLoopSound1("Sounds/Mars/Gantry Ambient.32K.16.AIFF");
     1216                        else
     1217                                loadLoopSound1("Sounds/Mars/Gantry Ambient.22K.8.AIFF");
     1218                }
    8851219        } else if (room >= kMars22 && room <= kMars31South) {
    886                 loadLoopSound1("Sounds/Mars/Reception.02.22K.8.AIFF", 0x100 / 4);
     1220                if (_vm->isDVD()) // Updated for the DVD version
     1221                        loadLoopSound1("Sounds/Mars/Reception.02.32K.16.AIFF", 0x100 / 4);
     1222                else
     1223                        loadLoopSound1("Sounds/Mars/Reception.02.22K.8.AIFF", 0x100 / 4);
    8871224        } else if (room >= kMars32 && room <= kMars34) {
    888                 loadLoopSound1("Sounds/Mars/Pod Room Ambient.22K.8.AIFF");
    889         } else if (room == kMars35) {
    890                 if (getAirQuality(room) == kAirQualityVacuum)
    891                         loadLoopSound1("Sounds/Mars/Gear Room Ambient.22K.8.AIFF");
     1225                if (_vm->isDVD()) // Updated for the DVD version
     1226                        loadLoopSound1("Sounds/Mars/Pod Room Ambient.32K.16.AIFF");
    8921227                else
    893                         loadLoopSound1("Sounds/Mars/Gantry Ambient.22K.8.AIFF", 0x100 / 2);
     1228                        loadLoopSound1("Sounds/Mars/Pod Room Ambient.22K.8.AIFF");
     1229        } else if (room == kMars35) {
     1230                if (getAirQuality(room) == kAirQualityVacuum) {
     1231                        if (_vm->isDVD()) // Updated for the DVD version
     1232                                loadLoopSound1("Sounds/Mars/Gear Room Ambient.44K.16.AIFF");
     1233                        else
     1234                                loadLoopSound1("Sounds/Mars/Gear Room Ambient.22K.8.AIFF");
     1235                } else {
     1236                        if (_vm->isDVD()) // Updated for the DVD version
     1237                                loadLoopSound1("Sounds/Mars/Gantry Ambient.32K.16.AIFF", 0x100 / 2);
     1238                        else
     1239                                loadLoopSound1("Sounds/Mars/Gantry Ambient.22K.8.AIFF", 0x100 / 2);
     1240                }
    8941241        } else if (room >= kMars36 && room <= kMars39) {
    895                 loadLoopSound1("Sounds/Mars/Gear Room Ambient.22K.8.AIFF");
     1242                if (_vm->isDVD()) // Updated for the DVD version
     1243                        loadLoopSound1("Sounds/Mars/Gear Room Ambient.44K.16.AIFF");
     1244                else
     1245                        loadLoopSound1("Sounds/Mars/Gear Room Ambient.22K.8.AIFF");
    8961246        } else if (room >= kMars45 && room <= kMars51) {
    897                 loadLoopSound1("Sounds/Mars/Lower Mars Ambient.22K.8.AIFF");
     1247                if (_vm->isDVD()) // Updated for the DVD version
     1248                        loadLoopSound1("Sounds/Mars/Lower Mars Ambient.32K.16.AIFF");
     1249                else
     1250                        loadLoopSound1("Sounds/Mars/Lower Mars Ambient.22K.8.AIFF");
    8981251        } else if (room >= kMars52 && room <= kMars58) {
    899                 loadLoopSound1("Sounds/Mars/ReactorLoop.22K.8.AIFF");
    900         } else if (room == kMars60) {
    901                 if (getAirQuality(room) == kAirQualityVacuum)
    902                         loadLoopSound1("Sounds/Mars/Mars Maze Ambient.22K.8.AIFF");
     1252                if (_vm->isDVD()) // Updated for the DVD version
     1253                        loadLoopSound1("Sounds/Mars/ReactorLoop.44K.16.AIFF");
    9031254                else
    904                         loadLoopSound1("Sounds/Mars/Lower Mars Ambient.22K.8.AIFF", 0x100 / 2);
     1255                        loadLoopSound1("Sounds/Mars/ReactorLoop.22K.8.AIFF");
     1256        } else if (room == kMars60) {
     1257                if (getAirQuality(room) == kAirQualityVacuum) {
     1258                        if (_vm->isDVD()) // Updated for the DVD version
     1259                                loadLoopSound1("Sounds/Mars/Mars Maze Ambient.32K.16.AIFF");
     1260                        else
     1261                                loadLoopSound1("Sounds/Mars/Mars Maze Ambient.22K.8.AIFF");
     1262                } else {
     1263                        if (_vm->isDVD()) // Updated for the DVD version
     1264                                loadLoopSound1("Sounds/Mars/Lower Mars Ambient.32K.16.AIFF", 0x100 / 2);
     1265                        else
     1266                                loadLoopSound1("Sounds/Mars/Lower Mars Ambient.22K.8.AIFF", 0x100 / 2);
     1267                }
    9051268        } else if (room >= kMarsMaze004 && room <= kMarsMaze200) {
    906                 loadLoopSound1("Sounds/Mars/Mars Maze Ambient.22K.8.AIFF");
     1269                if (_vm->isDVD()) { // Updated for the DVD version
     1270                        if (GameState.getEasterEgg() || room == kMarsMaze200 ||
     1271                                (room == kMarsMaze199 && GameState.getCurrentDirection() == kWest))
     1272                                loadLoopSound1("Sounds/Mars/Mars Maze Ambient.32K.16.AIFF");
     1273                        else
     1274                                loadLoopSound1("Sounds/Mars/Mars Maze GenoLoop.32K.16.AIFF");
     1275                } else {
     1276                        loadLoopSound1("Sounds/Mars/Mars Maze Ambient.22K.8.AIFF");
     1277                }
    9071278        } else if (room == kMarsRobotShuttle) {
    9081279                loadLoopSound1("Sounds/Mars/Robot Shuttle.22K.8.AIFF");
    9091280        }
    void Mars::timerExpired(const uint32 eventType) {  
    11301501}
    11311502
    11321503void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {
     1504        Input input;
     1505        InventoryItem *item;
     1506
    11331507        switch (MakeRoomView(room, direction)) {
    11341508        case MakeRoomView(kMars18, kNorth):
    11351509                if (GameState.getMarsPodAtUpperPlatform())
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    11421516                else
    11431517                        setCurrentAlternate(kAltMarsNormal);
    11441518                break;
     1519        case MakeRoomView(kMars31South, kSouth):
     1520                if (!GameState.isTakenItemID(kMarsCard) && g_arthurChip) {
     1521                        if (_vm->getRandomBit())
     1522                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA05", kArthurMarsZoomedToKeyCard);
     1523                        else
     1524                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA96", kArthurMarsZoomedToKeyCard);
     1525                }
     1526                break;
    11451527        case MakeRoomView(kMars35, kEast):
    11461528        case MakeRoomView(kMars35, kWest):
    11471529                if (GameState.getMarsAirlockOpen())
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    11551537                        setCurrentAlternate(kAltMars60AirlockEast);
    11561538                else
    11571539                        setCurrentAlternate(kAltMars60AirlockWest);
     1540                if (!(g_airMask && g_airMask->getAirLeft() > 0) && g_arthurChip)
     1541                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA39", kArthurMarsInAirlockNoOxygen);
    11581542                break;
    11591543        case MakeRoomView(kMars45, kNorth):
    11601544        case MakeRoomView(kMars45, kSouth):
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    11751559                        setCurrentAlternate(kAltMarsNormal);
    11761560                else
    11771561                        setCurrentAlternate(kAltMarsPodAtMars45);
     1562                if (g_arthurChip && room == kMars46) {
     1563                        if (direction == kEast && !GameState.isTakenItemID(kCrowbar))
     1564                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA34", kArthurMarsLeftPodNoCrowBar);
     1565                        else if (direction == kWest && GameState.getMarsPodAtUpperPlatform())
     1566                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA82", kArthurMarsLookAtEmptyTracks);
     1567                }
    11781568                break;
    11791569        case MakeRoomView(kMars48, kNorth):
    11801570        case MakeRoomView(kMars48, kSouth):
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    11961586                else
    11971587                        setCurrentAlternate(kAltMarsNormal);
    11981588                break;
     1589        case MakeRoomView(kMarsMaze004, kWest):
     1590                if (_vm->isDVD() && GameState.getCurrentRoom() == kMars60) {
     1591                        InputDevice.getInput(input, kFilterAllInput);
     1592                        // Check easter egg modifier for the Geno mix
     1593                        if (JMPPPInput::isEasterEggModifierInput(input))
     1594                                GameState.setEasterEgg(true);
     1595                        else
     1596                                GameState.setEasterEgg(false);
     1597                }
     1598                break;
    11991599        }
    12001600
    12011601        Neighborhood::arriveAt(room, direction);
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    12071607                if (!GameState.getMarsSeenTimeStream())
    12081608                        startExtraLongSequence(kMarsArrivalFromTSA, kMars0AWatchShuttleDepart, kExtraCompletedFlag, kFilterNoInput);
    12091609                break;
     1610        case MakeRoomView(kMars07, kNorth):
     1611                item = (InventoryItem *)g_allItems.findItemByID(kNitrogenCanister);
     1612                if (((g_airMask && g_airMask->getAirLeft() > 0) || item->getItemState() == kNitrogenFull) && g_arthurChip)
     1613                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA24", kArthurMarsSawWelcomeVideos);
     1614                break;
    12101615        case MakeRoomView(kMars07, kSouth):
    12111616        case MakeRoomView(kMars13, kNorth):
    12121617                if (!GameState.getMarsHeardCheckInMessage()) {
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    12141619                        GameState.setMarsHeardCheckInMessage(true);
    12151620                }
    12161621                break;
     1622        case MakeRoomView(kMars41, kEast):
     1623        case MakeRoomView(kMars42, kEast):
     1624                if (g_arthurChip)
     1625                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA73", kArthurMarsFoundNoShuttlePresent);
     1626                break;
    12171627        case MakeRoomView(kMars44, kWest):
    12181628                if (GameState.getMarsReadyForShuttleTransport())
    12191629                        startUpFromFinishedSpaceChase();
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    12291639        case MakeRoomView(kMars11, kSouth):
    12301640        case MakeRoomView(kMars12, kSouth):
    12311641                setCurrentActivation(kActivationReadyForKiosk);
     1642                if (g_arthurChip)
     1643                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA33", kArthurMarsReadyForKiosk);
    12321644                break;
    12331645        case MakeRoomView(kMars15, kWest):
    12341646                if (GameState.getMarsThreadedMaze() && !GameState.getMarsSecurityDown()) {
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    12531665        case MakeRoomView(kMars19, kNorth):
    12541666        case MakeRoomView(kMars19, kSouth):
    12551667        case MakeRoomView(kMars19, kWest):
    1256                 if (GameState.getMarsThreadedMaze() && !GameState.getMarsSawRobotLeave())
     1668                if (GameState.getMarsThreadedMaze() && !GameState.getMarsSawRobotLeave()) {
    12571669                        forceStridingStop(kMars19, kWest, kAltMarsNormal);
     1670                        if (g_arthurChip)
     1671                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA38", kArthurMarsExitedGearRoom);
     1672                }
    12581673
    12591674                if (GameState.getMarsThreadedMaze() && !GameState.getMarsSecurityDown())
    12601675                        forceStridingStop(kMars17, kWest, kAltMarsNormal);
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    13051720                        setCurrentActivation(kActivateReadyToPressurizeAirlock);
    13061721                break;
    13071722        case MakeRoomView(kMars39, kWest):
    1308                 if (GameState.getLastRoom() == kMarsMaze200)
     1723                if (GameState.getLastRoom() == kMarsMaze200) {
    13091724                        GameState.setMarsPodAtUpperPlatform(false);
     1725                        if (_vm->isDVD())
     1726                                GameState.setEasterEgg(false);
     1727                }
     1728                if (g_arthurChip)
     1729                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB40", kArthurMarsEnteredGearRoom);
     1730                break;
     1731        case MakeRoomView(kMars39, kNorth):
     1732        case MakeRoomView(kMars39, kSouth):
     1733        case MakeRoomView(kMars38, kNorth):
     1734        case MakeRoomView(kMars38, kSouth):
     1735        case MakeRoomView(kMars37, kNorth):
     1736        case MakeRoomView(kMars37, kSouth):
     1737        case MakeRoomView(kMars36, kNorth):
     1738        case MakeRoomView(kMars36, kSouth):
     1739                if (g_arthurChip)
     1740                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA83", kArthurMarsLookAtGears);
    13101741                break;
    13111742        case MakeRoomView(kMars45, kSouth):
    13121743                // Set up maze doors here.
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    13221753                if (!GameState.getMarsSeenRobotAtReactor()) {
    13231754                        // Preload the looping sound...
    13241755                        loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0, 0, 0);
    1325                         startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
     1756                        if (!_vm->isDVD()) {
     1757                                startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
     1758                        } else {
     1759                                InputDevice.getInput(input, kFilterAllInput);
     1760                                if (JMPPPInput::isEasterEggModifierInput(input)) {
     1761                                        if (_vm->getRandomBit())
     1762                                                startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
     1763                                        else
     1764                                                startExtraSequence(kMarsRobotBobSlow, kExtraCompletedFlag, kFilterNoInput);
     1765                                } else {
     1766                                        startExtraSequence(kMarsRobotGenoSlow, kExtraCompletedFlag, kFilterNoInput);
     1767                                }
     1768                        }
    13261769                } else if (!GameState.getMarsAvoidedReactorRobot()) {
    13271770                        loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0x100, 0, 0);
    13281771                        loopExtraSequence(kMars48RobotLoops);
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    13621805                        g_shield->setItemState(kShieldNormal);
    13631806                g_energyMonitor->setEnergyDrainRate(kEnergyDrainNormal);
    13641807                _vm->resetEnergyDeathReason();
     1808                if (GameState.isTakenItemID(kCardBomb) && g_arthurChip)
     1809                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA78", kArthurMarsExitedReactorWithCardBomb);
    13651810                break;
     1811        case MakeRoomView(kMars52, kEast):
     1812                if (g_arthurChip)
     1813                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA11", kArthurMarsEnteredReactor);
    13661814        case MakeRoomView(kMars52, kNorth):
    13671815        case MakeRoomView(kMars52, kSouth):
    1368         case MakeRoomView(kMars52, kEast):
    13691816        case MakeRoomView(kMars52, kWest):
    13701817        case MakeRoomView(kMars54, kNorth):
    13711818        case MakeRoomView(kMars54, kSouth):
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    14071854        case MakeRoomView(kMarsMaze007, kNorth):
    14081855                launchMaze007Robot();
    14091856                break;
     1857        case MakeRoomView(kMarsMaze009, kWest):
     1858                if (g_arthurChip)
     1859                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA20", kArthurMarsMazeReachedJunction);
     1860                break;
    14101861        case MakeRoomView(kMarsMaze015, kSouth):
    14111862                launchMaze015Robot();
    14121863                break;
    void Mars::arriveAt(const RoomID room, const DirectionConstant direction) {  
    14291880                GameState.setScoringThreadedMaze();
    14301881                GameState.setMarsThreadedMaze(true);
    14311882                break;
     1883        case MakeRoomView(kMarsMaze199, kWest):
     1884                if (g_arthurChip)
     1885                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA77", kArthurMarsFoundBuckets);
     1886                break;
     1887        case MakeRoomView(kMarsMaze200, kWest):
     1888                if (g_arthurChip) {
     1889                        if (_vm->getRandomBit())
     1890                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA10", kArthurMarsApproachedBuckets);
     1891                        else
     1892                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA76", kArthurMarsApproachedBuckets);
     1893                }
     1894                break;
    14321895        case MakeRoomView(kMarsDeathRoom, kNorth):
    14331896        case MakeRoomView(kMarsDeathRoom, kSouth):
    14341897        case MakeRoomView(kMarsDeathRoom, kEast):
    void Mars::shieldOff() {  
    14561919}
    14571920
    14581921void Mars::turnTo(const DirectionConstant direction) {
     1922        Input input;
     1923
    14591924        switch (MakeRoomView(GameState.getCurrentRoom(), direction)) {
    14601925        case MakeRoomView(kMars27, kNorth):
    14611926        case MakeRoomView(kMars27, kSouth):
    void Mars::turnTo(const DirectionConstant direction) {  
    14811946        case MakeRoomView(kMars11, kSouth):
    14821947        case MakeRoomView(kMars12, kSouth):
    14831948                setCurrentActivation(kActivationReadyForKiosk);
     1949                if (g_arthurChip)
     1950                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA33", kArthurMarsReadyForKiosk);         
    14841951                break;
    14851952        case MakeRoomView(kMars18, kNorth):
    14861953                if (GameState.getMarsPodAtUpperPlatform())
    void Mars::turnTo(const DirectionConstant direction) {  
    14921959                        GameState.setMarsHeardCheckInMessage(true);
    14931960                }
    14941961                break;
     1962        case MakeRoomView(kMars41, kEast):
     1963        case MakeRoomView(kMars42, kEast):
     1964                if (g_arthurChip)
     1965                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA73", kArthurMarsFoundNoShuttlePresent);
     1966                break;
    14951967        case MakeRoomView(kMars34, kSouth):
    14961968        case MakeRoomView(kMars45, kNorth):
    14971969                setCurrentActivation(kActivateMarsPodClosed);
    void Mars::turnTo(const DirectionConstant direction) {  
    15171989                if (GameState.getMarsThreadedMaze())
    15181990                        GameState.setScoringThreadedGearRoom();
    15191991                break;
     1992        case MakeRoomView(kMars39, kNorth):
     1993        case MakeRoomView(kMars39, kSouth):
     1994        case MakeRoomView(kMars38, kNorth):
     1995        case MakeRoomView(kMars38, kSouth):
     1996        case MakeRoomView(kMars37, kNorth):
     1997        case MakeRoomView(kMars37, kSouth):
     1998        case MakeRoomView(kMars36, kNorth):
     1999        case MakeRoomView(kMars36, kSouth):
     2000                if (g_arthurChip)
     2001                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA83", kArthurMarsLookAtGears);
     2002                break;
     2003        case MakeRoomView(kMars46, kWest):
     2004                if (GameState.getMarsPodAtUpperPlatform() && g_arthurChip)
     2005                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA82", kArthurMarsLookAtEmptyTracks);
     2006                break;
    15202007        case MakeRoomView(kMars48, kNorth):
    15212008                if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot())
    15222009                        die(kDeathDidntGetOutOfWay);
    void Mars::turnTo(const DirectionConstant direction) {  
    15252012                if (!GameState.getMarsSeenRobotAtReactor()) {
    15262013                        // Preload the looping sound...
    15272014                        loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0, 0, 0);
    1528                         startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
     2015                        if (!_vm->isDVD()) {
     2016                                startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
     2017                        } else {
     2018                                InputDevice.getInput(input, kFilterAllInput);
     2019                                if (JMPPPInput::isEasterEggModifierInput(input)) {
     2020                                        if (_vm->getRandomBit())
     2021                                                startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
     2022                                        else
     2023                                                startExtraSequence(kMarsRobotBobSlow, kExtraCompletedFlag, kFilterNoInput);
     2024                                } else {
     2025                                        startExtraSequence(kMarsRobotGenoSlow, kExtraCompletedFlag, kFilterNoInput);
     2026                                }
     2027                        }
    15292028                } else if (!GameState.getMarsAvoidedReactorRobot()) {
    15302029                        loopExtraSequence(kMars48RobotLoops);
    15312030                } else if (GameState.isTakenItemID(kAirMask)) {
    void Mars::turnTo(const DirectionConstant direction) {  
    15412040                        setCurrentAlternate(kAltMarsTookMask);
    15422041                else
    15432042                        setCurrentAlternate(kAltMarsNormal);
     2043                if (GameState.isTakenItemID(kCardBomb) && g_arthurChip)
     2044                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA78", kArthurMarsExitedReactorWithCardBomb);
    15442045                break;
    15452046        case MakeRoomView(kMars49, kSouth):
    15462047                if (GameState.isTakenItemID(kAirMask))
    void Mars::turnTo(const DirectionConstant direction) {  
    15482049                else
    15492050                        setCurrentActivation(kActivateMaskOnHolder);
    15502051                break;
     2052        case MakeRoomView(kMars51, kWest):
     2053        case MakeRoomView(kMars50, kWest):
     2054                if (GameState.isTakenItemID(kCardBomb) && g_arthurChip)
     2055                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA78", kArthurMarsExitedReactorWithCardBomb);
     2056                break;
    15512057        case MakeRoomView(kMars52, kNorth):
    15522058        case MakeRoomView(kMars52, kSouth):
    15532059        case MakeRoomView(kMars52, kEast):
    void Mars::turnTo(const DirectionConstant direction) {  
    15872093        case MakeRoomView(kMarsMaze184, kWest):
    15882094                launchMaze184Robot();
    15892095                break;
     2096        case MakeRoomView(kMarsMaze199, kNorth):
     2097        case MakeRoomView(kMarsMaze199, kSouth):
     2098        case MakeRoomView(kMarsMaze199, kEast):
     2099        case MakeRoomView(kMarsMaze199, kWest):
     2100                if (_vm->isDVD())
     2101                        loadAmbientLoops();
     2102                if (GameState.getCurrentDirection() == kWest && g_arthurChip)
     2103                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA77", kArthurMarsFoundBuckets);
     2104                break;
     2105        case MakeRoomView(kMarsMaze200, kWest):
     2106                if (g_arthurChip) {
     2107                        if (_vm->getRandomBit())
     2108                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA10", kArthurMarsApproachedBuckets);
     2109                        else
     2110                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA76", kArthurMarsApproachedBuckets);
     2111                }
     2112                break;
    15902113        }
    15912114}
    15922115
    void Mars::pickedUpItem(Item *item) {  
    18912414        case kAirMask:
    18922415                setCurrentActivation(kActivateHotSpotAlways);
    18932416                if (!GameState.getScoringGotOxygenMask()) {
    1894                         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XM48SB", false, kWarningInterruption);
     2417                        if (g_AIArea->isChattyAI())
     2418                                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XM48SB", false, kWarningInterruption);
    18952419                        GameState.setScoringGotOxygenMask();
    18962420                }
    18972421                break;
    void Mars::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {  
    19542478                switch (item->getObjectID()) {
    19552479                case kMarsCard:
    19562480                        Neighborhood::dropItemIntoRoom(item, dropSpot);
    1957                         if (dropSpot && dropSpot->getObjectID() == kMars34NorthCardDropSpotID)
    1958                                 startExtraSequence(kMarsTurnOnPod, kExtraCompletedFlag, kFilterNoInput);
     2481                        if (dropSpot && dropSpot->getObjectID() == kMars34NorthCardDropSpotID) {
     2482                                if (_vm->isDVD()) {
     2483                                        if (!GameState.getWalkthroughMode()) {
     2484                                                _interruptionFilter = kFilterNoInput;
     2485                                                _podSteerMovie.initFromMovieFile("Images/Mars/M45OMK.movie");
     2486                                                _podSteerMovie.setVolume(_vm->getSoundFXLevel());
     2487                                                _podSteerMovie.setDisplayOrder(kNavMovieOrder + 1);
     2488                                                _podSteerMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     2489                                                _podSteerMovie.startDisplaying();
     2490                                                _podSteerMovie.show();
     2491                                                _podSteerMovie.start();
     2492                                        } else {
     2493                                                startExtraSequence(kMarsTurnOnPod, kExtraCompletedFlag, kFilterNoInput);
     2494                                        }
     2495                                        startMarsTimer(kPodCautionDisplayedTime, kMovieTicksPerSecond, kMarsPodCautionDisplayed);
     2496                                } else {
     2497                                        startExtraSequence(kMarsTurnOnPod, kExtraCompletedFlag, kFilterNoInput);
     2498                                }
     2499                        }
    19592500                        break;
    19602501                case kNitrogenCanister:
    19612502                        Neighborhood::dropItemIntoRoom(item, dropSpot);
    1962                         if (dropSpot && dropSpot->getObjectID() == kMars57DropNitrogenSpotID)
     2503                        if (dropSpot && dropSpot->getObjectID() == kMars57DropNitrogenSpotID) {
    19632504                                startExtraSequence(kMars57FreezeLock, kExtraCompletedFlag, kFilterNoInput);
     2505                                if (g_arthurChip)
     2506                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA19", kArthurMarsUsedLiquidNitrogen);
     2507                        }
    19642508                        break;
    19652509                case kCrowbar:
    19662510                        _utilityFuse.stopFuse();
    void Mars::turnRight() {  
    20882632        }
    20892633}
    20902634
     2635void Mars::startExtraSequence(const ExtraID extraID, const NotificationFlags flags, const InputBits interruptionFilter) {
     2636        TimeValue segmentStart = 0, segmentStop = 0;
     2637        bool loopSequence = false;
     2638        Common::Rect pushBounds;
     2639        NotificationFlags extraFlags;
     2640
     2641        switch (extraID) {
     2642        case kMarsRobotBobSlow:
     2643        case kMarsRobotGenoSlow:
     2644                _turnPush.getBounds(pushBounds);
     2645               
     2646                switch (extraID) {
     2647                case kMarsRobotBobSlow:
     2648                        _extraMovie.initFromMovieFile("Images/Mars/M48RSB.movie");
     2649                        break;
     2650                case kMarsRobotGenoSlow:
     2651                        _extraMovie.initFromMovieFile("Images/Mars/M48RSA.movie");
     2652                        break;
     2653                default:
     2654                        break;
     2655                }
     2656                segmentStart = 0;
     2657                segmentStop = _extraMovie.getDuration();
     2658                loopSequence = false;
     2659               
     2660                _lastExtra = extraID;
     2661                _turnPush.hide();
     2662               
     2663                if (!loopSequence && g_AIArea)
     2664                        g_AIArea->lockAIOut();
     2665               
     2666                extraFlags = flags;
     2667                _interruptionFilter = interruptionFilter;
     2668                // Stop the nav movie before doing anything else
     2669                _navMovie.stop();
     2670                _navMovie.stopDisplaying();
     2671               
     2672                _extraMovie.setVolume(_vm->getSoundFXLevel());
     2673                _extraMovie.moveElementTo(pushBounds.left, pushBounds.top);
     2674                _extraMovie.setDisplayOrder(kNavMovieOrder + 1);
     2675                _extraMovie.startDisplaying();
     2676                _extraMovie.show();
     2677                _extraMovie.setFlags(0);
     2678                _extraMovie.setSegment(segmentStart, segmentStop);
     2679                _extraMovie.setTime(segmentStart);
     2680                if (loopSequence)
     2681                        _extraMovie.setFlags(kLoopTimeBase);
     2682                else
     2683                        extraFlags |= kNeighborhoodMovieCompletedFlag;
     2684                _extraMovieCallBack.cancelCallBack();
     2685                _extraMovieCallBack.initCallBack(&_extraMovie, kCallBackAtExtremes);
     2686                if (extraFlags != 0) {
     2687                        _extraMovieCallBack.setCallBackFlag(extraFlags);
     2688                        _extraMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     2689                }
     2690                _extraMovie.start();
     2691                break;
     2692        default:
     2693                Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
     2694                break;
     2695        }
     2696}
     2697
    20912698void Mars::receiveNotification(Notification *notification, const NotificationFlags flag) {
    20922699        InventoryItem *item;
    20932700
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    21132720                                                                                        kMarsPodDepartedUpperPlatformOut);
    21142721                                GameState.setMarsHeardUpperPodMessage(true);
    21152722                        }
     2723                        if (g_airMask && g_airMask->getAirLeft() > 0 && g_arthurChip)
     2724                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA74", kArthurMarsRobotThrownPlayerWithMask);
    21162725                        break;
    21172726                case kMarsInfoKioskIntro:
    21182727                        GameState.setScoringSawMarsKiosk();
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    21442753                        }
    21452754                        break;
    21462755                case kMarsTurnOnPod:
    2147                         item = (InventoryItem *)_vm->getAllItems().findItemByID(kMarsCard);
    2148                         _vm->addItemToInventory(item);
    2149                         GameState.setScoringTurnedOnTransport();
    2150                         loadLoopSound1("");
    2151                         loadLoopSound2("");
    2152                         startExtraSequence(kMarsTakePodToMars45, kExtraCompletedFlag, kFilterNoInput);
     2756                        if (!_vm->isDVD()) {
     2757                                item = (InventoryItem *)_vm->getAllItems().findItemByID(kMarsCard);
     2758                                _vm->addItemToInventory(item);
     2759                                GameState.setScoringTurnedOnTransport();
     2760                                loadLoopSound1("");
     2761                                loadLoopSound2("");
     2762                        }
     2763                        if (!_vm->isDVD() || GameState.getWalkthroughMode())
     2764                                startExtraSequence(kMarsTakePodToMars45, kExtraCompletedFlag, kFilterNoInput);
    21532765                        break;
    21542766                case kMarsTakePodToMars45:
    21552767                        arriveAt(kMars45, kSouth);
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    21722784                        checkAirMask();
    21732785                        loadAmbientLoops();
    21742786                        break;
     2787                case kMarsRobotBobSlow:
     2788                case kMarsRobotGenoSlow:
     2789                        _extraMovie.stopDisplaying();
     2790                        _extraMovie.releaseMovie();
     2791                        _navMovie.startDisplaying();
     2792                        // Fall through...
    21752793                case kMars48RobotApproaches:
    21762794                        loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0x100, 0, 0);
    21772795                        GameState.setMarsSeenRobotAtReactor(true);
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    21992817                        setCurrentActivation(kActivateMaskOnFiller);
    22002818                        setCurrentAlternate(kAltMarsMaskOnFiller);
    22012819                        GameState.setMarsMaskOnFiller(true);
     2820                        if (g_arthurChip) {
     2821                                if (_vm->getRandomBit())
     2822                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA13", kArthurMarsCantFillMask);
     2823                                else
     2824                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA80", kArthurMarsCantFillMask);
     2825                        }
    22022826                        break;
    22032827                case kMars58SpinLeft:
    22042828                case kMars54SpinRight:
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    22472871                        setCurrentActivation(kActivateReactorAskLowerScreen);
    22482872                        break;
    22492873                case kMars57LowerScreenClosed:
     2874                        item = (InventoryItem *)_vm->getAllItems().findItemByID(kNitrogenCanister);
     2875                        if (g_arthurChip) {
     2876                                if (item->getItemState() == kNitrogenFull)
     2877                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA12", kArthurMarsSawLockedPanel);
     2878                                else
     2879                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA39", kArthurMarsSawLockedPanelNoNitrogen);
     2880                        }
     2881                        // Fall through...
    22502882                case kMars57ThawLock:
    22512883                        setCurrentActivation(kActivateReactorReadyForNitrogen);
    22522884                        GameState.setMarsLockFrozen(false);
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    22832915                case kMars57RunDiagnostics:
    22842916                        setCurrentActivation(kActivateReactorRanDiagnostics);
    22852917                        GameState.setScoringFoundCardBomb();
     2918                        if (g_arthurChip) {
     2919                                if (_vm->getRandomBit())
     2920                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA73", kArthurMarsFoundCardBomb);
     2921                                else
     2922                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB34", kArthurMarsFoundCardBomb);
     2923                        }
    22862924                        break;
    22872925                case kMars57BombExplodes:
    22882926                case kMars57BombExplodesInGame:
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    23102948                case kMars57ExposeBomb:
    23112949                        setCurrentActivation(kActivateReactorBombExposed);
    23122950                        _privateFlags.setFlag(kMarsPrivateBombExposedFlag, true);
     2951                        if (g_arthurChip)
     2952                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA75", kArthurMarsDeactivatedCardBomb);
    23132953                        break;
    23142954                case kMars57BackToNormal:
    23152955                        setCurrentActivation(kActivateReactorPlatformIn);
    23162956                        _privateFlags.setFlag(kMarsPrivateBombExposedFlag, false);
    2317                         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XM51SW", false, kWarningInterruption);
     2957                        if (g_AIArea->isChattyAI())
     2958                                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XM51SW", false, kWarningInterruption);
     2959                        if (g_arthurChip)
     2960                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA02", kArthurMarsSolvedReactorGame);
    23182961                        break;
    23192962                case kMars60WestSpinAirlockToEast:
    23202963                        GameState.setMarsAirlockOpen(true);
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    23362979                        break;
    23372980                case kMarsRobotHeadOpen:
    23382981                        setCurrentActivation(kActivationRobotHeadOpen);
     2982                        if (g_arthurChip) {
     2983                                switch (_vm->getRandomNumber(2)) {
     2984                                case 0:
     2985                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA36", kArthurMarsRobotHeadOpen);
     2986                                        break;
     2987                                case 1:
     2988                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA37", kArthurMarsRobotHeadOpen);
     2989                                        break;
     2990                                case 2:
     2991                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA40", kArthurMarsRobotHeadOpen);
     2992                                        break;
     2993                                }
     2994                        }
    23392995                        break;
    23402996                case kMarsRobotHeadClose:
    23412997                        recallToTSASuccess();
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    23643020                        _rightDamageShuttleMovie.hide();
    23653021                        playMovieSegment(&_rightShuttleMovie, kShuttleRightDestroyedStart, kShuttleRightDestroyedStop);
    23663022                        playSpotSoundSync(kShuttleDestroyedIn, kShuttleDestroyedOut);
    2367                         throwAwayMarsShuttle();
     3023                        transportOutFromSpaceChase(true);
    23683024                        reinstateMonocleInterface();
    23693025                        recallToTSASuccess();
    23703026                }
    23713027        } else if ((flag & kTimeToTransportFlag) != 0) {
    2372                 transportToRobotShip();
     3028                transportOutFromSpaceChase(false);
    23733029        }
    23743030
    23753031        if (g_AIArea)
    void Mars::receiveNotification(Notification *notification, const NotificationFla  
    23793035void Mars::spotCompleted() {
    23803036        Neighborhood::spotCompleted();
    23813037
    2382         if (GameState.getCurrentRoom() == kMarsRobotShuttle)
    2383                 g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XN59WD", false, kWarningInterruption);
     3038        switch (GameState.getCurrentRoomAndView()) {
     3039        case MakeRoomView(kMars27, kNorth):
     3040        case MakeRoomView(kMars28, kNorth):
     3041                if (g_arthurChip) {
     3042                        switch (_vm->getRandomNumber(2)) {
     3043                        case 0:
     3044                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA09", kArthurMarsLookedAtGuards);
     3045                                break;
     3046                        case 1:
     3047                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA81", kArthurMarsLookedAtGuards);
     3048                                break;
     3049                        case 2:
     3050                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB32", kArthurMarsLookedAtGuards);
     3051                                break;
     3052                        }
     3053                }
     3054                break;
     3055        case MakeRoomView(kMarsRobotShuttle, kEast):
     3056                if (g_arthurChip)
     3057                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA79", kArthurMarsFoundDeadRobot);
     3058                if (g_AIArea->isChattyAI())
     3059                        g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XN59WD", false, kWarningInterruption);
     3060                break;
     3061        }
     3062}
     3063
     3064void Mars::startUpFromFinishedTunnelPod() {
     3065        arriveAt(kMars45, kSouth);
     3066        if (g_AIArea != NULL)
     3067                g_AIArea->checkMiddleArea();
    23843068}
    23853069
    23863070void Mars::doCanyonChase() {
     3071        Input input;
     3072        FaderMoveSpec spec;
     3073
    23873074        GameState.setScoringEnteredShuttle();
    23883075        setNextHandler(_vm);
    23893076        throwAwayInterface();
    void Mars::doCanyonChase() {  
    23943081        _spotSounds.initFromQuickTime(getSoundSpotsName());
    23953082        _spotSounds.setVolume(_vm->getSoundFXLevel());
    23963083
    2397         Video::VideoDecoder *video = new Video::QuickTimeDecoder();
    2398         if (!video->loadFile("Images/Mars/M44ESA.movie"))
    2399                 error("Could not load interface->shuttle transition video");
     3084        Video::VideoDecoder *video = 0;
     3085
     3086#ifdef USE_THEORADEC
     3087        if (_vm->isDVD()) {
     3088                video = new Video::TheoraDecoder();
     3089
     3090                if (!video->loadFile("Images/Mars/M44ESA_hq.ogg")) {
     3091                        delete video;
     3092                        video = 0;
     3093                }
     3094        }
     3095#endif
     3096
     3097        if (!video) {
     3098                video = new Video::QuickTimeDecoder();
     3099                if (!video->loadFile("Images/Mars/M44ESA.movie"))
     3100                        error("Could not load interface->shuttle transition video");
     3101        }
    24003102
    24013103        video->start();
    24023104
    void Mars::doCanyonChase() {  
    24293131        initOnePicture(&_shuttleInterface4, "Images/Mars/MCmain4.pict", kShuttleBackgroundOrder, kShuttle4Left,
    24303132                                                        kShuttle4Top, true);
    24313133
    2432         initOneMovie(&_canyonChaseMovie, "Images/Mars/Canyon.movie",
     3134        if (_vm->isDVD())
     3135                initOneMovie(&_canyonChaseMovie, "Images/Mars/Canyon_hq1.mov",
     3136                                                kShuttleMonitorOrder, kShuttleWindowLeft, kShuttleWindowTop, true);
     3137        else
     3138                initOneMovie(&_canyonChaseMovie, "Images/Mars/Canyon.movie",
    24333139                                                kShuttleMonitorOrder, kShuttleWindowLeft, kShuttleWindowTop, true);
    24343140        _canyonChaseMovie.setVolume(_vm->getSoundFXLevel());
    24353141
    2436         loadLoopSound1("Sounds/Mars/Inside Cockpit.22K.8.AIFF");
     3142        if (_vm->isDVD())
     3143                loadLoopSound1("Sounds/Mars/Inside Cockpit.44K.16.AIFF");
     3144        else
     3145                loadLoopSound1("Sounds/Mars/Inside Cockpit.22K.8.AIFF");
    24373146
    24383147        // Swing shuttle around...
    24393148        playMovieSegment(&_canyonChaseMovie, kShuttleSwingStart, kShuttleSwingStop);
    void Mars::doCanyonChase() {  
    24653174        initOneMovie(&_rightDamageShuttleMovie, "Images/Mars/Right Damage Shuttle.movie",
    24663175                        kShuttleStatusOrder, kShuttleRightEnergyLeft, kShuttleRightEnergyTop, false);
    24673176
     3177        if (_vm->isDVD()) {
     3178                _musicLoop.attachFader(&_musicFader);
     3179                _musicLoop.initFromAIFFFile("Sounds/Mars/Canyon Loop.44K.16.AIFF");
     3180                _musicFader.setMasterVolume(_vm->getSoundFXLevel());
     3181        }
     3182
    24683183        _centerShuttleMovie.show();
    24693184        _centerShuttleMovie.setTime(kShuttleCenterBoardingTime);
    24703185        playSpotSoundSync(kShuttleCockpitIn, kShuttleCockpitOut);
    void Mars::doCanyonChase() {  
    25383253
    25393254        loadLoopSound1("");
    25403255
    2541         _canyonChaseMovie.setSegment(kCanyonChaseStart, kCanyonChaseStop);
    2542         _canyonChaseMovie.start();
     3256        if (_vm->isDVD()) {
     3257                InputDevice.getInput(input, kFilterAllInput);
     3258                if (JMPPPInput::isEasterEggModifierInput(input)) {
     3259                        initOneMovie(&_canyonChaseMovie, "Images/Mars/Canyon_hqG.mov",
     3260                                                        kShuttleMonitorOrder, kShuttleWindowLeft, kShuttleWindowTop, true);
     3261                        _canyonChaseMovie.setVolume(_vm->getSoundFXLevel());
     3262                        _canyonChaseMovie.start();
     3263
     3264                        startMarsTimer(_canyonChaseMovie.getDuration() - 5 * kMovieTicksPerSecond,
     3265                                                        kMovieTicksPerSecond, kMarsLaunchTubeReached);
     3266                } else if (GameState.getWalkthroughMode()) {
     3267                        _canyonChaseMovie.setSegment(kCanyonChaseStart, kCanyonChaseDVDStop);
     3268                        _canyonChaseMovie.start();
     3269
     3270                        _musicLoop.loopSound();
     3271                        spec.makeTwoKnotFaderSpec(10, 0, 0, 1, 255);
     3272                        _musicFader.startFader(spec);
     3273
     3274                        startMarsTimer(kCanyonChaseExitedTime, kMovieTicksPerSecond, kMarsCanyonChaseExited);
     3275                } else {
     3276                        _canyonChaseMovie.stop();
     3277                        _canyonChaseMovie.stopDisplaying();
     3278                        _canyonChaseMovie.releaseMovie();
     3279
     3280                        newInteraction(kMarsCanyonChaseInteractionID);
     3281                }
     3282        } else {
     3283                _canyonChaseMovie.setSegment(kCanyonChaseStart, kCanyonChaseCDStop);
     3284                _canyonChaseMovie.start();
    25433285
    2544         startMarsTimer(kLaunchTubeReachedTime, kMovieTicksPerSecond, kMarsLaunchTubeReached);
     3286                startMarsTimer(kLaunchTubeCDReachedTime, kMovieTicksPerSecond, kMarsLaunchTubeReached);
     3287        }
    25453288}
    25463289
    25473290void Mars::startUpFromFinishedSpaceChase() {
    void Mars::startUpFromFinishedSpaceChase() {  
    26013344
    26023345        _lowerLeftShuttleMovie.show();
    26033346
    2604         loadLoopSound1("Sounds/Mars/Space Ambient.22K.8.AIFF");
     3347        playSpaceAmbient();
    26053348
    26063349        initOneMovie(&_junk, "Images/Mars/Junk.movie", kShuttleJunkOrder, kShuttleJunkLeft,
    26073350                        kShuttleJunkTop, false);
    void Mars::startUpFromSpaceChase() {  
    27103453
    27113454        _lowerLeftShuttleMovie.show();
    27123455
    2713         loadLoopSound1("Sounds/Mars/Space Ambient.22K.8.AIFF");
     3456        playSpaceAmbient();
    27143457
    27153458        initOneMovie(&_planetMovie, "Images/Mars/Planet.movie", kShuttlePlanetOrder,
    27163459                        kPlanetStartLeft, kPlanetStartTop, true);
    void Mars::startUpFromSpaceChase() {  
    27813524}
    27823525
    27833526void Mars::setSoundFXLevel(const uint16 level) {
     3527        CanyonChase *chase;
     3528
    27843529        Neighborhood::setSoundFXLevel(level);
    27853530
    2786         if (_canyonChaseMovie.isMovieValid())
    2787                 _canyonChaseMovie.setVolume(level);
     3531        if (_vm->isDVD()) {
     3532                if (GameState.getCurrentRoomAndView() == MakeRoomView(kMars44, kWest) &&
     3533                        _currentInteraction != NULL) {
     3534                        chase = (CanyonChase *)_currentInteraction;
     3535                        if (chase->_canyonMovie1.isMovieValid())
     3536                                chase->_canyonMovie1.setVolume(level);
     3537                        if (chase->_canyonMovie2.isMovieValid())
     3538                                chase->_canyonMovie2.setVolume(level);
     3539                        if (chase->_deathMovie.isMovieValid())
     3540                                chase->_deathMovie.setVolume(level);
     3541                        if (chase->_genoMovie.isMovieValid())
     3542                                chase->_genoMovie.setVolume(level);
     3543                        if (chase->_musicLoop.isSoundLoaded())
     3544                                chase->_musicFader.setMasterVolume(level);
     3545                }
     3546                if (_musicLoop.isSoundLoaded())
     3547                        _musicFader.setMasterVolume(level);
     3548        } else {
     3549                if (_canyonChaseMovie.isMovieValid())
     3550                        _canyonChaseMovie.setVolume(level);
     3551        }
    27883552
    27893553        if (_explosions.isMovieValid())
    27903554                _explosions.setVolume(level);
    void Mars::startMarsTimer(TimeValue time, TimeScale scale, MarsTimerCode code) {  
    27993563}
    28003564
    28013565void Mars::marsTimerExpired(MarsTimerEvent &event) {
     3566        InventoryItem *item;
     3567        FaderMoveSpec spec;
    28023568        Common::Rect r;
    28033569        uint16 x, y;
    28043570
    28053571        switch (event.event) {
     3572        case kMarsPodCautionDisplayed:
     3573                item = (InventoryItem *)_vm->getAllItems().findItemByID(kMarsCard);
     3574                _vm->addItemToInventory(item);
     3575                startMarsTimer(kPodCautionDismissedTime, kMovieTicksPerSecond, kMarsPodCautionDismissed);
     3576                return;
     3577        case kMarsPodCautionDismissed:
     3578                _podSteerMovie.hide();
     3579                _podSteerMovie.stopDisplaying();
     3580                _podSteerMovie.releaseMovie();
     3581                _interruptionFilter = kFilterAllInput;
     3582                GameState.setScoringTurnedOnTransport();
     3583                loadLoopSound1("");
     3584                loadLoopSound2("");
     3585                if (!GameState.getWalkthroughMode())
     3586                        newInteraction(kMarsTunnelPodInteractionID);
     3587                return;
     3588        // Bail out early for pod events so input is not filtered
     3589        case kMarsCanyonChaseExited:
     3590                spec.makeTwoKnotFaderSpec(20, 0, 255, 5, 160);
     3591                _musicFader.startFader(spec);
     3592                startMarsTimer(kCanyonChaseFadedTime, kMovieTicksPerSecond, kMarsCanyonChaseFaded);
     3593                break;
     3594        case kMarsCanyonChaseFaded:
     3595                spec.makeTwoKnotFaderSpec(10, 0, 160, 30, 0);
     3596                _musicFader.startFader(spec);
     3597                startMarsTimer(kLaunchTubeDVDReachedTime, kMovieTicksPerSecond, kMarsLaunchTubeReached);
     3598                break;
    28063599        case kMarsLaunchTubeReached:
    28073600                _lowerLeftShuttleMovie.setTime(kShuttleLowerLeftTubeTime);
    28083601                _lowerLeftShuttleMovie.redrawMovieWorld();
    2809                 startMarsTimer(kCanyonChaseFinishedTime, kMovieTicksPerSecond, kMarsCanyonChaseFinished);
     3602                startMarsTimer(kCanyonChaseCDFinishedTime, kMovieTicksPerSecond, kMarsCanyonChaseFinished);
    28103603                break;
    28113604        case kMarsCanyonChaseFinished:
    28123605                GameState.setScoringEnteredLaunchTube();
    28133606
    2814                 while (_canyonChaseMovie.isRunning()) {
    2815                         _vm->checkCallBacks();
    2816                         _vm->refreshDisplay();
    2817                         _vm->_system->delayMillis(10);
    2818                 }
     3607                if (_canyonChaseMovie.isMovieValid()) {
     3608                        while (_canyonChaseMovie.isRunning()) {
     3609                                _vm->checkCallBacks();
     3610                                _vm->refreshDisplay();
     3611                                _vm->_system->delayMillis(10);
     3612                        }
    28193613
    2820                 _canyonChaseMovie.stop();
    2821                 _canyonChaseMovie.stopDisplaying();
    2822                 _canyonChaseMovie.releaseMovie();
     3614                        _canyonChaseMovie.stop();
     3615                        _canyonChaseMovie.stopDisplaying();
     3616                        _canyonChaseMovie.releaseMovie();
     3617                }
    28233618
    28243619                _vm->_gfx->enableErase();
    28253620
    2826                 loadLoopSound1("Sounds/Mars/Space Ambient.22K.8.AIFF");
     3621                playSpaceAmbient();
    28273622
    2828                 playSpotSoundSync(kShuttleConfiguringIn, kShuttleConfiguringOut);
    2829                 playSpotSoundSync(kShuttleGeneratingIn, kShuttleGeneratingOut);
    2830                 playSpotSoundSync(kShuttleBreakawayIn, kShuttleBreakawayOut);
    2831                 playSpotSoundSync(kMarsAtmosphericBreakawayIn, kMarsAtmosphericBreakawayOut);
     3623                if (!_vm->isDVD()) {
     3624                        // Don't play a couple sounds in the DVD version; they were put into
     3625                        // the canyon video.
     3626                        playSpotSoundSync(kShuttleConfiguringIn, kShuttleConfiguringOut);
     3627                        playSpotSoundSync(kShuttleGeneratingIn, kShuttleGeneratingOut);
     3628                        playSpotSoundSync(kShuttleBreakawayIn, kShuttleBreakawayOut);
     3629                        playSpotSoundSync(kMarsAtmosphericBreakawayIn, kMarsAtmosphericBreakawayOut);
     3630                }
    28323631
    28333632                initOneMovie(&_planetMovie, "Images/Mars/Planet.movie", kShuttlePlanetOrder, kPlanetStartLeft, kPlanetStartTop, true);
    28343633                _planetMovie.setFlags(kLoopTimeBase);
    void Mars::throwAwayMarsShuttle() {  
    30133812        loadLoopSound1("");
    30143813}
    30153814
    3016 void Mars::transportToRobotShip() {
     3815void Mars::playSpaceAmbient() {
     3816        if (_vm->isDVD())
     3817                loadLoopSound1("Sounds/Mars/Space Ambient.44K.16.AIFF");
     3818        else
     3819                loadLoopSound1("Sounds/Mars/Space Ambient.22K.8.AIFF");
     3820}
     3821
     3822void Mars::transportOutFromSpaceChase(bool destroyedShip) {
    30173823        throwAwayMarsShuttle();
    30183824
    3019         Video::VideoDecoder *video = new Video::QuickTimeDecoder();
    3020         if (!video->loadFile("Images/Mars/M98EAE.movie"))
    3021                 error("Could not load shuttle->interface transition video");
     3825        Video::VideoDecoder *video = 0;
     3826
     3827#ifdef USE_THEORADEC
     3828        if (_vm->isDVD()) {
     3829                video = new Video::TheoraDecoder();
     3830
     3831                if (destroyedShip) {
     3832                        if (!video->loadFile("Images/Mars/M98EAP_hq.ogg")) {
     3833                                delete video;
     3834                                video = 0;
     3835                        }
     3836                } else if (!video->loadFile("Images/Mars/M98EAE_hq.ogg")) {
     3837                        delete video;
     3838                        video = 0;
     3839                }
     3840        }
     3841#endif
     3842
     3843        if (!video) {
     3844                video = new Video::QuickTimeDecoder();
     3845                if (destroyedShip && _vm->isDVD()) {
     3846                        if (!video->loadFile("Images/Mars/M98EAP.movie"))
     3847                                error("Could not load shuttle->TSA transition video");
     3848                } else if (!video->loadFile("Images/Mars/M98EAE.movie"))
     3849                        error("Could not load shuttle->interface transition video");
     3850        }
    30223851
     3852        video->setVolume(MIN<uint>(_vm->getSoundFXLevel(), 0xFF));
    30233853        video->start();
    30243854
    30253855        while (!_vm->shouldQuit() && !video->endOfVideo()) {
    void Mars::transportToRobotShip() {  
    30423872        if (_vm->shouldQuit())
    30433873                return;
    30443874
    3045         reinstateMonocleInterface();
     3875        if (!destroyedShip) {
     3876                reinstateMonocleInterface();
    30463877
    3047         g_energyMonitor->stopEnergyDraining();
    3048         g_energyMonitor->restoreLastEnergyValue();
    3049         _vm->resetEnergyDeathReason();
    3050         g_energyMonitor->startEnergyDraining();
     3878                g_energyMonitor->stopEnergyDraining();
     3879                g_energyMonitor->restoreLastEnergyValue();
     3880                _vm->resetEnergyDeathReason();
     3881                g_energyMonitor->startEnergyDraining();
    30513882
    3052         arriveAt(kMarsRobotShuttle, kEast);
     3883                arriveAt(kMarsRobotShuttle, kEast);
    30533884
    3054         _navMovie.stop();
    3055         _navMovie.setTime(_navMovie.getStart());
    3056         _navMovie.start();
     3885                _navMovie.stop();
     3886                _navMovie.setTime(_navMovie.getStart());
     3887                _navMovie.start();
     3888        }
    30573889}
    30583890
    30593891const int kRobotTooStrong = 1;
  • engines/pegasus/neighborhood/mars/mars.h

    diff --git a/engines/pegasus/neighborhood/mars/mars.h b/engines/pegasus/neighborhood/mars/mars.h
    index 0859522..09b4faf 100644
    a b  
    4040
    4141namespace Pegasus {
    4242
     43class CanyonChase;
    4344class InventoryItem;
    4445class Mars;
     46class TunnelPod;
    4547
    4648enum MarsTimerCode {
     49        kMarsPodCautionDisplayed,
     50        kMarsPodCautionDismissed,
     51        kMarsCanyonChaseExited,
     52        kMarsCanyonChaseFaded,
    4753        kMarsLaunchTubeReached,
    4854        kMarsCanyonChaseFinished,
    4955        kMarsSpaceChaseFinished // Player ran out of time...
    enum ShuttleWeaponSelection {  
    6470};
    6571
    6672class Mars : public Neighborhood {
     73friend class CanyonChase;
     74friend class TunnelPod;
    6775friend struct MarsTimerEvent;
    6876public:
    6977        Mars(InputHandler *, PegasusEngine *);
    7078        virtual ~Mars();
    7179
     80        virtual GameInteraction *makeInteraction(const InteractionID);
     81
    7282        void flushGameState();
    7383
    7484        virtual uint16 getDateResID() const;
    protected:  
    133143        CanOpenDoorReason canOpenDoor(DoorTable::Entry &);
    134144        void openDoor();
    135145        void closeDoorOffScreen(const RoomID, const DirectionConstant);
     146        void startDoorOpenMovie(const TimeValue, const TimeValue);
     147        void startExitMovie(const ExitTable::Entry &);
    136148        int16 getStaticCompassAngle(const RoomID, const DirectionConstant);
    137149        void getExitCompassMove(const ExitTable::Entry &, FaderMoveSpec &);
    138150        void getExtraCompassMove(const ExtraTable::Entry &, FaderMoveSpec &);
    139151        void turnTo(const DirectionConstant);
     152        void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits);
    140153        void receiveNotification(Notification *, const NotificationFlags);
    141154        void doorOpened();
     155        void startUpFromFinishedTunnelPod();
    142156        void setUpReactorEnergyDrain();
    143157        Hotspot *getItemScreenSpot(Item *, DisplayElement *);
    144158        void lockThawed();
    protected:  
    170184        void launchMaze136Robot();
    171185        void launchMaze184Robot();
    172186        void timerExpired(const uint32);
     187        void showRobotAtReactor();
    173188        void spotCompleted();
    174189
    175190        void doCanyonChase(void);
    protected:  
    178193        void throwAwayMarsShuttle();
    179194        void startUpFromFinishedSpaceChase();
    180195        void startUpFromSpaceChase();
    181         void transportToRobotShip();
     196        void transportOutFromSpaceChase(bool);
    182197        void spaceChaseClick(const Input &, const HotSpotID);
    183198        void updateCursor(const Common::Point, const Hotspot *);
     199        void playSpaceAmbient();
    184200
    185201        Common::String getSoundSpotsName();
    186202        Common::String getNavMovieName();
    187203
     204        Movie _extraMovie;
     205        NotificationCallBack _extraMovieCallBack;
     206
     207        Movie _podSteerMovie;
    188208        InventoryItem *_attackingItem;
    189209        FuseFunction _bombFuse;
    190210        FuseFunction _noAirFuse;
    protected:  
    202222        Picture _shuttleInterface3;
    203223        Picture _shuttleInterface4;
    204224        Movie _canyonChaseMovie;
     225        Sound _musicLoop;
     226        SoundFader _musicFader;
    205227
    206228        MarsTimerEvent _marsEvent;
    207229
  • new file engines/pegasus/neighborhood/mars/tunnelpod.cpp

    diff --git a/engines/pegasus/neighborhood/mars/tunnelpod.cpp b/engines/pegasus/neighborhood/mars/tunnelpod.cpp
    new file mode 100644
    index 0000000..b96c427
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#include "pegasus/pegasus.h"
     27#include "pegasus/items/biochips/arthurchip.h"
     28#include "pegasus/neighborhood/mars/tunnelpod.h"
     29#include "pegasus/neighborhood/mars/mars.h"
     30
     31namespace Pegasus {
     32
     33// Segment start and end points.
     34
     35static const TimeValue kLaunchStart = 315754;
     36static const TimeValue kLaunchEnd = 319392;
     37
     38static const TimeValue kBranch1MainStart = 0;
     39static const TimeValue kBranch1MainEnd = 3600;
     40static const TimeValue kBranch2MainStart = kBranch1MainEnd;
     41static const TimeValue kBranch2MainEnd = 13200;
     42static const TimeValue kBranch3MainStart = kBranch2MainEnd;
     43static const TimeValue kBranch3MainEnd = 20400;
     44static const TimeValue kFinishMainStart = kBranch3MainEnd;
     45static const TimeValue kFinishMainEnd = 30640;
     46
     47static const TimeValue kBranch2AltStart = 0;
     48static const TimeValue kBranch2AltEnd = 13200;
     49static const TimeValue kBranch3AltStart = kBranch2AltEnd;
     50static const TimeValue kBranch3AltEnd = 22800;
     51static const TimeValue kFinishAltStart = kBranch3AltEnd;
     52static const TimeValue kFinishAltEnd = 33640;
     53
     54// Tunnel state.
     55
     56enum {
     57        kTunnelLaunch,
     58        kTunnelBranch1Left,
     59        kTunnelBranch2Left,
     60        kTunnelBranch2Right,
     61        kTunnelBranch3Left,
     62        kTunnelBranch3Right,
     63        kTunnelFinish
     64};
     65
     66
     67TunnelPod::TunnelPod(Neighborhood *handler) : ChaseInteraction(kMarsTunnelPodInteractionID, handler,
     68                                                kMarsTunnelPodNotificationID, (PegasusEngine *)g_engine), _tunnelMainMovie(kNoDisplayElement),
     69                                                _tunnelAltMovie(kNoDisplayElement), _deathMovie(kNoDisplayElement) {
     70        _currentMovie = NULL;
     71        _currentCallBack = NULL;
     72}
     73
     74void TunnelPod::openInteraction() {
     75        ((Mars *)_owner)->_navMovie.stop();
     76
     77        _tunnelCallBack.setNotification(&_chaseNotification);
     78        _tunnelCallBack.initCallBack(&((Mars *)_owner)->_navMovie, kCallBackAtExtremes);
     79        _tunnelCallBack.setCallBackFlag(kChaseEnteredBranchZone);
     80        _tunnelCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     81
     82        _tunnelMainMovie.initFromMovieFile("Images/Mars/Pod 2345M.mov");
     83        _tunnelMainMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     84        _tunnelMainMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     85        _tunnelMainMovie.setDisplayOrder(kNavMovieOrder);
     86
     87        _tunnelMainCallBack.setNotification(&_chaseNotification);
     88        _tunnelMainCallBack.initCallBack(&_tunnelMainMovie, kCallBackAtExtremes);
     89        _tunnelMainCallBack.setCallBackFlag(kChaseEnteredBranchZone);
     90        _tunnelMainCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);     
     91
     92        _tunnelAltMovie.initFromMovieFile("Images/Mars/Pod 345A.mov");
     93        _tunnelAltMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     94        _tunnelAltMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     95        _tunnelAltMovie.setDisplayOrder(kNavMovieOrder);
     96
     97        _tunnelAltCallBack.setNotification(&_chaseNotification);
     98        _tunnelAltCallBack.initCallBack(&_tunnelAltMovie, kCallBackAtExtremes);
     99        _tunnelAltCallBack.setCallBackFlag(kChaseEnteredBranchZone);
     100        _tunnelAltCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     101
     102        _deathMovie.initFromMovieFile("Images/Mars/Pod 2D.mov");
     103        _deathMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     104        _deathMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     105        _deathMovie.setDisplayOrder(kNavMovieOrder);
     106
     107        _deathCallBack.setNotification(&_chaseNotification);
     108        _deathCallBack.initCallBack(&_deathMovie, kCallBackAtExtremes);
     109        _deathCallBack.setCallBackFlag(kChaseFinished);
     110        _deathCallBack.scheduleCallBack(kTriggerAtStop, 0 ,0);
     111
     112        ChaseInteraction::openInteraction();
     113
     114        _steerPict.setDisplayOrder(kNavMovieOrder + 1);
     115        _steerPict.moveElementTo(kPodSteerLeft, kPodSteerTop);
     116}
     117
     118void TunnelPod::initInteraction() {
     119        _steerPict.startDisplaying();
     120
     121        _tunnelState = kTunnelLaunch;
     122        ((Mars *)_owner)->_navMovie.setSegment(kLaunchStart, kLaunchEnd - kDecisionTime);
     123        ((Mars *)_owner)->_navMovie.setTime(kLaunchStart);
     124        ((Mars *)_owner)->_navMovie.start();
     125        _currentMovie = &((Mars *)_owner)->_navMovie;
     126        _currentCallBack = &_tunnelCallBack;
     127        ChaseInteraction::initInteraction();
     128        if (g_arthurChip)
     129                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB27", kArthurMarsTurnedOnTransport);
     130}
     131
     132void TunnelPod::closeInteraction() {
     133        ((Mars *)_owner)->_navMovie.stop();
     134        if (_tunnelState == kTunnelFinish) {
     135        // Only bring nack the nav movie if we successfully finished the chase
     136                ((Mars *)_owner)->_navMovie.startDisplaying();
     137                ((Mars *)_owner)->_navMovie.show();
     138        }
     139        _tunnelCallBack.releaseCallBack();
     140
     141        _tunnelAltMovie.stop();
     142        _tunnelAltMovie.stopDisplaying();
     143        _tunnelAltMovie.releaseMovie();
     144        _tunnelAltCallBack.releaseCallBack();
     145
     146        _deathMovie.stop();
     147        _deathMovie.stopDisplaying();
     148        _deathMovie.releaseMovie();
     149        _deathCallBack.releaseCallBack();
     150
     151        ChaseInteraction::closeInteraction();
     152}
     153
     154void TunnelPod::receiveNotification(Notification *notification, const NotificationFlags flags) {
     155        if (notification == &_chaseNotification && flags == kChaseFinished) {
     156                if (_tunnelState != kTunnelFinish) {
     157                        // We died
     158                        ((Mars *)_owner)->die(kDeathCollidedWithPod);
     159                } else {
     160                        ((Mars *)_owner)->startUpFromFinishedTunnelPod();
     161                }
     162        }
     163        ChaseInteraction::receiveNotification(notification, flags);
     164}
     165
     166void TunnelPod::setUpBranch() {
     167        TimeValue branchStart, branchEnd;
     168
     169        branchStart = 0;
     170        branchEnd = 0;
     171        switch (_tunnelState) {
     172        case kTunnelLaunch:
     173                branchStart = kLaunchEnd - kDecisionTime;
     174                branchEnd = kLaunchEnd;
     175                break;
     176        case kTunnelBranch1Left:
     177                branchStart = kBranch1MainEnd - kDecisionTime;
     178                branchEnd = kBranch1MainEnd;
     179                break;
     180        case kTunnelBranch2Left:
     181                branchStart = kBranch2AltEnd - kDecisionTime;
     182                branchEnd = kBranch2AltEnd;
     183                break;
     184        case kTunnelBranch2Right:
     185                branchStart = kBranch2MainEnd - kDecisionTime;
     186                branchEnd = kBranch2MainEnd;
     187                break;
     188        case kTunnelBranch3Left:
     189                branchStart = kBranch3MainEnd - kDecisionTime;
     190                branchEnd = kBranch3MainEnd;
     191                break;
     192        case kTunnelBranch3Right:
     193                branchStart = kBranch3AltEnd - kDecisionTime;
     194                branchEnd = kBranch3AltEnd;
     195                break;
     196        default:
     197                break;
     198        }
     199
     200        _currentMovie->setSegment(branchStart, branchEnd);
     201
     202        _currentCallBack->setCallBackFlag(kChaseExitedBranchZone);
     203        _currentCallBack->scheduleCallBack(kTriggerAtStop, 0, 0);
     204}
     205
     206void TunnelPod::branchLeft() {
     207        TimeValue branchStart, branchEnd;
     208        NotificationFlags flag;
     209        Movie *movie;
     210        NotificationCallBack *callBack;
     211
     212        branchStart = 0;
     213        branchEnd = 0;
     214        flag = 0;
     215        movie = NULL;
     216        callBack = NULL;
     217        switch (_tunnelState) {
     218        case kTunnelLaunch:
     219                branchStart = kBranch1MainStart;
     220                branchEnd = kBranch1MainEnd - kDecisionTime;
     221                _tunnelState = kTunnelBranch1Left;
     222                flag = kChaseEnteredBranchZone;
     223                movie = &_tunnelMainMovie;
     224                callBack = &_tunnelMainCallBack;
     225                break;
     226        case kTunnelBranch1Left:
     227                branchStart = kBranch2AltStart;
     228                branchEnd = kBranch2AltEnd - kDecisionTime;
     229                _tunnelState = kTunnelBranch2Left;
     230                flag = kChaseEnteredBranchZone;
     231                movie = &_tunnelAltMovie;
     232                callBack = &_tunnelAltCallBack;
     233                break;
     234        case kTunnelBranch2Left:
     235        case kTunnelBranch2Right:
     236                branchStart = kBranch3MainStart;
     237                branchEnd = kBranch3MainEnd - kDecisionTime;
     238                _tunnelState = kTunnelBranch3Left;
     239                flag = kChaseEnteredBranchZone;
     240                movie = &_tunnelMainMovie;
     241                callBack = &_tunnelMainCallBack;
     242                break;
     243        case kTunnelBranch3Left:
     244        case kTunnelBranch3Right:
     245                branchStart = kFinishAltStart;
     246                branchEnd = kFinishAltEnd;
     247                _tunnelState = kTunnelFinish;
     248                flag = kChaseFinished;
     249                movie = &_tunnelAltMovie;
     250                callBack = &_tunnelAltCallBack;
     251                break;
     252        default:
     253                break;
     254        }
     255
     256        movie->setSegment(branchStart, branchEnd);
     257        movie->setTime(branchStart);
     258
     259        switchTo(*movie, *callBack);
     260
     261        callBack->setCallBackFlag(flag);
     262        callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
     263}
     264
     265void TunnelPod::branchRight() {
     266        TimeValue branchStart, branchEnd;
     267        NotificationFlags flag;
     268        Movie *movie;
     269        NotificationCallBack *callBack;
     270
     271        branchStart = 0;
     272        branchEnd = 0;
     273        flag = 0;
     274        movie = NULL;
     275        callBack = NULL;
     276        switch (_tunnelState) {
     277        case kTunnelLaunch:
     278                switchTo(_deathMovie, _deathCallBack);
     279                return;
     280        case kTunnelBranch1Left:
     281                branchStart = kBranch2MainStart;
     282                branchEnd = kBranch2MainEnd - kDecisionTime;
     283                _tunnelState = kTunnelBranch2Right;
     284                flag = kChaseEnteredBranchZone;
     285                movie = &_tunnelMainMovie;
     286                callBack = &_tunnelMainCallBack;
     287                break;
     288        case kTunnelBranch2Left:
     289        case kTunnelBranch2Right:
     290                branchStart = kBranch3AltStart;
     291                branchEnd = kBranch3AltEnd - kDecisionTime;
     292                _tunnelState = kTunnelBranch3Right;
     293                flag = kChaseEnteredBranchZone;
     294                movie = &_tunnelAltMovie;
     295                callBack = &_tunnelAltCallBack;
     296                break;
     297        case kTunnelBranch3Left:
     298        case kTunnelBranch3Right:
     299                branchStart = kFinishMainStart;
     300                branchEnd = kFinishMainEnd;
     301                _tunnelState = kTunnelFinish;
     302                flag = kChaseFinished;
     303                movie = &_tunnelMainMovie;
     304                callBack = &_tunnelMainCallBack;
     305                break;
     306        default:
     307                break;
     308        }
     309
     310        movie->setSegment(branchStart, branchEnd);
     311        movie->setTime(branchStart);
     312
     313        switchTo(*movie, *callBack);
     314
     315        callBack->setCallBackFlag(flag);
     316        callBack->scheduleCallBack(kTriggerAtStop, 0, 0);
     317}
     318
     319void TunnelPod::dontBranch() {
     320        switch (_tunnelState) {
     321        case kTunnelLaunch:
     322        case kTunnelBranch1Left:
     323                if (_currentMovie == &_tunnelAltMovie)
     324                        branchLeft();
     325                else
     326                        branchRight();
     327                break;
     328        case kTunnelBranch2Left:
     329        case kTunnelBranch2Right:
     330                if (_currentMovie == &_tunnelAltMovie)
     331                        branchRight();
     332                else
     333                        branchLeft();
     334                break;
     335        case kTunnelBranch3Left:
     336        case kTunnelBranch3Right:
     337                if (_currentMovie == &_tunnelAltMovie)
     338                        branchLeft();
     339                else
     340                        branchRight();
     341                break;
     342        default:
     343                break;
     344        }
     345}
     346
     347void TunnelPod::switchTo(Movie &movie, NotificationCallBack &callBack) {
     348        if (_currentMovie != &movie) {
     349                if (_currentMovie != NULL) {
     350                        _currentMovie->stop();
     351                        _currentMovie->hide();
     352                        _currentMovie->stopDisplaying();
     353                }
     354
     355                _currentMovie = &movie;
     356
     357                _currentMovie->startDisplaying();
     358                _currentMovie->show();
     359                _currentMovie->start();
     360        }
     361
     362        if (_currentCallBack != &callBack) {
     363                _currentCallBack = &callBack;
     364        }
     365}
     366
     367} // End of namespace Pegasus
  • new file engines/pegasus/neighborhood/mars/tunnelpod.h

    diff --git a/engines/pegasus/neighborhood/mars/tunnelpod.h b/engines/pegasus/neighborhood/mars/tunnelpod.h
    new file mode 100644
    index 0000000..12b2dd9
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#ifndef PEGASUS_NEIGHBORHOOD_MARS_TUNNELPOD_H
     27#define PEGASUS_NEIGHBORHOOD_MARS_TUNNELPOD_H
     28
     29#include "pegasus/chase.h"
     30#include "pegasus/movie.h"
     31
     32namespace Pegasus {
     33
     34class Mars;
     35
     36class TunnelPod : public ChaseInteraction {
     37friend class Mars;
     38friend struct MusicTimerEvent;
     39public:
     40
     41        TunnelPod(Neighborhood *);
     42        virtual ~TunnelPod() {}
     43
     44protected:
     45
     46        void openInteraction();
     47        void initInteraction();
     48        void closeInteraction();
     49
     50        void receiveNotification(Notification *, const NotificationFlags);
     51
     52        void setUpBranch();
     53        void branchLeft();
     54        void branchRight();
     55        void dontBranch();
     56
     57        void switchTo(Movie &, NotificationCallBack &);
     58
     59        Movie _tunnelMainMovie;
     60        Movie _tunnelAltMovie;
     61        Movie _deathMovie;
     62        NotificationCallBack _tunnelCallBack;
     63        NotificationCallBack _tunnelMainCallBack;
     64        NotificationCallBack _tunnelAltCallBack;
     65        NotificationCallBack _deathCallBack;
     66
     67        Movie *_currentMovie;
     68        NotificationCallBack *_currentCallBack;
     69        short _tunnelState;
     70};
     71
     72} // End of namespace Pegasus
     73
     74#endif
  • engines/pegasus/neighborhood/neighborhood.cpp

    diff --git a/engines/pegasus/neighborhood/neighborhood.cpp b/engines/pegasus/neighborhood/neighborhood.cpp
    index 3116bd7..d7e25a1 100644
    a b  
    3636#include "pegasus/interface.h"
    3737#include "pegasus/pegasus.h"
    3838#include "pegasus/ai/ai_area.h"
     39#include "pegasus/items/biochips/arthurchip.h"
    3940#include "pegasus/items/biochips/mapchip.h"
    4041#include "pegasus/neighborhood/neighborhood.h"
    4142#include "pegasus/neighborhood/tsa/fulltsa.h"
    void Neighborhood::cantMoveThatWay(CanMoveForwardReason reason) {  
    719720}
    720721
    721722void Neighborhood::cantOpenDoor(CanOpenDoorReason) {
     723        bool firstLockedDoor;
     724
    722725        bumpIntoWall();
     726        if (g_arthurChip) {
     727                firstLockedDoor = g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA31", kArthurAttemptedLockedDoor);
     728
     729                if (!firstLockedDoor)
     730                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA32", kArthurAttemptedLockedDoorAgain);
     731        }
    723732}
    724733
    725734void Neighborhood::turnTo(const DirectionConstant direction) {
    void Neighborhood::startExitMovie(const ExitTable::Entry &exitEntry) {  
    10041013        GameState.setNextDirection(exitEntry.exitDirection);
    10051014
    10061015        if (exitEntry.movieEnd == exitEntry.exitEnd) // Just a walk.
    1007                 startMovieSequence(exitEntry.movieStart, exitEntry.movieEnd, kMoveForwardCompletedFlag, kFilterNoInput, false);
     1016                startMovieSequence(exitEntry.movieStart, exitEntry.movieEnd, kMoveForwardCompletedFlag, false, kFilterNoInput);
    10081017        else // We're stridin'!
    1009                 startMovieSequence(exitEntry.movieStart, exitEntry.exitEnd, kStrideCompletedFlag, kFilterNoInput, false, exitEntry.movieEnd);
     1018                startMovieSequence(exitEntry.movieStart, exitEntry.exitEnd, kStrideCompletedFlag, false, kFilterNoInput, exitEntry.movieEnd);
    10101019
    10111020        if (g_compass)
    10121021                g_compass->startFader(compassMove);
    void Neighborhood::startZoomMovie(const ZoomTable::Entry &zoomEntry) {  
    10211030        GameState.setNextRoom(zoomEntry.room);
    10221031        GameState.setNextDirection(zoomEntry.direction);
    10231032
    1024         startMovieSequence(zoomEntry.movieStart, zoomEntry.movieEnd, kMoveForwardCompletedFlag, kFilterNoInput, false);
     1033        startMovieSequence(zoomEntry.movieStart, zoomEntry.movieEnd, kMoveForwardCompletedFlag, false, kFilterNoInput);
    10251034
    10261035        if (g_compass)
    10271036                g_compass->startFader(compassMove);
    10281037}
    10291038
    10301039void Neighborhood::startDoorOpenMovie(const TimeValue startTime, const TimeValue stopTime) {
    1031         startMovieSequence(startTime, stopTime, kDoorOpenCompletedFlag, kFilterNoInput, false);
     1040        startMovieSequence(startTime, stopTime, kDoorOpenCompletedFlag, false, kFilterNoInput);
    10321041}
    10331042
    10341043void Neighborhood::startTurnPush(const TurnDirection turnDirection, const TimeValue newView, const DirectionConstant nextDir) {
    void Neighborhood::activateOneHotspot(HotspotInfoTable::Entry &entry, Hotspot *h  
    11861195
    11871196void Neighborhood::startSpotOnceOnly(TimeValue startTime, TimeValue stopTime) {
    11881197        _turnPush.hide();
    1189         startMovieSequence(startTime, stopTime, kSpotCompletedFlag, kFilterNoInput, false);
     1198        startMovieSequence(startTime, stopTime, kSpotCompletedFlag, false, kFilterNoInput);
    11901199}
    11911200
    11921201void Neighborhood::startMovieSequence(const TimeValue startTime, const TimeValue stopTime, NotificationFlags flags, bool loopSequence,
    void Neighborhood::startExtraLongSequence(const uint32 firstExtra, const uint32  
    15501559                getExtraEntry(lastExtra, lastEntry);
    15511560                _lastExtra = firstExtra;
    15521561                _turnPush.hide();
    1553                 startMovieSequence(firstEntry.movieStart, lastEntry.movieEnd, flags, kFilterNoInput, interruptionFilter);
     1562                startMovieSequence(firstEntry.movieStart, lastEntry.movieEnd, flags, false, interruptionFilter);
    15541563        }
    15551564}
    15561565
    void Neighborhood::handleInput(const Input &input, const Hotspot *cursorSpot) {  
    16471656                else if (input.rightButtonAnyDown())
    16481657                        rightButton(input);
    16491658        }
    1650 
     1659        if (_vm->toggleRequested()) {
     1660                _vm->requestToggle(false);
     1661                if (g_AIArea)
     1662                        g_AIArea->setChattyAI(!g_AIArea->isChattyAI());
     1663        }
    16511664        InputHandler::handleInput(input, cursorSpot);
    16521665}
    16531666
  • engines/pegasus/neighborhood/neighborhood.h

    diff --git a/engines/pegasus/neighborhood/neighborhood.h b/engines/pegasus/neighborhood/neighborhood.h
    index 3c1c5ea..308f608 100644
    a b bool operator!=(const QueueRequest &arg1, const QueueRequest &arg2);  
    9393
    9494class GameInteraction;
    9595class Item;
     96class SubChase;
     97class SubPlatform;
    9698class Neighborhood;
    9799
    98100class StriderCallBack : public TimeBaseCallBack {
    typedef Common::Queue<QueueRequest> NeighborhoodActionQueue;  
    110112
    111113class Neighborhood : public IDObject, public NotificationReceiver, public InputHandler, public Idler {
    112114friend class StriderCallBack;
     115friend class SubChase;
     116friend class SubPlatform;
    113117
    114118public:
    115119        Neighborhood(InputHandler *nextHandler, PegasusEngine *vm, const Common::String &resName, NeighborhoodID id);
    protected:  
    290294
    291295        virtual void createNeighborhoodSpots();
    292296
    293         void resetLastExtra() { _lastExtra = -1; }
     297        void resetLastExtra() { _lastExtra = 0xffffffff; }
    294298
    295299        virtual void throwAwayInterface();
    296300
    protected:  
    352356        AlternateID _currentAlternate;
    353357        HotSpotActivationID _currentActivation;
    354358
    355         int32 _lastExtra;
     359        ExtraID _lastExtra;
    356360        DeathReason _extraDeathReason;
    357361
    358362        // Graphics
  • engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp

    diff --git a/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp b/engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp
    index e2a0267..d15fe33 100644
    a b  
    2424 */
    2525
    2626#include "pegasus/pegasus.h"
     27#include "pegasus/items/biochips/arthurchip.h"
    2728#include "pegasus/neighborhood/norad/constants.h"
    2829#include "pegasus/neighborhood/norad/norad.h"
    2930#include "pegasus/neighborhood/norad/alpha/ecrmonitor.h"
    void NoradAlphaECRMonitor::closeInteraction() {  
    214215        _ecrPan.stopDisplaying();
    215216        _ecrPan.releasePanorama();
    216217        _ecrPanCallBack.releaseCallBack();
     218
     219        if (g_arthurChip)
     220                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB33", kArthurNoradAtSecurityMonitor);
    217221}
    218222
    219223} // End of namespace Pegasus
  • engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp

    diff --git a/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp b/engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp
    index 3491f16..ff5f2d7 100644
    a b  
    2525
    2626#include "pegasus/gamestate.h"
    2727#include "pegasus/pegasus.h"
     28#include "pegasus/items/biochips/arthurchip.h"
    2829#include "pegasus/items/inventory/airmask.h"
    2930#include "pegasus/neighborhood/norad/constants.h"
    3031#include "pegasus/neighborhood/norad/alpha/fillingstation.h"
    void NoradAlphaFillingStation::splashFinished() {  
    192193
    193194void NoradAlphaFillingStation::intakeWarningFinished() {
    194195        setStaticState(kFSMainMenu, kMainMenu);
     196        if (g_arthurChip)
     197                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA29", kArthurNoradSawIntakeWarning);
    195198}
    196199
    197200void NoradAlphaFillingStation::showIntakeInProgress(uint16 numSeconds) {
  • engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp

    diff --git a/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp b/engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
    index 6a24113..744dff4 100644
    a b  
    2323 *
    2424 */
    2525
     26#include "pegasus/cursor.h"
    2627#include "pegasus/energymonitor.h"
    2728#include "pegasus/gamestate.h"
     29#include "pegasus/interface.h"
    2830#include "pegasus/pegasus.h"
    2931#include "pegasus/ai/ai_area.h"
     32#include "pegasus/items/biochips/arthurchip.h"
    3033#include "pegasus/items/inventory/airmask.h"
    3134#include "pegasus/neighborhood/norad/constants.h"
    3235#include "pegasus/neighborhood/norad/subcontrolroom.h"
    3336#include "pegasus/neighborhood/norad/alpha/ecrmonitor.h"
    3437#include "pegasus/neighborhood/norad/alpha/fillingstation.h"
    3538#include "pegasus/neighborhood/norad/alpha/noradalpha.h"
     39#include "pegasus/neighborhood/norad/alpha/subchase.h"
    3640
    3741namespace Pegasus {
    3842
     43static const ExtraID kShowThermalScan = 1000;
     44
     45static const HotSpotID kThermalScanHotSpotID = 10000;
     46
    3947const uint32 NoradAlpha::_noradAlphaClawExtras[22] = {
    4048        kN22ClawFromAToB,
    4149        kN22ClawALoop,
    const uint32 NoradAlpha::_noradAlphaClawExtras[22] = {  
    6169        kN22ClawDClockwise
    6270};
    6371
    64 NoradAlpha::NoradAlpha(InputHandler *nextHandler, PegasusEngine *owner) : Norad(nextHandler, owner, "Norad Alpha", kNoradAlphaID) {
     72NoradAlpha::NoradAlpha(InputHandler *nextHandler, PegasusEngine *owner)
     73        : Norad(nextHandler, owner, "Norad Alpha", kNoradAlphaID),
     74        _thermalScanSpot(kThermalScanHotSpotID), _extraMovie(kNoDisplayElement) {
    6575        _elevatorUpRoomID = kNorad11South;
    6676        _elevatorDownRoomID = kNorad12South;
    6777        _elevatorUpSpotID = kNorad12ElevatorUpSpotID;
    NoradAlpha::NoradAlpha(InputHandler *nextHandler, PegasusEngine *owner) : Norad(  
    8292        _lowerPressureDoorDownSpotID = kAlphaLowerPressureDoorDownSpotID;
    8393        _lowerPressureDoorAbortSpotID = kNorad21WestOutSpotID;
    8494
    85         _pressureSoundIn = kPressureDoorIntro1In;
    86         _pressureSoundOut = kPressureDoorIntro1Out;
    87         _equalizeSoundIn = kPressureDoorIntro2In;
    88         _equalizeSoundOut = kPressureDoorIntro2Out;
     95        _pressureSoundIn = kAlphaPressureDoorIntro1In;
     96        _pressureSoundOut = kAlphaPressureDoorIntro1Out;
     97        _equalizeSoundIn = kAlphaPressureDoorIntro2In;
     98        _equalizeSoundOut = kAlphaPressureDoorIntro2Out;
    8999        _accessDeniedIn = kAlphaAccessDeniedIn;
    90100        _accessDeniedOut = kAlphaAccessDeniedOut;
    91101
    NoradAlpha::NoradAlpha(InputHandler *nextHandler, PegasusEngine *owner) : Norad(  
    97107        setIsItemTaken(kGasCanister);
    98108}
    99109
     110NoradAlpha::~NoradAlpha() {
     111        if (_vm->isDVD())
     112                _vm->getAllHotspots().remove(&_thermalScanSpot);
     113}
     114
    100115void NoradAlpha::init() {
    101116        Norad::init();
    102117
     118        _extraMovieCallBack.setNotification(&_neighborhoodNotification);
     119
     120        if (_vm->isDVD()) {
     121                _thermalScanSpot.setArea(Common::Rect(216, 112, 336, 312));
     122                _thermalScanSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
     123                _vm->getAllHotspots().push_back(&_thermalScanSpot);
     124        }
     125       
    103126        Hotspot *hotspot = _vm->getAllHotspots().findHotspotByID(kN01GasCanisterSpotID);
    104127        hotspot->setMaskedHotspotFlags(kPickUpItemSpotFlag, kPickUpItemSpotFlag);
    105128        HotspotInfoTable::Entry *hotspotEntry = findHotspotEntry(kN01GasCanisterSpotID);
    void NoradAlpha::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSp  
    208231}
    209232
    210233void NoradAlpha::playClawMonitorIntro() {
    211         playSpotSoundSync(kLoadClawIntroIn, kLoadClawIntroOut);
     234        playSpotSoundSync(kAlphaLoadClawIntroIn, kAlphaLoadClawIntroOut);
    212235}
    213236
    214237GameInteraction *NoradAlpha::makeInteraction(const InteractionID interactionID) {
    GameInteraction *NoradAlpha::makeInteraction(const InteractionID interactionID)  
    217240                return new NoradAlphaECRMonitor(this);
    218241        case kNoradFillingStationInteractionID:
    219242                return new NoradAlphaFillingStation(this);
     243        case kNoradSubChaseInteractionID:
     244                return new SubChase(this);
    220245        }
    221246
    222247        return Norad::makeInteraction(interactionID);
    void NoradAlpha::loadAmbientLoops() {  
    247272                                play unmanned loop
    248273*/
    249274
    250         if (!GameState.getNoradSeenTimeStream())
     275        if (!GameState.getNoradSeenTimeStream() || !g_interface || _vm->getEnergyDeathReason() == kDeathSubDestroyed)
    251276                return;
    252277
    253278        RoomID room = GameState.getCurrentRoom();
    254279        if (GameState.getNoradGassed()) {
    255                 if (room >= kNorad11 && room <= kNorad19West)
    256                         loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3);
    257                 else if (room >= kNorad21 && room <= kNorad22West)
    258                         loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3);
    259                 else
    260                         loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume);
     280                if (room >= kNorad11 && room <= kNorad19West) {
     281                        if (_vm->isDVD())
     282                                loadLoopSound1("Sounds/Norad/NEW SUB AMB.44K.AIFF", kNoradWarningVolume * 3);
     283                        else
     284                                loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3);
     285                } else if (room >= kNorad21 && room <= kNorad22West) {
     286                        if (_vm->isDVD())
     287                                loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.32K.AIFF", kNoradWarningVolume * 3);
     288                        else
     289                                loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3);
     290                } else {
     291                        if (_vm->isDVD())
     292                                loadLoopSound1("Sounds/Norad/WARNING LOOP.32K.AIFF", kNoradWarningVolume);
     293                        else
     294                                loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume);
     295                }
    261296        } else {
    262297                loadLoopSound1("");
    263298        }
    void NoradAlpha::arriveAt(const RoomID room, const DirectionConstant direction)  
    317352        case kNorad04:
    318353                arriveAtNorad04();
    319354                break;
     355        case kNorad07:
     356                if (_vm->isDVD() && GameState.getLastRoom() == kNorad06)
     357                        startExtraSequence(kShowThermalScan, kExtraCompletedFlag, kFilterNoInput);
     358                break;
    320359        case kNorad07North:
    321360                GameState.setScoringSawUnconsciousOperator(true);
     361                if (g_arthurChip)
     362                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA70", kArthurNoradSawUnconsciousOperator);
    322363                break;
    323364        case kNorad11:
    324365                GameState.setScoringWentThroughPressureDoor(true);
    void NoradAlpha::arriveAt(const RoomID room, const DirectionConstant direction)  
    330371}
    331372
    332373void NoradAlpha::arriveAtNorad01() {
    333         if (!GameState.getNoradSeenTimeStream() && GameState.getCurrentDirection() == kSouth) {
    334                 GameState.setNoradN22MessagePlayed(false);
    335                 requestExtraSequence(kNoradArriveFromTSA, kExtraCompletedFlag, kFilterNoInput);
    336                 // You are no match for me, human.
    337                 requestExtraSequence(kNorad01RobotTaunt, kExtraCompletedFlag, kFilterNoInput);
     374        Item *argonCanister, *nitrogenCanister;
     375
     376        switch (GameState.getCurrentDirection()) {
     377        case kSouth:
     378                if (!GameState.getNoradSeenTimeStream()) {
     379                        GameState.setNoradN22MessagePlayed(false);
     380                        requestExtraSequence(kNoradArriveFromTSA, kExtraCompletedFlag, kFilterNoInput);
     381                        // You are no match for me, human.
     382                        requestExtraSequence(kNorad01RobotTaunt, kExtraCompletedFlag, kFilterNoInput);
     383                }
     384                break;
     385        case kEast:
     386                if (g_arthurChip)
     387                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA33", kArthurNoradAtSecurityMonitor);
     388                break;
     389        case kWest:
     390                if (GameState.getLastRoom() == kNorad01West) {
     391                        argonCanister = g_allItems.findItemByID(kArgonCanister);
     392                        nitrogenCanister = g_allItems.findItemByID(kNitrogenCanister);
     393                        if (((GameState.isTakenItemID(kArgonCanister) && argonCanister->getItemState() != kArgonFull) ||
     394                                (GameState.isTakenItemID(kNitrogenCanister) && nitrogenCanister->getItemState() != kNitrogenFull)) && g_arthurChip)
     395                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA34", kArthurNoradDidntFillCanisters);
     396                }                       
     397                break;
    338398        }
    339399}
    340400
    void NoradAlpha::arriveAtNorad22() {  
    359419        }
    360420}
    361421
     422void NoradAlpha::turnTo(const DirectionConstant direction) {
     423        Norad::turnTo(direction);
     424        if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad01, kEast) && g_arthurChip)
     425                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA33", kArthurNoradAtSecurityMonitor);
     426}
     427
    362428void NoradAlpha::bumpIntoWall() {
    363429        requestSpotSound(kAlphaBumpIntoWallIn, kAlphaBumpIntoWallOut, kFilterNoInput, 0);
    364430        Neighborhood::bumpIntoWall();
    365431}
    366432
     433void NoradAlpha::startExtraSequence(const ExtraID extraID, const NotificationFlags flags, const InputBits interruptionFilter) {
     434        TimeValue segmentStart = 0, segmentStop = 0;
     435        bool loopSequence = false;
     436        Common::Rect pushBounds;
     437        NotificationFlags extraFlags;
     438
     439        switch (extraID) {
     440        case kShowThermalScan:
     441                _turnPush.getBounds(pushBounds);
     442               
     443                switch (extraID) {
     444                case kShowThermalScan:
     445                        _extraMovie.initFromMovieFile("Images/Norad Alpha/N07NS.movie");
     446                        segmentStart = 0;
     447                        segmentStop = _extraMovie.getDuration();
     448                        loopSequence = false;
     449                        break;
     450                default:
     451                        break;
     452                }
     453               
     454                _lastExtra = extraID;
     455                _turnPush.hide();
     456               
     457                if (!loopSequence && g_AIArea)
     458                        g_AIArea->lockAIOut();
     459               
     460                extraFlags = flags;
     461                _interruptionFilter = interruptionFilter;
     462                // Stop the nav movie before doing anything else
     463                _navMovie.stop();
     464                _navMovie.stopDisplaying();
     465               
     466                _extraMovie.setVolume(_vm->getSoundFXLevel());
     467                _extraMovie.moveElementTo(pushBounds.left, pushBounds.top);
     468                _extraMovie.setDisplayOrder(kNavMovieOrder + 1);
     469                _extraMovie.startDisplaying();
     470                _extraMovie.show();
     471                _extraMovie.setFlags(0);
     472                _extraMovie.setSegment(segmentStart, segmentStop);
     473                _extraMovie.setTime(segmentStart);
     474                if (loopSequence)
     475                        _extraMovie.setFlags(kLoopTimeBase);
     476                else
     477                        extraFlags |= kNeighborhoodMovieCompletedFlag;
     478                _extraMovieCallBack.cancelCallBack();
     479                _extraMovieCallBack.initCallBack(&_extraMovie, kCallBackAtExtremes);
     480                if (extraFlags != 0) {
     481                        _extraMovieCallBack.setCallBackFlag(extraFlags);
     482                        _extraMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     483                }
     484                _extraMovie.start();
     485                break;
     486        default:
     487                Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
     488                break;
     489        }
     490}
     491
    367492void NoradAlpha::receiveNotification(Notification *notification, const NotificationFlags flags) {
    368493        if ((flags & kExtraCompletedFlag) != 0) {
    369494                switch (_lastExtra) {
     495                case kShowThermalScan:
     496                        _interruptionFilter = kFilterAllInput;
     497                        _extraMovie.stopDisplaying();
     498                        _extraMovie.releaseMovie();
     499                        _navMovie.startDisplaying();
     500                        break;
     501                case kNorad19ExitToSub:
     502                        if (_vm->isDVD()) {
     503                                _interruptionFilter = kFilterAllInput;
     504                                _vm->_cursor->hide();
     505                                setNextHandler(_vm);
     506                                throwAwayInterface();
     507                                loadLoopSound1("");
     508                                newInteraction(kNoradSubChaseInteractionID);
     509                                GameState.setScoringEnteredSub(true);
     510                        }
     511                        break;
    370512                case kNoradArriveFromTSA:
    371513                        GameState.setNoradSeenTimeStream(true);
    372514                        loadAmbientLoops();
    373515                        break;
    374516                case kNorad01RobotTaunt:
    375                         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN01SB", false, kWarningInterruption);
     517                        if (g_AIArea->isChattyAI())
     518                                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN01SB", false, kWarningInterruption);
    376519                        _interruptionFilter = kFilterAllInput;
    377520                        makeContinuePoint();
    378521                        break;
    void NoradAlpha::receiveNotification(Notification *notification, const Notificat  
    389532                        startExtraSequence(kNorad22SouthFinish, kExtraCompletedFlag, kFilterNoInput);
    390533                        break;
    391534                case kNorad22SouthFinish:
     535                        if (g_arthurChip)
     536                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB29", kArthurNoradSawSubMessage);
    392537                        _interruptionFilter = kFilterAllInput;
    393538                        // Force ArriveAt to do its thing...
    394539                        GameState.setCurrentRoom(kNorad21);
    395540                        arriveAt(kNorad22, kSouth);
    396541                        break;
     542                case kN22ClawFromAToB:
     543                case kN22ClawAPinch:
     544                case kN22ClawACounterclockwise:
     545                case kN22ClawAClockwise:
     546                case kN22ClawFromBToA:
     547                case kN22ClawFromBToC:
     548                case kN22ClawFromBToD:
     549                case kN22ClawBPinch:
     550                case kN22ClawBCounterclockwise:
     551                case kN22ClawBClockwise:
     552                case kN22ClawFromCToB:
     553                case kN22ClawCPinch:
     554                case kN22ClawCCounterclockwise:
     555                case kN22ClawCClockwise:
     556                case kN22ClawFromDToB:
     557                case kN22ClawDPinch:
     558                case kN22ClawDCounterclockwise:
     559                case kN22ClawDClockwise:
     560                        if (g_arthurChip) {
     561                                if (_vm->getRandomBit())
     562                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA64", kArthurNoradPlayedWithClaw);
     563                                else
     564                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA66", kArthurNoradPlayedWithClaw);
     565                        }
     566                        break;
    397567                }
    398568        }
    399569
    TimeValue NoradAlpha::getViewTime(const RoomID room, const DirectionConstant dir  
    490660        return Norad::getViewTime(room, direction);
    491661}
    492662
     663void NoradAlpha::setSoundFXLevel(const uint16 level) {
     664        SubChase *chase;
     665
     666        Neighborhood::setSoundFXLevel(level);
     667        if (_currentInteraction != NULL && GameState.getScoringEnteredSub()) {
     668                chase = (SubChase *)_currentInteraction;
     669                if (chase->_subMovie.isMovieValid())
     670                        chase->_subMovie.setVolume(level);
     671        }
     672}
     673
    493674void NoradAlpha::turnOnFillingStation() {
    494675        if (GameState.getCurrentRoom() == kNorad01West && !GameState.getNoradFillingStationOn()) {
    495676                GameState.setNoradFillingStationOn(true);
    496677                updateViewFrame();
     678                if (g_arthurChip)
     679                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA72", kArthurNoradSawFillingStation);
    497680        }
    498681}
    499682
    void NoradAlpha::activateHotspots() {  
    545728                        }
    546729                }
    547730                break;
     731        case MakeRoomView(kNorad07, kNorth):
     732                if (_vm->isDVD())
     733                        _vm->getAllHotspots().activateOneHotspot(kThermalScanHotSpotID);
     734                break;
    548735        case MakeRoomView(kNorad10, kEast):
    549736                if (GameState.isCurrentDoorOpen())
    550737                        _vm->getAllHotspots().deactivateOneHotspot(kNorad10DoorSpotID);
    void NoradAlpha::clickInHotspot(const Input &input, const Hotspot *cursorSpot) {  
    568755                                hotspotEntry->hotspotItem = item->getObjectID();
    569756                        }
    570757                }
     758        } else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad07, kNorth) &&
     759                                cursorSpot->getObjectID() == kThermalScanHotSpotID) {
     760                startExtraSequence(kShowThermalScan, kExtraCompletedFlag, kFilterNoInput);
    571761        }
    572762}
    573763
  • engines/pegasus/neighborhood/norad/alpha/noradalpha.h

    diff --git a/engines/pegasus/neighborhood/norad/alpha/noradalpha.h b/engines/pegasus/neighborhood/norad/alpha/noradalpha.h
    index 582d6c2..ef209d3 100644
    a b  
    3131namespace Pegasus {
    3232
    3333class Item;
     34class SubChase;
    3435
    3536class NoradAlpha : public Norad {
     37friend class SubChase;
    3638public:
    3739        NoradAlpha(InputHandler *, PegasusEngine *);
    38         virtual ~NoradAlpha() {}
     40        virtual ~NoradAlpha();
    3941
    4042        virtual void init();
    4143        void start();
    public:  
    7779
    7880        void checkContinuePoint(const RoomID, const DirectionConstant);
    7981
     82        void setSoundFXLevel(const uint16);
     83
    8084        bool canSolve();
    8185        void doSolve();
    8286
    protected:  
    9094        virtual void arriveAtNorad22();
    9195
    9296        virtual void arriveAt(const RoomID, const DirectionConstant);
     97        virtual void turnTo(const DirectionConstant);
     98
     99        virtual void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits);
    93100
    94101        virtual void getZoomEntry(const HotSpotID, ZoomTable::Entry &);
    95102        virtual TimeValue getViewTime(const RoomID, const DirectionConstant);
    protected:  
    102109
    103110        void bumpIntoWall();
    104111
     112        Hotspot _thermalScanSpot;
     113
     114        Movie _extraMovie;
     115        NotificationCallBack _extraMovieCallBack;
     116
    105117        Item *_fillingStationItem;
    106118
    107119        bool _subPrepFailed;
  • new file engines/pegasus/neighborhood/norad/alpha/subchase.cpp

    diff --git a/engines/pegasus/neighborhood/norad/alpha/subchase.cpp b/engines/pegasus/neighborhood/norad/alpha/subchase.cpp
    new file mode 100644
    index 0000000..861227d
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#include "pegasus/pegasus.h"
     27#include "pegasus/gamestate.h"
     28#include "pegasus/neighborhood/norad/alpha/subchase.h"
     29#include "pegasus/neighborhood/norad/alpha/noradalpha.h"
     30#include "pegasus/neighborhood/norad/constants.h"
     31
     32namespace Pegasus {
     33
     34static const TimeScale kSubChaseScale = 600;
     35
     36static const DisplayOrder kSubChaseOrder = 27000;
     37
     38// Segment start and end points.
     39
     40static const TimeValue kIntroStart = 0;
     41static const TimeValue kIntroEnd = 2400;
     42static const TimeValue kDialogStart = kIntroEnd;
     43static const TimeValue kDialogEnd = 20920;
     44static const TimeValue kBranch1Start = kDialogEnd;
     45static const TimeValue kBranch1End = 32120;
     46static const TimeValue kBranch2LeftStart = kBranch1End;
     47static const TimeValue kBranch2LeftEnd = 48080;
     48static const TimeValue kBranch3Start = kBranch2LeftEnd;
     49static const TimeValue kBranch3End = 61080;
     50static const TimeValue kBranch4Start = kBranch3End;
     51static const TimeValue kBranch4End = 84080;
     52static const TimeValue kBranch5Start = kBranch4End;
     53static const TimeValue kBranch5End = 94840;
     54static const TimeValue kBranch6Start = kBranch5End;
     55static const TimeValue kBranch6End = 106040;
     56static const TimeValue kBranch7LeftStart = kBranch6End;
     57static const TimeValue kBranch7LeftEnd = 118840;
     58static const TimeValue kExitStart = kBranch7LeftEnd;
     59static const TimeValue kExitEnd = 133200;
     60static const TimeValue kBranch2RightStart = 133200;
     61static const TimeValue kBranch2RightEnd = 149160;
     62static const TimeValue kBranch7RightStart = 168000;
     63static const TimeValue kBranch7RightEnd = 180800;
     64
     65// Death start and end points.
     66
     67static const TimeValue kDeath4Start = 149160;
     68static const TimeValue kDeath4End = 158040;
     69static const TimeValue kDeath5Start = kDeath4End;
     70static const TimeValue kDeath5End = 163760;
     71static const TimeValue kDeath6Start = kDeath5End;
     72static const TimeValue kDeath6End = 168000;
     73static const TimeValue kDeath7Start = 180800;
     74static const TimeValue kDeath7End = 187040;
     75
     76// Chase state.
     77
     78enum {
     79        kSubDialog,
     80        kSubBranch1,
     81        kSubBranch2Left,
     82        kSubBranch2Right,
     83        kSubBranch3,
     84        kSubBranch4,
     85        kSubBranch5,
     86        kSubBranch6,
     87        kSubBranch7Left,
     88        kSubBranch7Right,
     89        kSubExit
     90};
     91
     92void HintTimerEvent::fire() {
     93        subChase->hintTimerExpired(*this);
     94}
     95
     96void BlinkTimerEvent::fire() {
     97        subChase->blinkTimerExpired(*this);
     98}
     99
     100SubChase::SubChase(Neighborhood *handler) : ChaseInteraction(kNoradSubChaseInteractionID, handler,
     101                                                kNoradSubChaseNotificationID, (PegasusEngine *)g_engine), _subMovie(kNoDisplayElement),
     102                                                _hintPict(kNoDisplayElement), _blinkPict(kNoDisplayElement), _canSteerSub(true) {
     103}
     104
     105void SubChase::openInteraction() {
     106        _subMovie.initFromMovieFile("Images/Norad Alpha/Sub Chase Movie");
     107        _subMovie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     108        _subMovie.moveElementTo(0, 0);
     109        _subMovie.setDisplayOrder(kSubChaseOrder);
     110        _subMovie.startDisplaying();
     111        _subMovie.show();
     112       
     113        _subCallBack.setNotification(&_chaseNotification);
     114        _subCallBack.initCallBack(&_subMovie, kCallBackAtExtremes);
     115       
     116        ChaseInteraction::openInteraction();
     117       
     118        _steerPict.setDisplayOrder(kSubChaseOrder + 1);
     119        _steerPict.moveElementTo(kNoradSubSteerLeft, kNoradSubSteerTop);
     120       
     121        _hintPict.initFromPICTFile("Images/Norad Alpha/Sub Chase steerk1.pict", true);
     122        _hintPict.setDisplayOrder(kSubChaseOrder + 1);
     123        _hintPict.moveElementTo(kNoradSubHintLeft, kNoradSubHintTop);
     124        _blinkPict.initFromPICTFile("Images/Norad Alpha/Sub Chase steerk0.pict", true);
     125        _blinkPict.setDisplayOrder(kSubChaseOrder + 1);
     126        _blinkPict.moveElementTo(kNoradSubHintLeft, kNoradSubHintTop);
     127}
     128
     129void SubChase::initInteraction() {
     130        _canSteerSub = !GameState.getWalkthroughMode();
     131
     132        _owner->playMovieSegment(&_subMovie, kIntroStart, kIntroEnd);
     133
     134        _subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     135
     136        if (_canSteerSub) {
     137                _steerPict.startDisplaying();
     138                _hintPict.startDisplaying();
     139                _blinkPict.startDisplaying();
     140                startHintTimer(20000 - kDialogStart, kSubChaseScale, kStartedHint);
     141                _subCallBack.setCallBackFlag(kChaseEnteredBranchZone);
     142                _subMovie.setSegment(kDialogStart, kBranch1End - kDecisionTime);
     143        } else {
     144                _subCallBack.setCallBackFlag(kChaseFinished);
     145                _subMovie.setSegment(kDialogStart, kExitEnd);
     146        }
     147
     148        _subState = kSubDialog;
     149        _subMovie.setTime(kDialogStart);
     150        _subMovie.start();
     151       
     152        ChaseInteraction::initInteraction();
     153}
     154
     155void SubChase::closeInteraction() {
     156        _subMovie.stop();
     157        _subMovie.stopDisplaying();
     158        _subMovie.releaseMovie();
     159        _subCallBack.releaseCallBack();
     160       
     161        _hintPict.hide();
     162        _hintPict.deallocateSurface();
     163       
     164        _blinkPict.hide();
     165        _blinkPict.deallocateSurface();
     166       
     167        ChaseInteraction::closeInteraction();
     168}
     169
     170void SubChase::receiveNotification(Notification *notification, const NotificationFlags flags) {
     171        if (notification == &_chaseNotification && flags == kChaseFinished) {
     172                if (_subState != kSubDialog && _subState != kSubExit) {
     173                        // We died
     174                        ((NoradAlpha *)_owner)->die(kDeathSubDestroyed);
     175                } else {
     176                        _subMovie.stopDisplaying();
     177                        ((PegasusEngine *)g_engine)->_gfx->enableErase();
     178                        ((PegasusEngine *)g_engine)->_gfx->updateDisplay();
     179                        ((PegasusEngine *)g_engine)->_gfx->disableErase();
     180                        ((PegasusEngine *)g_engine)->jumpToNewEnvironment(kNoradDeltaID, kNorad41, kEast);
     181                }
     182        }
     183        ChaseInteraction::receiveNotification(notification, flags);
     184}
     185
     186void SubChase::handleInput(const Input &input, const Hotspot *cursorSpot) {
     187        if (_subMovie.getTime() < kBranch1Start && input.anyInput()) {
     188                if (_canSteerSub) {
     189                        if (!_blinkFuse.isFuseLit()) {
     190                                // If the hint is not blinking then it must not be running, so display it
     191                                _hintPict.show();
     192                                startBlinkTimer(10, 10, kEnteredBlinkState);
     193                        }
     194                        _subState = kSubBranch1;
     195                        startHintTimer(3000, kSubChaseScale, kEndedHint);
     196                } else {
     197                        _subState = kSubExit;
     198                }
     199                _subMovie.setTime(kBranch1Start);
     200        } else {
     201                ChaseInteraction::handleInput(input, cursorSpot);
     202        }
     203}
     204
     205void SubChase::setUpBranch() {
     206        TimeValue branchStart, branchEnd;
     207       
     208        branchStart = 0;
     209        branchEnd = 0;
     210        switch (_subState) {
     211        case kSubDialog:
     212        case kSubBranch1:
     213                branchStart = kBranch1End - kDecisionTime;
     214                branchEnd = kBranch1End;
     215                break;
     216        case kSubBranch2Left:
     217                branchStart = kBranch2LeftEnd - kDecisionTime;
     218                branchEnd = kBranch2LeftEnd;
     219                break;
     220        case kSubBranch2Right:
     221                branchStart = kBranch2RightEnd - kDecisionTime;
     222                branchEnd = kBranch2RightEnd;
     223                break;
     224        case kSubBranch3:
     225                branchStart = kBranch3End - kDecisionTime;
     226                branchEnd = kBranch3End;
     227                break;
     228        case kSubBranch4:
     229                branchStart = kBranch4End - kDecisionTime;
     230                branchEnd = kBranch4End;
     231                break;
     232        case kSubBranch5:
     233                branchStart = kBranch5End - kDecisionTime;
     234                branchEnd = kBranch5End;
     235                break;
     236        case kSubBranch6:
     237                branchStart = kBranch6End - kDecisionTime;
     238                branchEnd = kBranch6End;
     239                break;
     240        case kSubBranch7Left:
     241                branchStart = kBranch7LeftEnd - kDecisionTime;
     242                branchEnd = kBranch7LeftEnd;
     243                break;
     244        case kSubBranch7Right:
     245                branchStart = kBranch7RightEnd - kDecisionTime;
     246                branchEnd = kBranch7RightEnd;
     247                break;
     248        default:
     249                break;
     250        }
     251       
     252        _subMovie.setSegment(branchStart, branchEnd);
     253       
     254        _subCallBack.setCallBackFlag(kChaseExitedBranchZone);
     255        _subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     256}
     257
     258void SubChase::branchLeft() {
     259        TimeValue branchStart, branchEnd;
     260        NotificationFlags flag;
     261       
     262        branchStart = 0;
     263        branchEnd = 0;
     264        flag = 0;
     265        switch (_subState) {
     266        case kSubDialog:
     267        case kSubBranch1:
     268                branchStart = kBranch2LeftStart;
     269                branchEnd = kBranch2LeftEnd;
     270                // Don't show the controls hint when we approach the whale
     271                // since the branch segments here are identical
     272                flag = kChaseExitedBranchZone;
     273                _subState = kSubBranch2Left;
     274                break;
     275        case kSubBranch2Left:
     276        case kSubBranch2Right:
     277                branchStart = kBranch3Start;
     278                branchEnd = kBranch3End - kDecisionTime;
     279                flag = kChaseEnteredBranchZone;
     280                _subState = kSubBranch3;
     281                break;
     282        case kSubBranch3:
     283                branchStart = kBranch4Start;
     284                branchEnd = kBranch4End - kDecisionTime;
     285                flag = kChaseEnteredBranchZone;
     286                _subState = kSubBranch4;
     287                break;
     288        case kSubBranch4:
     289                branchStart = kDeath5Start;
     290                branchEnd = kDeath5End;
     291                flag = kChaseFinished;
     292                _subState = kSubBranch5;
     293                break;
     294        case kSubBranch5:
     295                branchStart = kBranch6Start;
     296                branchEnd = kBranch6End - kDecisionTime;
     297                flag = kChaseEnteredBranchZone;
     298                _subState = kSubBranch6;
     299                break;
     300        case kSubBranch6:
     301                branchStart = kBranch7LeftStart;
     302                branchEnd = kBranch7LeftEnd;
     303                flag = kChaseExitedBranchZone;
     304                _subState = kSubBranch7Left;
     305                break;
     306        case kSubBranch7Left:
     307        case kSubBranch7Right:
     308                branchStart = kExitStart;
     309                branchEnd = kExitEnd;
     310                flag = kChaseFinished;
     311                _subState = kSubExit;
     312                break;
     313        default:
     314                break;
     315        }
     316       
     317        _subMovie.setSegment(branchStart, branchEnd);
     318        _subMovie.setTime(branchStart);
     319       
     320        _subCallBack.setCallBackFlag(flag);
     321        _subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     322}
     323
     324void SubChase::branchRight() {
     325        TimeValue branchStart, branchEnd;
     326        NotificationFlags flag;
     327       
     328        branchStart = 0;
     329        branchEnd = 0;
     330        flag = 0;
     331        switch (_subState) {
     332        case kSubDialog:
     333        case kSubBranch1:
     334                branchStart = kBranch2RightStart;
     335                branchEnd = kBranch2RightEnd;
     336                // Don't show the controls hint when we approach the whale
     337                // since the branch segments here are identical
     338                flag = kChaseExitedBranchZone;
     339                _subState = kSubBranch2Right;
     340                break;
     341        case kSubBranch2Left:
     342        case kSubBranch2Right:
     343                branchStart = kBranch3Start;
     344                branchEnd = kBranch3End - kDecisionTime;
     345                flag = kChaseEnteredBranchZone;
     346                _subState = kSubBranch3;
     347                break;
     348        case kSubBranch3:
     349                branchStart = kDeath4Start;
     350                branchEnd = kDeath4End;
     351                flag = kChaseFinished;
     352                _subState = kSubBranch4;
     353                break;
     354        case kSubBranch4:
     355                branchStart = kBranch5Start;
     356                branchEnd = kBranch5End - kDecisionTime;
     357                flag = kChaseEnteredBranchZone;
     358                _subState = kSubBranch5;
     359                break;
     360        case kSubBranch5:
     361                branchStart = kDeath6Start;
     362                branchEnd = kDeath6End;
     363                flag = kChaseFinished;
     364                _subState = kSubBranch6;
     365                break;
     366        case kSubBranch6:
     367                if (((PegasusEngine *)g_engine)->getRandomBit()) {
     368                        branchStart = kBranch7RightStart;
     369                        branchEnd = kBranch7RightEnd;
     370                        flag = kChaseExitedBranchZone;
     371                } else {
     372                        branchStart = kDeath7Start;
     373                        branchEnd = kDeath7End;
     374                        flag = kChaseFinished;
     375                }
     376                _subState = kSubBranch7Right;
     377                break;
     378        case kSubBranch7Left:
     379        case kSubBranch7Right:
     380                branchStart = kExitStart;
     381                branchEnd = kExitEnd;
     382                flag = kChaseFinished;
     383                _subState = kSubExit;
     384                break;
     385        default:
     386                break;
     387        }
     388
     389        _subMovie.setSegment(branchStart, branchEnd);
     390        _subMovie.setTime(branchStart);
     391       
     392        _subCallBack.setCallBackFlag(flag);
     393        _subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     394}
     395
     396void SubChase::dontBranch() {
     397        if (((PegasusEngine *)g_engine)->getRandomBit())
     398                branchLeft();
     399        else
     400                branchRight();
     401}
     402
     403void SubChase::startHintTimer(TimeValue time, TimeScale scale, HintTimerCode code) {
     404        if (_canSteerSub) {
     405                _hintFuse.primeFuse(time, scale);
     406                _hintEvent.subChase = this;
     407                _hintEvent.theEvent = code;
     408                _hintFuse.setFunctor(new Common::Functor0Mem<void, HintTimerEvent>(&_hintEvent, &HintTimerEvent::fire));
     409                _hintFuse.lightFuse();
     410        }
     411}
     412
     413void SubChase::hintTimerExpired(HintTimerEvent &event) {
     414        switch (event.theEvent) {
     415        case kStartedHint:
     416                _hintPict.show();
     417                startBlinkTimer(10, 10, kEnteredBlinkState);
     418                startHintTimer(3920, kSubChaseScale, kEndedHint);
     419                break;
     420        case kEndedHint:
     421                _hintPict.hide();
     422                _blinkPict.hide();
     423                _blinkFuse.stopFuse();
     424                break;
     425        default:
     426                break;
     427        }
     428}
     429
     430void SubChase::startBlinkTimer(TimeValue time, TimeScale scale, BlinkTimerCode code) {
     431        _blinkFuse.primeFuse(time, scale);
     432        _blinkEvent.subChase = this;
     433        _blinkEvent.theEvent = code;
     434        _blinkFuse.setFunctor(new Common::Functor0Mem<void, BlinkTimerEvent>(&_blinkEvent, &BlinkTimerEvent::fire));
     435        _blinkFuse.lightFuse();
     436}
     437
     438void SubChase::blinkTimerExpired(BlinkTimerEvent &event) {
     439        switch (event.theEvent) {
     440        case kEnteredBlinkState:
     441                _hintPict.hide();
     442                _blinkPict.show();
     443                startBlinkTimer(5, 10, kExitedBlinkState);
     444                break;
     445        case kExitedBlinkState:
     446                _blinkPict.hide();
     447                _hintPict.show();
     448                startBlinkTimer(10, 10, kEnteredBlinkState);
     449                break;
     450        default:
     451                break;
     452        }
     453}
     454
     455} // End of namespace Pegasus
  • new file engines/pegasus/neighborhood/norad/alpha/subchase.h

    diff --git a/engines/pegasus/neighborhood/norad/alpha/subchase.h b/engines/pegasus/neighborhood/norad/alpha/subchase.h
    new file mode 100644
    index 0000000..6eeb6d5
    - +  
     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 * Additional copyright for this file:
     8 * Copyright (C) 1995-2013 Presto Studios, Inc.
     9 *
     10 * This program is free software; you can redistribute it and/or
     11 * modify it under the terms of the GNU General Public License
     12 * as published by the Free Software Foundation; either version 2
     13 * of the License, or (at your option) any later version.
     14
     15 * This program is distributed in the hope that it will be useful,
     16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18 * GNU General Public License for more details.
     19
     20 * You should have received a copy of the GNU General Public License
     21 * along with this program; if not, write to the Free Software
     22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     23 *
     24 */
     25
     26#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_SUBCHASE_H
     27#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_SUBCHASE_H
     28
     29#include "pegasus/chase.h"
     30#include "pegasus/movie.h"
     31
     32namespace Pegasus {
     33
     34class NoradAlpha;
     35class SubChase;
     36
     37enum HintTimerCode {
     38        kStartedHint,
     39        kEndedHint
     40};
     41
     42struct HintTimerEvent {
     43        SubChase *subChase;
     44        HintTimerCode theEvent;
     45
     46        void fire();
     47};
     48
     49enum BlinkTimerCode {
     50        kEnteredBlinkState,
     51        kExitedBlinkState
     52};
     53
     54struct BlinkTimerEvent {
     55        SubChase *subChase;
     56        BlinkTimerCode theEvent;
     57
     58        void fire();
     59};
     60
     61class SubChase : public ChaseInteraction {
     62friend class NoradAlpha;
     63friend struct HintTimerEvent;
     64friend struct BlinkTimerEvent;
     65public:
     66
     67        SubChase(Neighborhood *);
     68        virtual ~SubChase() {}
     69
     70        void handleInput(const Input &, const Hotspot *);
     71
     72protected:
     73
     74        void openInteraction();
     75        void initInteraction();
     76        void closeInteraction();
     77       
     78        void receiveNotification(Notification *, const NotificationFlags);
     79       
     80        void startBranching();
     81        void setUpBranch();
     82        void branchLeft();
     83        void branchRight();
     84        void dontBranch();
     85       
     86        void startHintTimer(TimeValue, TimeScale, HintTimerCode);
     87        void hintTimerExpired(HintTimerEvent &);
     88       
     89        void startBlinkTimer(TimeValue, TimeScale, BlinkTimerCode);
     90        void blinkTimerExpired(BlinkTimerEvent &);
     91       
     92        Movie _subMovie;
     93        NotificationCallBack _subCallBack;
     94        Picture _hintPict;
     95        Picture _blinkPict;
     96        FuseFunction _hintFuse;
     97        FuseFunction _blinkFuse;
     98       
     99        HintTimerEvent _hintEvent;
     100        BlinkTimerEvent _blinkEvent;
     101       
     102        short _subState;
     103
     104        bool _canSteerSub;
     105};
     106
     107} // End of namespace Pegasus
     108
     109#endif
  • engines/pegasus/neighborhood/norad/constants.h

    diff --git a/engines/pegasus/neighborhood/norad/constants.h b/engines/pegasus/neighborhood/norad/constants.h
    index 37c1769..68e4bcf 100644
    a b static const InteractionID kNoradElevatorInteractionID = 3;  
    216216static const InteractionID kNoradPressureDoorInteractionID = 4;
    217217static const InteractionID kNoradSubControlRoomInteractionID = 5;
    218218static const InteractionID kNoradSubPlatformInteractionID = 6;
     219static const InteractionID kNoradSubChaseInteractionID = 7;
    219220
    220221/////////////////////////////////////////////
    221222//
    static const CoordType kNoradLowerDownTop = kNavAreaTop + 212;  
    265266static const CoordType kNoradPlatformLeft = kNavAreaLeft + 36;
    266267static const CoordType kNoradPlatformTop = kNavAreaTop + 87;
    267268
     269static const CoordType kNoradSubSteerLeft = 288;
     270static const CoordType kNoradSubSteerTop = 28;
     271
     272static const CoordType kNoradSubHintLeft = 480;
     273static const CoordType kNoradSubHintTop = 240;
     274
    268275static const CoordType kNoradSubControlLeft = kNavAreaLeft + 0;
    269276static const CoordType kNoradSubControlTop = kNavAreaTop + 84;
    270277
    static const DisplayElementID kClawMonitorGreenBallID = kSubControlCWID + 1;  
    385392
    386393// Norad Delta display IDs.
    387394
    388 static const DisplayElementID kGlobeMonitorID = kNeighborhoodDisplayID;
    389 static const DisplayElementID kGlobeMovieID = kGlobeMonitorID + 14;
     395static const DisplayElementID kGlobeRobotID = kNeighborhoodDisplayID;
     396static const DisplayElementID kGlobeMonitorID = kGlobeRobotID + 1;
     397static const DisplayElementID kGlobeMovieID = kGlobeMonitorID + 1;
    390398static const DisplayElementID kGlobeCircleLeftID = kGlobeMovieID + 1;
    391399static const DisplayElementID kGlobeCircleRightID = kGlobeCircleLeftID + 1;
    392400static const DisplayElementID kGlobeCircleUpID = kGlobeCircleRightID + 1;
  • engines/pegasus/neighborhood/norad/delta/globegame.cpp

    diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.cpp b/engines/pegasus/neighborhood/norad/delta/globegame.cpp
    index 0b95e9b..db90daf 100644
    a b  
    2525
    2626#include "pegasus/cursor.h"
    2727#include "pegasus/pegasus.h"
     28#include "pegasus/items/biochips/arthurchip.h"
    2829#include "pegasus/neighborhood/norad/constants.h"
    2930#include "pegasus/neighborhood/norad/delta/globegame.h"
    3031#include "pegasus/neighborhood/norad/delta/noraddelta.h"
    static const TimeValue kGlobeMovieStartTime = 2 * 2 * kNumLongSlices * 600 / 15;  
    387388static const TimeValue kTimePerGlobeFrame = 40;
    388389
    389390static const NotificationFlags kGlobeSplash1Finished = 1;
    390 static const NotificationFlags kGlobeTimerExpired = kGlobeSplash1Finished << 1;
     391static const NotificationFlags kGlobeRobot1Finished = kGlobeSplash1Finished << 1;
     392static const NotificationFlags kGlobeRobot2Finished = kGlobeRobot1Finished << 1;
     393static const NotificationFlags kGlobeRobot3Finished = kGlobeRobot2Finished << 1;
     394static const NotificationFlags kGlobeRobot4Finished = kGlobeRobot3Finished << 1;
     395static const NotificationFlags kGlobeRobot5Finished = kGlobeRobot4Finished << 1;
     396static const NotificationFlags kGlobeRobot6Finished = kGlobeRobot5Finished << 1;
     397static const NotificationFlags kGlobeTimerExpired = kGlobeRobot6Finished << 1;
    391398static const NotificationFlags kMaxDeactivatedFinished = kGlobeTimerExpired << 1;
    392399
    393400static const NotificationFlags kGlobeNotificationFlags = kGlobeSplash1Finished |
     401                                                                                                        kGlobeRobot1Finished |
     402                                                                                                        kGlobeRobot2Finished |
     403                                                                                                        kGlobeRobot3Finished |
     404                                                                                                        kGlobeRobot4Finished |
     405                                                                                                        kGlobeRobot5Finished |
     406                                                                                                        kGlobeRobot6Finished |
    394407                                                                                                        kGlobeTimerExpired |
    395408                                                                                                        kMaxDeactivatedFinished;
    396409
    float radiansToDegrees(float angle) {  
    440453}
    441454
    442455GlobeGame::GlobeGame(Neighborhood *handler) : GameInteraction(kNoradGlobeGameInteractionID, handler),
    443                 _monitorMovie(kGlobeMonitorID), _globeMovie(kGlobeMovieID), _upperNamesMovie(kGlobeUpperNamesID),
    444                 _lowerNamesMovie(kGlobeLowerNamesID), _globeNotification(kNoradGlobeNotificationID, (PegasusEngine *)g_engine),
    445                 _globeCircleLeft(kGlobeCircleLeftID), _globeCircleRight(kGlobeCircleRightID),
    446                 _globeCircleUp(kGlobeCircleUpID), _globeCircleDown(kGlobeCircleDownID),
     456                _robotMovie(kGlobeRobotID), _monitorMovie(kGlobeMonitorID), _globeMovie(kGlobeMovieID),
     457                _upperNamesMovie(kGlobeUpperNamesID), _lowerNamesMovie(kGlobeLowerNamesID),
     458                _globeNotification(kNoradGlobeNotificationID, (PegasusEngine *)g_engine), _globeCircleLeft(kGlobeCircleLeftID),
     459                _globeCircleRight(kGlobeCircleRightID), _globeCircleUp(kGlobeCircleUpID), _globeCircleDown(kGlobeCircleDownID),
    447460                _motionHighlightLeft(kMotionHiliteLeftID), _motionHighlightRight(kMotionHiliteRightID),
    448461                _motionHighlightUp(kMotionHiliteUpID), _motionHighlightDown(kMotionHiliteDownID),
    449462                _targetHighlightUpperLeft(kTargetHiliteUpperLeftID), _targetHighlightUpperRight(kTargetHiliteUpperRightID),
    GlobeGame::GlobeGame(Neighborhood *handler) : GameInteraction(kNoradGlobeGameInt  
    454467}
    455468
    456469void GlobeGame::openInteraction() {
     470        if (((PegasusEngine *)g_engine)->isDVD()) {
     471                _robotMovie.initFromMovieFile("Images/Norad Delta/N79 Back Monitor1");
     472                _robotMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     473                _robotMovie.setDisplayOrder(kGlobeMonitorLayer);
     474                _robotMovie.startDisplaying();
     475                _robotMovie.show();
     476
     477                _robotCallBack.setNotification(&_globeNotification);
     478                _robotCallBack.initCallBack(&_robotMovie, kCallBackAtExtremes);
     479                _robotCallBack.setCallBackFlag(kGlobeRobot1Finished);
     480                _robotCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     481        }
     482
    457483        _monitorMovie.initFromMovieFile("Images/Norad Delta/N79 Left Monitor");
    458484        _monitorMovie.moveElementTo(kGlobeMonitorLeft, kGlobeMonitorTop);
    459485        _monitorMovie.setDisplayOrder(kGlobeMonitorLayer);
    void GlobeGame::openInteraction() {  
    563589}
    564590
    565591void GlobeGame::initInteraction() {
     592        if (((PegasusEngine *)g_engine)->isDVD())
     593                _robotMovie.start();
    566594        _monitorMovie.start();
    567595        _monitorMovie.redrawMovieWorld();
    568596}
    569597
    570598void GlobeGame::closeInteraction() {
     599        if (((PegasusEngine *)g_engine)->isDVD()) {
     600                _robotMovie.stop();
     601                _robotMovie.stopDisplaying();
     602                _robotMovie.releaseMovie();
     603                _robotCallBack.releaseCallBack();
     604        }
     605
    571606        _monitorMovie.stop();
    572607        _monitorMovie.stopDisplaying();
    573608        _monitorMovie.releaseMovie();
    void GlobeGame::receiveNotification(Notification *notification, const Notificati  
    626661        if (notification == _neighborhoodNotification) {
    627662                switch (_gameState) {
    628663                case kPlayingRobotIntro:
    629                         _monitorMovie.stop();
    630                         _monitorMovie.setSegment(0, _monitorMovie.getDuration());
    631                         _monitorMovie.setTime(kSplash2End * scale - 1);
    632                         _monitorMovie.redrawMovieWorld();
    633                         _monitorMovie.setFlags(0);
     664                        if (!((PegasusEngine *)g_engine)->isDVD()) {
     665                                _monitorMovie.stop();
     666                                _monitorMovie.setSegment(0, _monitorMovie.getDuration());
     667                                _monitorMovie.setTime(kSplash2End * scale - 1);
     668                                _monitorMovie.redrawMovieWorld();
     669                                _monitorMovie.setFlags(0);
    634670
    635                         _owner->requestDelay(1, 2, kFilterNoInput, 0);
    636                         _owner->requestSpotSound(kStrikeAuthorizedIn, kStrikeAuthorizedOut,
    637                                         kFilterNoInput, kSpotSoundCompletedFlag);
    638                         _gameState = kPlayingStrikeAuthorized;
     671                                _owner->requestDelay(1, 2, kFilterNoInput, 0);
     672                                _owner->requestSpotSound(kStrikeAuthorizedIn, kStrikeAuthorizedOut,
     673                                                kFilterNoInput, kSpotSoundCompletedFlag);
     674                                _gameState = kPlayingStrikeAuthorized;
     675                        }
    639676                        break;
    640677                case kPlayingStrikeAuthorized:
    641678                        _monitorMovie.setSegment(kSplash3Start * scale, kSplash3Stop * scale);
    void GlobeGame::receiveNotification(Notification *notification, const Notificati  
    741778
    742779                        switch (_currentSiloIndex) {
    743780                        case 3:
    744                                 _owner->requestSpotSound(kYouCannotPossiblyIn, kYouCannotPossiblyOut,
    745                                                 kFilterNoInput, kSpotSoundCompletedFlag);
     781                                if (!((PegasusEngine *)g_engine)->isDVD()) {
     782                                        _owner->requestSpotSound(kYouCannotPossiblyIn, kYouCannotPossiblyOut,
     783                                                        kFilterNoInput, kSpotSoundCompletedFlag);
     784                                } else {
     785                                        _robotMovie.hide();
     786                                        _robotMovie.stopDisplaying();
     787                                        _robotMovie.releaseMovie();
     788
     789                                        _robotMovie.initFromMovieFile("Images/Norad Delta/N79 Back Monitor2");
     790                                        _robotMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     791                                        _robotMovie.startDisplaying();
     792                                        _robotMovie.show();
     793                                        _robotMovie.start();
     794
     795                                        _owner->requestDelay(_robotMovie.getDuration(), 0, kFilterNoInput, kDelayCompletedFlag);
     796                                }
    746797                                break;
    747798                        case 5:
    748                                 _owner->requestSpotSound(kYouWillFailIn, kYouWillFailOut, kFilterNoInput,
    749                                                 kSpotSoundCompletedFlag);
     799                                if (!((PegasusEngine *)g_engine)->isDVD()) {
     800                                        _owner->requestSpotSound(kYouWillFailIn, kYouWillFailOut, kFilterNoInput,
     801                                                        kSpotSoundCompletedFlag);
     802                                } else {
     803                                        _robotMovie.hide();
     804                                        _robotMovie.stopDisplaying();
     805                                        _robotMovie.releaseMovie();
     806
     807                                        _robotMovie.initFromMovieFile("Images/Norad Delta/N79 Back Monitor3");
     808                                        _robotMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     809                                        _robotMovie.startDisplaying();
     810                                        _robotMovie.show();
     811                                        _robotMovie.start();
     812
     813                                        _owner->requestDelay(_robotMovie.getDuration(), 0, kFilterNoInput, kDelayCompletedFlag);
     814                                }
    750815                                break;
    751816                        case 7:
    752                                 _owner->requestSpotSound(kGiveUpHumanIn, kGiveUpHumanOut, kFilterNoInput,
    753                                                 kSpotSoundCompletedFlag);
     817                                if (!((PegasusEngine *)g_engine)->isDVD()) {
     818                                        _owner->requestSpotSound(kGiveUpHumanIn, kGiveUpHumanOut, kFilterNoInput,
     819                                                        kSpotSoundCompletedFlag);
     820                                } else {
     821                                        _robotMovie.hide();
     822                                        _robotMovie.stopDisplaying();
     823                                        _robotMovie.releaseMovie();
     824
     825                                        _robotMovie.initFromMovieFile("Images/Norad Delta/N79 Back Monitor4");
     826                                        _robotMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     827                                        _robotMovie.startDisplaying();
     828                                        _robotMovie.show();
     829                                        _robotMovie.start();
     830
     831                                        _owner->requestDelay(_robotMovie.getDuration(), 0, kFilterNoInput, kDelayCompletedFlag);
     832                                }
    754833                                break;
    755834                        case 9:
    756                                 _owner->requestSpotSound(kYouAreRunningIn, kYouAreRunningOut,
    757                                                 kFilterNoInput, kSpotSoundCompletedFlag);
     835                                if (!((PegasusEngine *)g_engine)->isDVD()) {
     836                                        _owner->requestSpotSound(kYouAreRunningIn, kYouAreRunningOut,
     837                                                        kFilterNoInput, kSpotSoundCompletedFlag);
     838                                } else {
     839                                        _robotMovie.hide();
     840                                        _robotMovie.stopDisplaying();
     841                                        _robotMovie.releaseMovie();
     842
     843                                        _robotMovie.initFromMovieFile("Images/Norad Delta/N79 Back Monitor5");
     844                                        _robotMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     845                                        _robotMovie.startDisplaying();
     846                                        _robotMovie.show();
     847                                        _robotMovie.start();
     848
     849                                        _owner->requestDelay(_robotMovie.getDuration(), 0, kFilterNoInput, kDelayCompletedFlag);
     850                                }
    758851                                break;
    759852                        default:
    760853                                _owner->requestSpotSound(kNewLaunchSiloIn, kNewLaunchSiloOut,
    void GlobeGame::receiveNotification(Notification *notification, const Notificati  
    766859                        }
    767860                        break;
    768861                case kRobotTaunting:
    769                         _owner->requestDelay(1, 1, kFilterNoInput, 0);
     862                        _owner->requestDelay(1, 2, kFilterNoInput, 0);
    770863                        _owner->requestSpotSound(kNewLaunchSiloIn, kNewLaunchSiloOut, kFilterNoInput, kSpotSoundCompletedFlag);
    771864                        _monitorMovie.setTime(kNewLaunchSiloTime * scale);
    772865                        _monitorMovie.redrawMovieWorld();
    void GlobeGame::receiveNotification(Notification *notification, const Notificati  
    790883
    791884                switch (flags) {
    792885                case kGlobeSplash1Finished:
    793                         _owner->getExtraEntry(kN79BrightView, entry);
    794886                        _monitorMovie.stop();
    795887                        _monitorMovie.setSegment(kSplash1End * scale, kSplash2End * scale);
    796888                        _monitorMovie.setFlags(kLoopTimeBase);
    797889                        _monitorMovie.start();
    798                         _owner->showViewFrame(entry.movieStart);
    799                         _owner->requestSpotSound(kIJustBrokeIn, kIJustBrokeOut, kFilterNoInput, 0);
    800                         _owner->requestDelay(1, 2, kFilterNoInput, kDelayCompletedFlag);
    801                         _gameState = kPlayingRobotIntro;
     890                        if (!((PegasusEngine *)g_engine)->isDVD()) {
     891                                _owner->getExtraEntry(kN79BrightView, entry);
     892                                _owner->showViewFrame(entry.movieStart);
     893                                _owner->requestSpotSound(kIJustBrokeIn, kIJustBrokeOut, kFilterNoInput, 0);
     894                                _owner->requestDelay(1, 2, kFilterNoInput, kDelayCompletedFlag);
     895                                _gameState = kPlayingRobotIntro;
     896                        }
     897                        break;
     898                case kGlobeRobot1Finished:
     899                        if (((PegasusEngine *)g_engine)->isDVD()) {
     900                                _owner->getExtraEntry(kN79BrightView, entry);
     901                                _monitorMovie.stop();
     902                                _monitorMovie.setSegment(0, _monitorMovie.getDuration());
     903                                _monitorMovie.setTime(kSplash2End * scale - 1);
     904                                _monitorMovie.redrawMovieWorld();
     905                                _monitorMovie.setFlags(0);
     906
     907                                _owner->showViewFrame(entry.movieStart);
     908                                _owner->requestDelay(1, 2, kFilterNoInput, 0);
     909                                _owner->requestSpotSound(kStrikeAuthorizedIn, kStrikeAuthorizedOut,
     910                                                kFilterNoInput, kSpotSoundCompletedFlag);
     911
     912                                _gameState = kPlayingStrikeAuthorized;
     913                        }
    802914                        break;
    803915                case kGlobeTimerExpired:
    804916                        // Missile launched, player loses.
     917                        _upperNamesMovie.hide();
     918                        _lowerNamesMovie.hide();
     919                        _countdown.hide();
     920                        _monitorMovie.setTime(kMissileLaunchedTime * scale);
     921                        _monitorMovie.redrawMovieWorld();
    805922                        _owner->requestSpotSound(kMissileLaunchedIn, kMissileLaunchedOut, kFilterNoInput, kSpotSoundCompletedFlag);
    806923                        _gameState = kPlayerLost1;
    807924                        break;
    808925                case kMaxDeactivatedFinished:
    809926                        _monitorMovie.stop();
    810927                        _monitorMovie.setSegment(0, _monitorMovie.getDuration());
    811                         _owner->requestDelay(1, 2, kFilterNoInput, 0);
    812                         _owner->requestSpotSound(kTheOnlyGoodHumanIn, kTheOnlyGoodHumanOut, kFilterNoInput, 0);
    813                         _owner->requestDelay(1, 2, kFilterNoInput, kDelayCompletedFlag);
     928                        if (g_arthurChip)
     929                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA02", kArthurNoradFinishedGlobeGame);
     930                        if (!((PegasusEngine *)g_engine)->isDVD()) {
     931                                _owner->requestDelay(1, 2, kFilterNoInput, 0);
     932                                _owner->requestSpotSound(kTheOnlyGoodHumanIn, kTheOnlyGoodHumanOut, kFilterNoInput, 0);
     933                                _owner->requestDelay(1, 2, kFilterNoInput, kDelayCompletedFlag);
     934                        } else {
     935                                _robotMovie.hide();
     936                                _robotMovie.stopDisplaying();
     937                                _robotMovie.releaseMovie();
     938
     939                                _robotMovie.initFromMovieFile("Images/Norad Delta/N79 Back Monitor6");
     940                                _robotMovie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     941                                _robotMovie.setDisplayOrder(kGlobeCountdownLayer + 1);
     942                                _robotMovie.startDisplaying();
     943                                _robotMovie.show();
     944                                _robotMovie.start();
     945
     946                                _owner->requestDelay(_robotMovie.getDuration(), 0, kFilterNoInput, kDelayCompletedFlag);
     947                        }
    814948                        _gameState = kPlayerWon2;
    815949                        break;
    816950                default:
    void GlobeGame::spinGlobe(const Input &input, const Hotspot *spot, GlobeTrackDir  
    8741008}
    8751009
    8761010void GlobeGame::clickGlobe(const Input &input) {
    877         int16 newSilo = findClickedSilo(input);
    878 
    879         if (newSilo != -1) {
    880                 _targetHighlightUpperLeft.hide();
    881                 _targetHighlightUpperRight.hide();
    882                 _targetHighlightLowerLeft.hide();
    883                 _targetHighlightLowerRight.hide();
    884                 _lowerNamesMovie.show();
    885                 _lowerNamesMovie.setTime(newSilo * _lowerNamesMovie.getScale());
    886                 _lowerNamesMovie.redrawMovieWorld();
    887                 _owner->requestSpotSound(kSiloBeepIn, kSiloBeepOut, kFilterNoInput, 0);
     1011        Movie movie(kNoDisplayElement);
     1012        Input movieInput;
     1013
     1014        if (((PegasusEngine *)g_engine)->isDVD() && JMPPPInput::isEasterEggModifierInput(input)) {
     1015                ((PegasusEngine *)g_engine)->_cursor->hide();
     1016
     1017                movie.initFromMovieFile("Images/Norad Delta/N79 Back Monitor7");
     1018                movie.setVolume(((PegasusEngine *)g_engine)->getSoundFXLevel());
     1019                movie.moveElementTo(kNavAreaLeft, kNavAreaTop);
     1020                movie.setDisplayOrder(kGlobeCountdownLayer + 1);
     1021                movie.startDisplaying();
     1022                movie.show();
     1023                movie.start();
     1024
     1025                while (movie.isRunning() && !((PegasusEngine *)g_engine)->shouldQuit()) {
     1026                        InputDevice.getInput(movieInput, kFilterNoInput);
     1027
     1028                        ((PegasusEngine *)g_engine)->checkCallBacks();
     1029                        ((PegasusEngine *)g_engine)->refreshDisplay();
     1030                        ((PegasusEngine *)g_engine)->_system->delayMillis(10);
     1031                }
    8881032
    889                 if (newSilo == _targetSilo[_currentSiloIndex]) {
    890                         _currentSiloIndex++;
    891                         _countdown.stopCountdown();
    892                         _owner->requestSpotSound(kSiloDeactivatedIn, kSiloDeactivatedOut, kFilterNoInput, 0);
     1033                if (((PegasusEngine *)g_engine)->shouldQuit())
     1034                        return;
    8931035
    894                         if (_currentSiloIndex == kNumTargetSilos) {
    895                                 // Player won.
    896                                 _owner->requestDelay(1, 2, kFilterNoInput, 0);
    897                                 _upperNamesMovie.hide();
    898                                 _lowerNamesMovie.hide();
    899                                 _countdown.hide();
    900                                 _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale(),
    901                                                 kMaxDeactivatedStop * _monitorMovie.getScale());
    902                                 _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale());
    903                                 _monitorCallBack.setCallBackFlag(kMaxDeactivatedFinished);
    904                                 _monitorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
    905                                 _monitorMovie.start();
    906                                 _owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut,
    907                                                 kFilterNoInput, kSpotSoundCompletedFlag);
     1036                movie.hide();
     1037                movie.stopDisplaying();
     1038                movie.releaseMovie();
    9081039
    909                                 // This sound was left out of the original.
    910                                 _owner->requestSpotSound(kAllSilosDeactivatedIn, kAllSilosDeactivatedOut,
    911                                                 kFilterNoInput, kSpotSoundCompletedFlag);
    912 
    913                                 _gameState = kPlayerWon1;
     1040                ((PegasusEngine *)g_engine)->_cursor->hideUntilMoved();
     1041        } else {
     1042                int16 newSilo = findClickedSilo(input);
     1043                if (newSilo != -1) {
     1044                        _targetHighlightUpperLeft.hide();
     1045                        _targetHighlightUpperRight.hide();
     1046                        _targetHighlightLowerLeft.hide();
     1047                        _targetHighlightLowerRight.hide();
     1048                        _lowerNamesMovie.show();
     1049                        _lowerNamesMovie.setTime(newSilo * _lowerNamesMovie.getScale());
     1050                        _lowerNamesMovie.redrawMovieWorld();
     1051                        _owner->requestSpotSound(kSiloBeepIn, kSiloBeepOut, kFilterNoInput, 0);
     1052
     1053                        if (newSilo == _targetSilo[_currentSiloIndex]) {
     1054                                _currentSiloIndex++;
     1055                                _countdown.stopCountdown();
     1056                                _owner->requestSpotSound(kSiloDeactivatedIn, kSiloDeactivatedOut, kFilterNoInput, 0);
     1057
     1058                                if (_currentSiloIndex == kNumTargetSilos) {
     1059                                        // Player won.
     1060                                        _owner->requestDelay(1, 2, kFilterNoInput, 0);
     1061                                        _upperNamesMovie.hide();
     1062                                        _lowerNamesMovie.hide();
     1063                                        _countdown.hide();
     1064                                        _monitorMovie.setSegment(kMaxDeactivatedStart * _monitorMovie.getScale(),
     1065                                                        kMaxDeactivatedStop * _monitorMovie.getScale());
     1066                                        _monitorMovie.setTime(kMaxDeactivatedStart * _monitorMovie.getScale());
     1067                                        _monitorCallBack.setCallBackFlag(kMaxDeactivatedFinished);
     1068                                        _monitorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     1069                                        _monitorMovie.start();
     1070                                        _owner->requestSpotSound(kMaximumDeactivationIn, kMaximumDeactivationOut,
     1071                                                        kFilterNoInput, kSpotSoundCompletedFlag);
     1072
     1073                                        // This sound was left out of the original.
     1074                                        _owner->requestSpotSound(kAllSilosDeactivatedIn, kAllSilosDeactivatedOut,
     1075                                                        kFilterNoInput, kSpotSoundCompletedFlag);
     1076
     1077                                        _gameState = kPlayerWon1;
     1078                                } else {
     1079                                        _owner->requestDelay(1, 2, kFilterNoInput, kDelayCompletedFlag);
     1080                                        _upperNamesMovie.hide();
     1081                                        _lowerNamesMovie.hide();
     1082                                        _countdown.hide();
     1083                                        _monitorMovie.setTime(kSiloDeactivatedTime * _monitorMovie.getScale());
     1084                                        _monitorMovie.redrawMovieWorld();
     1085                                        _gameState = kSiloDeactivated;
     1086                                }
    9141087                        } else {
    915                                 _owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag);
    916                                 _upperNamesMovie.hide();
    917                                 _lowerNamesMovie.hide();
    918                                 _countdown.hide();
    919                                 _monitorMovie.setTime(kSiloDeactivatedTime * _monitorMovie.getScale());
    920                                 _monitorMovie.redrawMovieWorld();
    921                                 _gameState = kSiloDeactivated;
     1088                                _owner->requestDelay(5, 1, kFilterNoInput, kDelayCompletedFlag);
     1089                                _gameState = kDelayingPlayer;
     1090                                // Play "incorrect" sound?
     1091                                if (g_arthurChip)
     1092                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB38", kArthurNoradSelectedIncorrectSilo);
    9221093                        }
    923                 } else {
    924                         _owner->requestDelay(5, 1, kFilterNoInput, kDelayCompletedFlag);
    925                         _gameState = kDelayingPlayer;
    926                         // Play "incorrect" sound?
    9271094                }
    9281095        }
    9291096}
  • engines/pegasus/neighborhood/norad/delta/globegame.h

    diff --git a/engines/pegasus/neighborhood/norad/delta/globegame.h b/engines/pegasus/neighborhood/norad/delta/globegame.h
    index 73ed488..89c1afd 100644
    a b protected:  
    137137        void screenPointTo3DPoint(int16, int16, Point3D &);
    138138        bool lineHitsGlobe(const Line3D &, Point3D &);
    139139
     140        Movie _robotMovie;
    140141        Movie _monitorMovie;
    141142        Movie _globeMovie;
    142143        Movie _upperNamesMovie;
    143144        Movie _lowerNamesMovie;
    144145        Notification _globeNotification;
     146        NotificationCallBack _robotCallBack;
    145147        NotificationCallBack _monitorCallBack;
    146148        GlobeTracker _globeTracker;
    147149        Picture _globeCircleLeft;
  • engines/pegasus/neighborhood/norad/delta/noraddelta.cpp

    diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
    index 1eea2f0..e20ee96 100644
    a b  
    2828#include "pegasus/interface.h"
    2929#include "pegasus/pegasus.h"
    3030#include "pegasus/ai/ai_area.h"
     31#include "pegasus/items/biochips/arthurchip.h"
    3132#include "pegasus/items/biochips/opticalchip.h"
    3233#include "pegasus/items/biochips/retscanchip.h"
    3334#include "pegasus/items/inventory/airmask.h"
    void NoradDelta::loadAmbientLoops() {  
    265266        if (GameState.getNoradArrivedFromSub()) {
    266267                RoomID room = GameState.getCurrentRoom();
    267268
    268                 if (room == kNorad79West) {
    269                         if (_privateFlags.getFlag(kNoradPrivateFinishedGlobeGameFlag))
    270                                 loadLoopSound1("Sounds/Norad/GlobAmb2.22K.AIFF");
    271                         else
     269                if (room >= kNorad78 && room <= kNorad79West) {
     270                        if (GameState.getNoradPlayedGlobeGame()) {
     271                                // blitter moved clone2727's globe room loop fix up here
     272                                // since the original didn't play the red alert sound during the
     273                                // globe game.
     274
     275                                // clone2727 added this fix so we can play the correct sound
     276                                // with the DVD version. This originally loaded it into slot 2,
     277                                // which in addition to having the corrupted sound on the disk,
     278                                // caused it to never play.
     279                                if (_vm->isDVD())
     280                                        loadLoopSound1("Sounds/Norad/GlobAmb2.32K.AIFF");
     281                                else
     282                                        loadLoopSound1("Sounds/Norad/GlobAmb2.22K.AIFF");
     283                        } else
    272284                                loadLoopSound1("Sounds/Norad/RedAlert.22K.AIFF");
    273                 } else if (room >= kNorad78 && room <= kNorad79) {
    274                         // clone2727 says: This looks like it should be loadLoopSound1...
    275                         loadLoopSound2("Sounds/Norad/RedAlert.22K.AIFF");
    276285                } else if (GameState.getNoradGassed()) {
    277                         if (room >= kNorad41 && room <= kNorad49South)
    278                                 loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3);
    279                         else if (room >= kNorad59 && room <= kNorad60West)
    280                                 loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3);
    281                         else
    282                                 loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume);
     286                        if (room >= kNorad41 && room <= kNorad49South) {
     287                                if (_vm->isDVD())
     288                                        loadLoopSound1("Sounds/Norad/NEW SUB AMB.44K.AIFF", kNoradWarningVolume * 3);
     289                                else
     290                                        loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3);
     291                        } else if (room >= kNorad59 && room <= kNorad60West) {
     292                                if (_vm->isDVD())
     293                                        loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.32K.AIFF", kNoradWarningVolume * 3);
     294                                else
     295                                        loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3);
     296                        } else {
     297                                if (_vm->isDVD())
     298                                        loadLoopSound1("Sounds/Norad/WARNING LOOP.32K.AIFF", kNoradWarningVolume);
     299                                else
     300                                        loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume);
     301                        }
    283302                } else {
    284303                        loadLoopSound1("");
    285304                }
    void NoradDelta::loadAmbientLoops() {  
    290309                        else
    291310                                loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", kNoradSuckWindVolume, 0, 0);
    292311                } else {
    293                         if (room == kNorad54North)
    294                                 loadLoopSound2("Sounds/Norad/N54NAS.22K.AIFF", 0x100 / 2);
    295                         else
     312                        if (room == kNorad54North) {
     313                                if (_vm->isDVD())
     314                                        loadLoopSound2("Sounds/Norad/N54NAS.32K.AIFF", 0x100 / 2);
     315                                else
     316                                        loadLoopSound2("Sounds/Norad/N54NAS.22K.AIFF", 0x100 / 2);
     317                        } else
    296318                                loadLoopSound2("");
    297319                }
    298320        } else {
    299321                // Start them off at zero...
    300                 if (GameState.getNoradGassed())
    301                         loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", 0, 0, 0);
     322                if (GameState.getNoradGassed()) {
     323                        if (_vm->isDVD())
     324                                loadLoopSound1("Sounds/Norad/NEW SUB AMB.44K.AIFF", 0, 0, 0);
     325                        else
     326                                loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", 0, 0, 0);
     327                }
    302328                if (!g_airMask->isAirFilterOn())
    303329                        loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", 0, 0, 0);
    304330        }
    void NoradDelta::arriveAt(const RoomID room, const DirectionConstant direction)  
    328354
    329355        switch (room) {
    330356        case kNorad41:
    331                 if (direction == kEast && !GameState.getNoradArrivedFromSub()) {
    332                         GameState.setNoradPlayedGlobeGame(false);
     357                if (direction == kEast) {
     358                        if (!GameState.getNoradArrivedFromSub()) {
     359                                GameState.setNoradPlayedGlobeGame(false);
    333360
    334                         GameState.setNoradBeatRobotWithClaw(false);
    335                         GameState.setNoradBeatRobotWithDoor(false);
    336                         GameState.setNoradRetScanGood(false);
     361                                GameState.setNoradBeatRobotWithClaw(false);
     362                                GameState.setNoradBeatRobotWithDoor(false);
     363                                GameState.setNoradRetScanGood(false);
    337364
    338                         GameState.setScoringExitedSub(true);
     365                                GameState.setScoringExitedSub(true);
    339366
    340                         getExtraEntry(kArriveFromSubChase, entry);
     367                                getExtraEntry(kArriveFromSubChase, entry);
    341368
    342                         loop1Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
    343                                         entry.movieStart, kNoradWarningVolume);
    344                         loop1Spec.insertFaderKnot(7320, 0);
    345                         loop1Spec.insertFaderKnot(7880, kNoradWarningVolume);
     369                                loop1Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
     370                                                entry.movieStart, kNoradWarningVolume);
     371                                loop1Spec.insertFaderKnot(7320, 0);
     372                                loop1Spec.insertFaderKnot(7880, kNoradWarningVolume);
    346373
    347                         loop2Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
    348                                         entry.movieStart, kNoradSuckWindVolume);
    349                         loop1Spec.insertFaderKnot(7320, 0);
    350                         loop1Spec.insertFaderKnot(7880, kNoradSuckWindVolume);
     374                                loop2Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
     375                                                entry.movieStart, kNoradSuckWindVolume);
     376                                loop1Spec.insertFaderKnot(7320, 0);
     377                                loop1Spec.insertFaderKnot(7880, kNoradSuckWindVolume);
    351378
    352                         startExtraSequence(kArriveFromSubChase, kExtraCompletedFlag, kFilterNoInput);
     379                                startExtraSequence(kArriveFromSubChase, kExtraCompletedFlag, kFilterNoInput);
    353380
    354                         startLoop1Fader(loop1Spec);
    355                         startLoop2Fader(loop2Spec);
     381                                startLoop1Fader(loop1Spec);
     382                                startLoop2Fader(loop2Spec);
     383                        } else {
     384                                if (g_arthurChip)
     385                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA08", kArthurNoradExitedSub);
     386                        }
    356387                }
    357388                break;
     389        case kNorad54:
     390                if (g_arthurChip)
     391                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA71", kArthurNoradApproachedDamagedDoor);
     392                break;
    358393        case kNorad54North:
    359394                GameState.setScoringSawRobotAt54North(true);
    360395                break;
    361396        case kNorad68:
    362397                if (GameState.getNoradRetScanGood())
    363398                        openDoor();
     399                else if (!_vm->playerHasItemID(kRetinalScanBiochip) && g_arthurChip)
     400                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA39", kArthurNoradAtRetScanNoBiochip);
    364401                break;
    365402        case kNorad68West:
    366403                arriveAtNorad68West();
    void NoradDelta::arriveAtNorad79West() {  
    396433                newInteraction(kNoradGlobeGameInteractionID);
    397434}
    398435
     436void NoradDelta::turnTo(const DirectionConstant direction) {
     437        Norad::turnTo(direction);
     438        if (g_arthurChip) {
     439                switch (GameState.getCurrentRoomAndView()) {
     440                case MakeRoomView(kNorad54, kNorth):
     441                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA71", kArthurNoradApproachedDamagedDoor);
     442                        break;
     443                case MakeRoomView(kNorad68, kWest):
     444                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA39", kArthurNoradApproachedDamagedDoor);
     445                        break;
     446                }
     447        }
     448}
     449
    399450void NoradDelta::bumpIntoWall() {
    400451        requestSpotSound(kDeltaBumpIntoWallIn, kDeltaBumpIntoWallOut, kFilterNoInput, 0);
    401452        Neighborhood::bumpIntoWall();
    void NoradDelta::finishedGlobeGame() {  
    423474        _privateFlags.setFlag(kNoradPrivateFinishedGlobeGameFlag, true);
    424475        GameState.setScoringFinishedGlobeGame(true);
    425476        loadAmbientLoops();
    426         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN60WD1", false, kWarningInterruption);
     477        if (g_arthurChip)
     478                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA63", kArthurNoradThreatenedByRobot);
     479        if (g_AIArea->isChattyAI())
     480                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN60WD1", false, kWarningInterruption);
     481        updateViewFrame();
    427482}
    428483
    429484bool NoradDelta::playingAgainstRobot() {
    void NoradDelta::playerBeatRobotWithDoor() {  
    451506        GameState.setNoradBeatRobotWithDoor(true);
    452507        updateViewFrame();
    453508        GameState.setScoringStoppedNoradRobot(true);
    454         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
     509        if (g_AIArea->isChattyAI())
     510                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
    455511}
    456512
    457513void NoradDelta::playerBeatRobotWithClaw() {
    void NoradDelta::playerBeatRobotWithClaw() {  
    459515        updateViewFrame();
    460516        GameState.setScoringStoppedNoradRobot(true);
    461517        GameState.setScoringNoradGandhi(true);
    462         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
     518        if (g_AIArea->isChattyAI())
     519                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
    463520}
    464521
    465522TimeValue NoradDelta::getViewTime(const RoomID room, const DirectionConstant direction) {
    void NoradDelta::receiveNotification(Notification *notification, const Notificat  
    604661                case kN59RobotHeadOpens:
    605662                case kN60RobotHeadOpens:
    606663                        _privateFlags.setFlag(kNoradPrivateRobotHeadOpenFlag, true);
     664                        if (g_arthurChip) {
     665                                switch (_vm->getRandomNumber(2)) {
     666                                case 0:
     667                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA36", kArthurNoradRobotHeadOpen);
     668                                        break;
     669                                case 1:
     670                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA37", kArthurNoradRobotHeadOpen);
     671                                        break;
     672                                case 2:
     673                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA40", kArthurNoradRobotHeadOpen);
     674                                        break;
     675                                }
     676                        }
    607677                        break;
    608678                case kNoradDeltaRetinalScanBad:
    609679                        retScan = (RetScanChip *)_vm->getCurrentBiochip();
    610680                        retScan->setItemState(kNormalItem);
    611681                        playSpotSoundSync(kRetinalScanFailedIn, kRetinalScanFailedOut);
    612682                        downButton(dummy);
     683                        if (g_arthurChip)
     684                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA13", kArthurNoradAtRetScanNoBiochip);
    613685                        break;
    614686                case kNoradDeltaRetinalScanGood:
    615687                        retScan = (RetScanChip *)_vm->getCurrentBiochip();
    void NoradDelta::receiveNotification(Notification *notification, const Notificat  
    623695                }
    624696
    625697                _interruptionFilter = kFilterAllInput;
     698        } else if ((flags & kSpotSoundCompletedFlag) != 0) {
     699                if (_spotSounds.getStart() == kToDeactivateIn && g_arthurChip)
     700                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB41", kArthurNoradStartGlobeGame);
    626701        }
    627702
    628703        g_AIArea->checkMiddleArea();
  • engines/pegasus/neighborhood/norad/delta/noraddelta.h

    diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.h b/engines/pegasus/neighborhood/norad/delta/noraddelta.h
    index 11065f2..82aa7a9 100644
    a b protected:  
    8888        virtual void arriveAt(const RoomID, const DirectionConstant);
    8989        void arriveAtNorad68West();
    9090        void arriveAtNorad79West();
     91        void turnTo(const DirectionConstant);
    9192        TimeValue getViewTime(const RoomID, const DirectionConstant);
    9293        void openDoor();
    9394        void activateHotspots();
  • engines/pegasus/neighborhood/norad/norad.cpp

    diff --git a/engines/pegasus/neighborhood/norad/norad.cpp b/engines/pegasus/neighborhood/norad/norad.cpp
    index 53b3ff9..177b908 100644
    a b  
    2727#include "pegasus/gamestate.h"
    2828#include "pegasus/pegasus.h"
    2929#include "pegasus/ai/ai_area.h"
     30#include "pegasus/items/biochips/arthurchip.h"
    3031#include "pegasus/items/inventory/airmask.h"
    3132#include "pegasus/neighborhood/norad/constants.h"
    3233#include "pegasus/neighborhood/norad/norad.h"
    void Norad::arriveAtNoradElevator() {  
    162163
    163164void Norad::arriveAtUpperPressureDoorRoom() {
    164165        newInteraction(kNoradPressureDoorInteractionID);
     166        if (g_arthurChip)
     167                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA69", kArthurNoradReachedPressureDoor);
    165168}
    166169
    167170void Norad::arriveAtLowerPressureDoorRoom() {
    168171        newInteraction(kNoradPressureDoorInteractionID);
     172        if (g_arthurChip)
     173                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA69", kArthurNoradReachedPressureDoor);
    169174}
    170175
    171176void Norad::arriveAtSubPlatformRoom() {
    CanOpenDoorReason Norad::canOpenDoor(DoorTable::Entry &entry) {  
    199204}
    200205
    201206void Norad::cantOpenDoor(CanOpenDoorReason reason) {
     207        bool firstLockedDoor;
     208
    202209        if (reason == kCantOpenBadPressure)
    203210                playSpotSoundSync(_pressureSoundIn, _pressureSoundOut);
    204211        else
    205212                playSpotSoundSync(_accessDeniedIn, _accessDeniedOut);
     213        if (g_arthurChip) {
     214                firstLockedDoor = g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA65", kArthurNoradAttemptedLockedDoor);
     215
     216                if (!firstLockedDoor)
     217                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA68", kArthurNoradAttemptedLockedDoorAgain);
     218        }
    206219}
    207220
    208221void Norad::startExitMovie(const ExitTable::Entry &exitEntry) {
  • engines/pegasus/neighborhood/norad/subcontrolroom.cpp

    diff --git a/engines/pegasus/neighborhood/norad/subcontrolroom.cpp b/engines/pegasus/neighborhood/norad/subcontrolroom.cpp
    index d48481e..6812fa7 100644
    a b  
    2525
    2626#include "pegasus/gamestate.h"
    2727#include "pegasus/pegasus.h"
     28#include "pegasus/items/biochips/arthurchip.h"
    2829#include "pegasus/neighborhood/norad/constants.h"
    2930#include "pegasus/neighborhood/norad/norad.h"
    3031#include "pegasus/neighborhood/norad/subcontrolroom.h"
    void SubControlRoom::receiveNotification(Notification *notification, const Notif  
    562563                switch (flags) {
    563564                case kAlphaSplashFinished:
    564565                        setControlMonitorToTime(kMainMenuTime * _subControlScale, kAlphaMainMenu, true);
     566                        if (g_arthurChip)
     567                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA29", kArthurNoradSawClawMonitor);
    565568                        break;
    566569                case kPrepHighlightFinished:
    567570                        if (GameState.getNoradSubPrepState() == kSubDamaged)
    void SubControlRoom::receiveNotification(Notification *notification, const Notif  
    655658                                hideEverything();
    656659                                _robotState = kPlayerWon;
    657660                                owner->startExtraSequence(kN60PlayerFollowsRobotToDoor, kExtraCompletedFlag, kFilterAllInput);
     661                                if (g_arthurChip)
     662                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA67", kArthurNoradBeatRobotWithClaw);
    658663                                break;
    659664                        case kPlayerWon:
    660665                                ((NoradDelta *)owner)->playerBeatRobotWithClaw();
  • engines/pegasus/neighborhood/norad/subplatform.cpp

    diff --git a/engines/pegasus/neighborhood/norad/subplatform.cpp b/engines/pegasus/neighborhood/norad/subplatform.cpp
    index 97079a9..c13d812 100644
    a b  
    2626#include "pegasus/gamestate.h"
    2727#include "pegasus/pegasus.h"
    2828#include "pegasus/ai/ai_area.h"
     29#include "pegasus/items/biochips/arthurchip.h"
    2930#include "pegasus/neighborhood/norad/constants.h"
    3031#include "pegasus/neighborhood/norad/norad.h"
    3132#include "pegasus/neighborhood/norad/subplatform.h"
    void SubPlatform::receiveNotification(Notification *notification, const Notifica  
    147148                        loop1Spec.insertFaderKnot(5080, 0);
    148149
    149150                        owner->startExtraSequence(kNorad19ExitToSub, kExtraCompletedFlag, kFilterNoInput);
     151                        if (g_arthurChip)
     152                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA07", kArthurNoradEnteredSub);
    150153
    151154                        owner->startLoop1Fader(loop1Spec);
    152155                        owner->startLoop2Fader(loop2Spec);
    void SubPlatform::receiveNotification(Notification *notification, const Notifica  
    162165                        allowInput(true);
    163166                        break;
    164167                }
    165         } else if (notification == _neighborhoodNotification) {
     168        } else if (notification == _neighborhoodNotification && !((PegasusEngine *)g_engine)->isDVD()) {
    166169                allowInput(true);
    167170                ((PegasusEngine *)g_engine)->jumpToNewEnvironment(kNoradSubChaseID, kNoRoomID, kNoDirection);
    168171                GameState.setScoringEnteredSub(true);
  • engines/pegasus/neighborhood/prehistoric/prehistoric.cpp

    diff --git a/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp b/engines/pegasus/neighborhood/prehistoric/prehistoric.cpp
    index 190984f..b105857 100644
    a b  
    3131#include "pegasus/ai/ai_area.h"
    3232#include "pegasus/ai/ai_condition.h"
    3333#include "pegasus/ai/ai_rule.h"
     34#include "pegasus/items/biochips/arthurchip.h"
    3435#include "pegasus/neighborhood/prehistoric/prehistoric.h"
    3536
    3637namespace Pegasus {
    void Prehistoric::start() {  
    99100        }
    100101
    101102        Neighborhood::start();
     103       
     104        if (GameState.getCurrentRoomAndView() == MakeRoomView(kPrehistoric02, kSouth) && g_arthurChip)
     105                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA01", kArthurGoToPrehistoric);
    102106}
    103107
    104108class FinishPrehistoricAction : public AIPlayMessageAction {
    void Prehistoric::turnTo(const DirectionConstant newDirection) {  
    270274        Neighborhood::turnTo(newDirection);
    271275
    272276        Item *keyCard;
     277        bool doArthurFeelLikeYodelingMovie = false;
    273278
    274279        switch (GameState.getCurrentRoomAndView()) {
     280        case MakeRoomView(kPrehistoric08, kEast):
     281        case MakeRoomView(kPrehistoric10, kEast):
     282        case MakeRoomView(kPrehistoric12, kEast):
     283        case MakeRoomView(kPrehistoric14, kEast):
     284        case MakeRoomView(kPrehistoric25, kWest):
     285                doArthurFeelLikeYodelingMovie = true;
     286                break; 
    275287        case MakeRoomView(kPrehistoric18, kEast):
    276288                zoomToVault();
    277289                break;
    void Prehistoric::turnTo(const DirectionConstant newDirection) {  
    285297                // fall through
    286298        case MakeRoomView(kPrehistoric25, kEast):
    287299                setCurrentActivation(kActivationVaultClosed);
     300                if (GameState.getCurrentRoomAndView() == MakeRoomView(kPrehistoric25, kEast) &&
     301                        !GameState.isTakenItemID(kHistoricalLog) && g_arthurChip)
     302                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA60", kArthurPrehistoricCrossedBridge);
     303                break;
     304        case MakeRoomView(kPrehistoric23, kWest):
     305                if (g_arthurChip)
     306                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA59", kArthurPrehistoricSawEggs);
    288307                break;
    289308        case MakeRoomView(kPrehistoric16, kNorth):
    290309        case MakeRoomView(kPrehistoric21, kWest):
    void Prehistoric::turnTo(const DirectionConstant newDirection) {  
    305324                }
    306325                break;
    307326        }
     327        if (doArthurFeelLikeYodelingMovie && g_arthurChip)
     328                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA15", kArthurPrehistoricAtCliffEdge);
    308329}
    309330
    310331void Prehistoric::zoomToVault() {
    void Prehistoric::checkContinuePoint(const RoomID room, const DirectionConstant  
    326347
    327348void Prehistoric::arriveAt(const RoomID room, const DirectionConstant direction) {
    328349        Item *keyCard;
     350        bool doArthurLetsSpreadOutMovie, doArthurFeelLikeYodelingMovie;
    329351
    330352        if (MakeRoomView(room, direction) == MakeRoomView(kPrehistoric25, kEast) &&
    331353                        _privateFlags.getFlag(kPrehistoricPrivateExtendedBridgeFlag)) {
    void Prehistoric::arriveAt(const RoomID room, const DirectionConstant direction)  
    336358
    337359        Neighborhood::arriveAt(room, direction);
    338360
     361        doArthurLetsSpreadOutMovie = false;
     362        doArthurFeelLikeYodelingMovie = false;
    339363        switch (MakeRoomView(room, direction)) {
    340364        case MakeRoomView(kPrehistoricDeath, kNorth):
    341365        case MakeRoomView(kPrehistoricDeath, kSouth):
    void Prehistoric::arriveAt(const RoomID room, const DirectionConstant direction)  
    356380                        startExtraSequence(kPreArrivalFromTSA, kExtraCompletedFlag, kFilterNoInput);
    357381                }
    358382                break;
     383        case MakeRoomView(kPrehistoric06, kNorth):
     384        case MakeRoomView(kPrehistoric13, kWest):
     385                doArthurLetsSpreadOutMovie = true;
     386                break;
     387        case MakeRoomView(kPrehistoric22North, kNorth):
     388                if (g_arthurChip)
     389                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB44", kArthurPrehistoricSawBreaker);
     390                break;
     391        case MakeRoomView(kPrehistoric10, kEast):
     392        case MakeRoomView(kPrehistoric12, kEast):
     393        case MakeRoomView(kPrehistoric14, kEast):
     394        case MakeRoomView(kPrehistoric25, kWest):
     395                doArthurFeelLikeYodelingMovie = true;
     396                break;
    359397        case MakeRoomView(kPrehistoric18, kEast):
    360398                zoomToVault();
    361399                break;
    void Prehistoric::arriveAt(const RoomID room, const DirectionConstant direction)  
    375413                if (g_AIArea)
    376414                        g_AIArea->checkRules();
    377415                break;
     416        case MakeRoomView(kPrehistoric13, kNorth):
     417                doArthurLetsSpreadOutMovie = true;
    378418        case MakeRoomView(kPrehistoric08, kSouth):
    379419        case MakeRoomView(kPrehistoric10, kSouth):
    380420        case MakeRoomView(kPrehistoric12, kSouth):
    381         case MakeRoomView(kPrehistoric13, kNorth):
    382421        case MakeRoomView(kPrehistoric14, kSouth):
    383422        case MakeRoomView(kPrehistoric15, kNorth):
    384423        case MakeRoomView(kPrehistoric16, kSouth):
    void Prehistoric::arriveAt(const RoomID room, const DirectionConstant direction)  
    396435                break;
    397436        case MakeRoomView(kPrehistoric25, kEast):
    398437                setCurrentActivation(kActivationVaultClosed);
     438                if (!GameState.isTakenItemID(kHistoricalLog) && g_arthurChip)
     439                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA60", kArthurPrehistoricCrossedBridge);
     440                break;
     441        case MakeRoomView(kPrehistoric23, kWest):
     442                if (g_arthurChip)
     443                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA59", kArthurPrehistoricSawEggs);
    399444                break;
    400445        }
     446        if (g_arthurChip) {
     447                if (doArthurLetsSpreadOutMovie)
     448                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA20", kArthurPrehistoricReachedJunction);
     449                else if (doArthurFeelLikeYodelingMovie)
     450                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA15", kArthurPrehistoricAtCliffEdge);
     451        }
    401452}
    402453
    403454void Prehistoric::loadAmbientLoops() {
    void Prehistoric::loadAmbientLoops() {  
    425476        case kPrehistoric20:
    426477                // 1/4 volume.
    427478                if (_vm->isDVD()) // Updated sound for the DVD version
    428                         loadLoopSound1("Sounds/Prehistoric/P02SAL00.32k.AIFF", 64);
     479                        loadLoopSound1("Sounds/Prehistoric/P02SAL00.32K.AIFF", 64);
    429480                else
    430                         loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 64);
     481                        loadLoopSound1("Sounds/Prehistoric/P02SAL00.22K.AIFF", 64);
    431482                break;
    432483        case kPrehistoric08:
    433484        case kPrehistoric10:
    void Prehistoric::loadAmbientLoops() {  
    438489        case kPrehistoric21:
    439490                // 3/16 volume.
    440491                if (_vm->isDVD()) // Updated sound for the DVD version
    441                         loadLoopSound1("Sounds/Prehistoric/P02SAL00.32k.AIFF", 48);
     492                        loadLoopSound1("Sounds/Prehistoric/P02SAL00.32K.AIFF", 48);
    442493                else
    443                         loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 48);
     494                        loadLoopSound1("Sounds/Prehistoric/P02SAL00.22K.AIFF", 48);
    444495                break;
    445496        case kPrehistoric25:
    446497                // 1/8 volume.
    447498                if (_vm->isDVD()) // Updated sound for the DVD version
    448                         loadLoopSound1("Sounds/Prehistoric/P02SAL00.32k.AIFF", 32);
     499                        loadLoopSound1("Sounds/Prehistoric/P02SAL00.32K.AIFF", 32);
    449500                else
    450                         loadLoopSound1("Sounds/Prehistoric/P02SAL00.22k.AIFF", 32);
     501                        loadLoopSound1("Sounds/Prehistoric/P02SAL00.22K.AIFF", 32);
    451502                break;
    452503        case kPrehistoric22:
    453504        case kPrehistoric22North:
    void Prehistoric::loadAmbientLoops() {  
    492543        case kPrehistoric18:
    493544                if (_privateFlags.getFlag(kPrehistoricPrivateExtendedBridgeFlag)) {
    494545                        if (_vm->isDVD()) // Updated sound for the DVD version
    495                                 loadLoopSound2("Sounds/Prehistoric/P18EAL00.44K.aiff", 0x100, 0, 0);
     546                                loadLoopSound2("Sounds/Prehistoric/P18EAL00.44K.AIFF", 0x100, 0, 0);
    496547                        else
    497                                 loadLoopSound2("Sounds/Prehistoric/P18EAL00.22k.AIFF", 0x100, 0, 0);
     548                                loadLoopSound2("Sounds/Prehistoric/P18EAL00.22K.AIFF", 0x100, 0, 0);
    498549                } else {
    499550                        loadLoopSound2("");
    500551                }
    void Prehistoric::loadAmbientLoops() {  
    504555        case kPrehistoric22:
    505556        case kPrehistoric22North:
    506557                if (_vm->isDVD()) // Updated sound for the DVD version
    507                         loadLoopSound2("Sounds/Prehistoric/P24NAL00.32k.AIFF", 64);
     558                        loadLoopSound2("Sounds/Prehistoric/P24NAL00.32K.AIFF", 64);
    508559                else
    509                         loadLoopSound2("Sounds/Prehistoric/P24NAL00.22k.AIFF", 64);
     560                        loadLoopSound2("Sounds/Prehistoric/P24NAL00.22K.aiff", 64);
    510561                break;
    511562        }
    512563}
    void Prehistoric::receiveNotification(Notification *notification, const Notifica  
    556607                        break;
    557608                case kPre18EastZoom:
    558609                        startExtraSequence(kPre18EastZoomOut, kExtraCompletedFlag, kFilterNoInput);
     610                        if (g_arthurChip)
     611                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA61", kArthurPrehistoricZoomedToVault);
    559612                        break;
    560613                case kPre18EastZoomOut:
    561614                        GameState.setPrehistoricSeenBridgeZoom(true);
    void Prehistoric::receiveNotification(Notification *notification, const Notifica  
    566619                        GameState.setPrehistoricTriedToExtendBridge(false);
    567620                        loadAmbientLoops();
    568621                        GameState.setScoringExtendedBridge(true);
     622                        if (g_arthurChip) {
     623                                if (_vm->getRandomBit())
     624                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA10", kArthurPrehistoricExtendedBridge);
     625                                else
     626                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA56", kArthurPrehistoricExtendedBridge);
     627                        }
    569628                        break;
    570629                case kPre18EastBridgeOut:
    571630                        GameState.setPrehistoricTriedToExtendBridge(true);
     631                        if (g_arthurChip)
     632                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA58", kArthurPrehistoricAttemptedBridge);
    572633                        if (g_AIArea)
    573634                                g_AIArea->checkMiddleArea();
    574635                        break;
    575636                case kPre22ThrowBreaker:
    576637                        GameState.setPrehistoricBreakerThrown(true);
    577638                        GameState.setScoringThrewBreaker(true);
     639                        if (g_arthurChip)
     640                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA57", kArthurPrehistoricBreakerThrown);
    578641                        break;
    579642                case kPre25EastUnlockingVaultNoLog:
    580643                case kPre25EastUnlockingVaultWithLog:
     644                        if (!GameState.isTakenItemID(kHistoricalLog) && g_arthurChip)
     645                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA05", kArthurPrehistoricUnlockedVault);
    581646                        _vm->addItemToInventory((InventoryItem *)_vm->getAllItems().findItemByID(kJourneymanKey));
    582647                        break;
    583648                }
     649        } else if ((flags & kSpotCompletedFlag) != 0 &&
     650                                GameState.getCurrentRoomAndView() == MakeRoomView(kPrehistoric08, kEast)) {
     651                if (g_arthurChip)
     652                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA15", kArthurPrehistoricAtCliffEdge);
    584653        }
    585654
    586655        g_AIArea->checkMiddleArea();
    587656}
    588657
     658void Prehistoric::spotCompleted() {
     659        Neighborhood::spotCompleted();
     660        if (GameState.getCurrentRoomAndView() == MakeRoomView(kPrehistoric08, kEast) && g_arthurChip)
     661                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA15", kArthurPrehistoricAtCliffEdge);
     662}
     663
    589664Common::String Prehistoric::getBriefingMovie() {
    590665        Common::String movieName = Neighborhood::getBriefingMovie();
    591666
  • engines/pegasus/neighborhood/prehistoric/prehistoric.h

    diff --git a/engines/pegasus/neighborhood/prehistoric/prehistoric.h b/engines/pegasus/neighborhood/prehistoric/prehistoric.h
    index 17f9993..a2502b0 100644
    a b protected:  
    140140        int16 getStaticCompassAngle(const RoomID, const DirectionConstant);
    141141        void getExitCompassMove(const ExitTable::Entry &, FaderMoveSpec &);
    142142        virtual void receiveNotification(Notification *, const NotificationFlags);
     143        void spotCompleted();
    143144        void turnTo(const DirectionConstant);
    144145        void zoomToVault();
    145146        TimeValue getViewTime(const RoomID, const DirectionConstant);
  • engines/pegasus/neighborhood/tsa/fulltsa.cpp

    diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
    index 75f652a..31f84e7 100644
    a b  
    2323 *
    2424 */
    2525
     26#include "common/file.h"
     27
     28#include "pegasus/compass.h"
    2629#include "pegasus/cursor.h"
    2730#include "pegasus/energymonitor.h"
    2831#include "pegasus/gamestate.h"
    2932#include "pegasus/pegasus.h"
    3033#include "pegasus/ai/ai_area.h"
    3134#include "pegasus/items/biochips/aichip.h"
     35#include "pegasus/items/biochips/arthurchip.h"
    3236#include "pegasus/items/biochips/opticalchip.h"
    3337#include "pegasus/neighborhood/caldoria/caldoria.h"
    3438#include "pegasus/neighborhood/norad/constants.h"
    const CoordType kRedirectionFDRolloverTop = kNavAreaTop + 160;  
    480484const CoordType kRedirectionCCDoorLeft = kNavAreaLeft + 174;
    481485const CoordType kRedirectionCCDoorTop = kNavAreaTop + 36;
    482486
    483 const CoordType kRedirectionRRDoorLeft = kNavAreaLeft + 418;
     487const CoordType kRedirectionRRDoorLeft = kNavAreaLeft + 428;
    484488const CoordType kRedirectionRRDoorTop = kNavAreaTop + 32;
    485489
    486490const CoordType kRedirectionFDDoorLeft = kNavAreaLeft + 298;
    static const bool kPegasusResolved = true;  
    521525static const bool kPegasusCantExit = false;
    522526static const bool kPegasusCanExit = true;
    523527
     528static const ExtraID kEasterEggJimenez = 1000;
     529static const ExtraID kEasterEggCastillo = 1001;
     530static const ExtraID kEasterEggSinclair = 1002;
     531
    524532// Monitor modes
    525533enum {
    526534        kMonitorNeutral = 0,
    void RipTimer::timeChanged(const TimeValue newTime) {  
    644652}
    645653
    646654FullTSA::FullTSA(InputHandler *nextHandler, PegasusEngine *owner) : Neighborhood(nextHandler, owner, "Full TSA", kFullTSAID),
    647                 _ripTimer(kNoDisplayElement), _sprite1(kNoDisplayElement), _sprite2(kNoDisplayElement), _sprite3(kNoDisplayElement) {
     655                _extraMovie(kNoDisplayElement), _blankMovie(kNoDisplayElement), _playedSolvedMusicCue(false), _ripTimer(kNoDisplayElement),
     656                _sprite1(kNoDisplayElement), _sprite2(kNoDisplayElement), _sprite3(kNoDisplayElement) {
    648657        setIsItemTaken(kJourneymanKey);
    649658        setIsItemTaken(kPegasusBiochip);
    650659        setIsItemTaken(kMapBiochip);
    FullTSA::FullTSA(InputHandler *nextHandler, PegasusEngine *owner) : Neighborhood  
    652661
    653662void FullTSA::init() {
    654663        Neighborhood::init();
     664        _extraMovieCallBack.setNotification(&_neighborhoodNotification);
     665        if (Common::File::exists("Images/TSA/Blank TSA.movie"))
     666                _blankMovie.initFromMovieFile("Images/TSA/Blank TSA.movie");
     667        _blankMovie.setVolume(_vm->getSoundFXLevel());
     668        _blankMovie.setDisplayOrder(kNavMovieOrder + 1);
     669        _blankMovie.startDisplaying();
    655670        _ripTimer.setDisplayOrder(kRipTimerOrder);
    656671        _ripTimer.startDisplaying();
    657672
    void FullTSA::dieUncreatedInTSA() {  
    677692void FullTSA::start() {
    678693        g_energyMonitor->stopEnergyDraining();
    679694
     695        if (_vm->isDVD()) {
     696                _entranceMusic.attachFader(&_entranceFader);
     697                _entranceMusic.initFromAIFFFile("Sounds/TSA/TSA Entrance.32K.AIFF");
     698                _entranceFader.setMasterVolume(_vm->getAmbienceLevel() / 2);
     699        }
    680700        if (!GameState.getScoringEnterTSA()) {
    681701                _utilityFuse.primeFuse(GameState.getTSAFuseTimeLimit());
    682702                _utilityFuse.setFunctor(new Common::Functor0Mem<void, FullTSA>(this, &FullTSA::dieUncreatedInTSA));
    void FullTSA::loadAmbientLoops() {  
    836856        switch (GameState.getTSAState()) {
    837857        case kTSAPlayerDetectedRip:
    838858        case kTSAPlayerNeedsHistoricalLog:
    839                 if ((room >= kTSA16 && room <= kTSA0B) || (room >= kTSA21Cyan && room <= kTSA24Cyan) || (room >= kTSA21Red && room <= kTSA24Red))
    840                         loadLoopSound1("Sounds/TSA/TSA CLAXON.22K.AIFF", 0x100 / 4, 0, 0);
    841                 else if (room == kTSA25Cyan || room == kTSA25Red)
    842                         loadLoopSound1("Sounds/TSA/TSA CLAXON.22K.AIFF", 0x100 / 6, 0, 0);
    843                 else
    844                         loadLoopSound1("Sounds/TSA/TSA EchoClaxon.22K.AIFF", 0x100 / 4, 0, 0);
     859                if (_vm->isDVD()) {
     860                        if ((room >= kTSA16 && room <= kTSA0B) || (room >= kTSA21Cyan && room <= kTSA24Cyan) || (room >= kTSA21Red && room <= kTSA24Red))
     861                                loadLoopSound1("Sounds/TSA/TSA CLAXON.44K.AIFF", 0x100 * 3 / 16, 0, 0);
     862                        else if (room == kTSA25Cyan || room == kTSA25Red)
     863                                loadLoopSound1("Sounds/TSA/TSA CLAXON.44K.AIFF", 0x100 / 8, 0, 0);
     864                        else
     865                                loadLoopSound1("Sounds/TSA/TSA EchoClaxon.22K.AIFF", 0x100 * 3 / 16, 0, 0);
     866                } else {
     867                        if ((room >= kTSA16 && room <= kTSA0B) || (room >= kTSA21Cyan && room <= kTSA24Cyan) || (room >= kTSA21Red && room <= kTSA24Red))
     868                                loadLoopSound1("Sounds/TSA/TSA CLAXON.22K.AIFF", 0x100 / 4, 0, 0);
     869                        else if (room == kTSA25Cyan || room == kTSA25Red)
     870                                loadLoopSound1("Sounds/TSA/TSA CLAXON.22K.AIFF", 0x100 / 6, 0, 0);
     871                        else
     872                                loadLoopSound1("Sounds/TSA/TSA EchoClaxon.22K.AIFF", 0x100 / 4, 0, 0);
     873                }
    845874                break;
    846875        default:
    847                 if (room >= kTSA00 && room <= kTSA02)
    848                         loadLoopSound1("Sounds/TSA/T01NAE.NEW.22K.AIFF");
    849                 else if (room >= kTSA03 && room <= kTSA15)
    850                         loadLoopSound1("Sounds/TSA/T01NAE.NEW.22K.AIFF");
    851                 else if (room >= kTSA16 && room <= kTSA0B)
    852                         loadLoopSound1("Sounds/TSA/T14SAEO1.22K.AIFF");
    853                 else if (room >= kTSA21Cyan && room <= kTSA25Red)
    854                         loadLoopSound1("Sounds/TSA/T15SAE01.22K.AIFF");
    855                 else if (room >= kTSA26 && room <= kTSA37)
    856                         loadLoopSound1("Sounds/TSA/T01NAE.NEW.22K.AIFF");
     876                if (_vm->isDVD()) {
     877                        if ((room >= kTSA00 && room <= kTSA02) || (room >= kTSA03 && room <= kTSA15) || (room >= kTSA26 && room <= kTSA37))
     878                                loadLoopSound1("Sounds/TSA/T01NAE.NEW.32K.AIFF", 0x100 * 3 / 4, 0, 0);
     879                        else if (room >= kTSA16 && room <= kTSA0B)
     880                                loadLoopSound1("Sounds/TSA/T14SAEO1.32K.AIFF", 0x100 * 3 / 4, 0, 0);
     881                        else if (room >= kTSA21Cyan && room <= kTSA25Red)
     882                                loadLoopSound1("Sounds/TSA/T15SAE01.32K.AIFF", 0x100 * 3 / 4, 0, 0);
     883                } else {
     884                        if ((room >= kTSA00 && room <= kTSA02) || (room >= kTSA03 && room <= kTSA15) || (room >= kTSA26 && room <= kTSA37))
     885                                loadLoopSound1("Sounds/TSA/T01NAE.NEW.22K.AIFF");
     886                        else if (room >= kTSA16 && room <= kTSA0B)
     887                                loadLoopSound1("Sounds/TSA/T14SAEO1.22K.AIFF");
     888                        else if (room >= kTSA21Cyan && room <= kTSA25Red)
     889                                loadLoopSound1("Sounds/TSA/T15SAE01.22K.AIFF");
     890                }
    857891                break;
    858892        }
    859893}
    void FullTSA::getExtraEntry(const uint32 id, ExtraTable::Entry &extraEntry) {  
    11071141                extraEntry.movieStart += kFullTSAFrameDuration * 3;
    11081142}
    11091143
     1144void FullTSA::showViewFrame(TimeValue viewTime) {
     1145        if ((int32)viewTime >= 0) {
     1146                _turnPush.hide();
     1147                _navMovie.stop();
     1148                _navMovie.setFlags(0);
     1149                if (_blankMovie.isMovieValid() &&
     1150                        (GameState.getTSAState() == kRobotsAtCommandCenter ||
     1151                        GameState.getTSAState() == kRobotsAtFrontDoor ||
     1152                        GameState.getTSAState() == kRobotsAtReadyRoom) &&
     1153                        (GameState.getCurrentRoom() == kTSA0A ||
     1154                        GameState.getCurrentRoom() == kTSA06) &&
     1155                        (GameState.getCurrentDirection() == kEast ||
     1156                        GameState.getCurrentDirection() == kWest)) {
     1157                        viewTime = 0;
     1158                        if (GameState.getCurrentRoom() == kTSA06)
     1159                                viewTime = 2 * _blankMovie.getScale();
     1160                        if (GameState.getCurrentDirection() == kWest)
     1161                                viewTime += _blankMovie.getScale();
     1162
     1163                        _navMovie.hide();
     1164                        _blankMovie.setSegment(0, _blankMovie.getDuration());
     1165                        _blankMovie.setTime(viewTime);
     1166
     1167                        Common::Rect pushBounds;
     1168                        _turnPush.getBounds(pushBounds);
     1169
     1170                        _blankMovie.moveElementTo(pushBounds.left, pushBounds.top);
     1171                        _blankMovie.show();
     1172                        _blankMovie.redrawMovieWorld();
     1173                } else {
     1174                        _blankMovie.hide();
     1175                        _navMovie.setSegment(0, _navMovie.getDuration());
     1176                        _navMovie.setTime(viewTime);
     1177
     1178                        Common::Rect pushBounds;
     1179                        _turnPush.getBounds(pushBounds);
     1180
     1181                        _navMovie.moveElementTo(pushBounds.left, pushBounds.top);
     1182                        _navMovie.show();
     1183                        _navMovie.redrawMovieWorld();
     1184                }
     1185        }
     1186}
     1187
    11101188void FullTSA::pickedUpItem(Item *item) {
    11111189        BiochipItem *biochip;
    11121190
    void FullTSA::startDoorOpenMovie(const TimeValue startTime, const TimeValue stop  
    11911269        Neighborhood::startDoorOpenMovie(startTime, stopTime);
    11921270}
    11931271
     1272void FullTSA::startTurnPush(const TurnDirection turnDirection, const TimeValue newView, const DirectionConstant nextDir) {
     1273        if (g_AIArea)
     1274                g_AIArea->lockAIOut();
     1275
     1276        _vm->_cursor->hide();
     1277
     1278        GameState.setNextDirection(nextDir);
     1279
     1280        _interruptionFilter = kFilterNoInput;
     1281        _turnPush.stopFader();
     1282
     1283        // Set up callback.
     1284        _turnPushCallBack.setCallBackFlag(kTurnCompletedFlag);
     1285        _turnPushCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     1286
     1287        // Stop nav movie.
     1288        _navMovie.stop();
     1289        _navMovie.setFlags(0);
     1290
     1291        if (_blankMovie.isMovieValid() &&
     1292                (GameState.getTSAState() == kRobotsAtCommandCenter ||
     1293                GameState.getTSAState() == kRobotsAtFrontDoor ||
     1294                GameState.getTSAState() == kRobotsAtReadyRoom) &&
     1295                (GameState.getCurrentRoom() == kTSA0A || GameState.getCurrentRoom() == kTSA06) &&
     1296                (nextDir == kEast || nextDir == kWest)) {
     1297                TimeValue newRobotView = 0;
     1298                if (GameState.getCurrentRoom() == kTSA06)
     1299                        newRobotView = 2 * _blankMovie.getScale();
     1300                if (nextDir == kWest)
     1301                        newRobotView += _blankMovie.getScale();
     1302
     1303                _blankMovie.setSegment(0, _blankMovie.getDuration());
     1304
     1305                _pushIn.initFromMovieFrame(_blankMovie.getMovie(), newRobotView);
     1306                _turnPush.setInAndOutElements(&_pushIn, &_navMovie);           
     1307        } else {
     1308                // Set segment of nav movie to whole movie, so that subsequent initFromMovieFrame
     1309                // will work.
     1310                _navMovie.setSegment(0, _navMovie.getDuration());
     1311
     1312                _pushIn.initFromMovieFrame(_navMovie.getMovie(), newView);
     1313                if (_blankMovie.isMovieValid() &&
     1314                        (GameState.getTSAState() == kRobotsAtCommandCenter ||
     1315                        GameState.getTSAState() == kRobotsAtFrontDoor ||
     1316                        GameState.getTSAState() == kRobotsAtReadyRoom) &&
     1317                        (GameState.getCurrentRoom() == kTSA0A ||
     1318                        GameState.getCurrentRoom() == kTSA06))
     1319                        _turnPush.setInAndOutElements(&_pushIn, &_blankMovie);
     1320                else
     1321                        _turnPush.setInAndOutElements(&_pushIn, &_navMovie);
     1322        }
     1323
     1324        _blankMovie.hide();
     1325        _navMovie.hide();
     1326
     1327        switch (turnDirection) {
     1328        case kTurnLeft:
     1329                _turnPush.setSlideDirection(kSlideRightMask);
     1330                break;
     1331        case kTurnRight:
     1332                _turnPush.setSlideDirection(kSlideLeftMask);
     1333                break;
     1334        case kTurnUp:
     1335                _turnPush.setSlideDirection(kSlideDownMask);
     1336                break;
     1337        case kTurnDown:
     1338                _turnPush.setSlideDirection(kSlideUpMask);
     1339                break;
     1340        }
     1341
     1342        _turnPush.show();
     1343
     1344        FaderMoveSpec moveSpec;
     1345        moveSpec.makeTwoKnotFaderSpec(60, 0, 0, 15, 1000);
     1346        _turnPush.startFader(moveSpec);
     1347
     1348        if (g_compass) {
     1349                _turnPush.pauseFader();
     1350
     1351                int32 startAngle = getStaticCompassAngle(GameState.getCurrentRoom(), GameState.getCurrentDirection());
     1352                int32 stopAngle = getStaticCompassAngle(GameState.getCurrentRoom(), nextDir);
     1353
     1354                if (turnDirection == kTurnLeft) {
     1355                        if (startAngle < stopAngle)
     1356                                startAngle += 360;
     1357                } else {
     1358                        if (stopAngle < startAngle)
     1359                                stopAngle += 360;
     1360                }
     1361
     1362                FaderMoveSpec turnSpec;
     1363                _turnPush.getCurrentFaderMove(turnSpec);
     1364
     1365                FaderMoveSpec compassMove;
     1366                compassMove.makeTwoKnotFaderSpec(turnSpec.getFaderScale(), turnSpec.getNthKnotTime(0), startAngle, turnSpec.getNthKnotTime(1), stopAngle);
     1367                g_compass->startFader(compassMove);
     1368        }
     1369
     1370        _turnPushCallBack.cancelCallBack();
     1371        _turnPush.continueFader();
     1372
     1373        do {
     1374                _vm->checkCallBacks();
     1375                _vm->refreshDisplay();
     1376                _vm->_system->delayMillis(10);
     1377        } while (_turnPush.isFading());
     1378
     1379        _turnPush.stopFader();
     1380        _neighborhoodNotification.setNotificationFlags(kTurnCompletedFlag, kTurnCompletedFlag);
     1381}
     1382
    11941383InputBits FullTSA::getInputFilter() {
    11951384        InputBits result = Neighborhood::getInputFilter();
    11961385
    void FullTSA::turnRight() {  
    12481437}
    12491438
    12501439void FullTSA::openDoor() {
     1440        FaderMoveSpec spec;
     1441
    12511442        switch (GameState.getCurrentRoomAndView()) {
     1443        case MakeRoomView(kTSA14, kSouth):
     1444                if (_vm->isDVD()) {
     1445                        spec.makeTwoKnotFaderSpec(10, 0, 255, 5, 0);
     1446                        _entranceFader.startFader(spec);
     1447                }
     1448                break;
    12521449        case MakeRoomView(kTSA15, kSouth):
     1450                if (_vm->isDVD()) {
     1451                        spec.makeTwoKnotFaderSpec(10, 0, 255, 5, 0);
     1452                        _entranceFader.startFader(spec);
     1453                }
    12531454                if (GameState.getTSAState() == kTSAPlayerNeedsHistoricalLog || GameState.getTSAState() == kRobotsAtFrontDoor)
    12541455                        setCurrentAlternate(kAltTSARedAlert);
    12551456                break;
    void FullTSA::openDoor() {  
    12581459        Neighborhood::openDoor();
    12591460}
    12601461
     1462void FullTSA::doorOpened() {
     1463        if (_vm->isDVD()) {
     1464                switch (GameState.getCurrentRoomAndView()) {
     1465                case MakeRoomView(kTSA02, kNorth):
     1466                        if (_lastExtra == kTSA02NorthDoorWithAgent3 && g_arthurChip) {
     1467                                if (_vm->getRandomBit())
     1468                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB36", kArthurTSASawAgent3);
     1469                                else
     1470                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB37", kArthurTSASawAgent3);
     1471                        }
     1472                        break;
     1473                case MakeRoomView(kTSA16, kSouth):
     1474                case MakeRoomView(kTSA21Cyan, kSouth):
     1475                        _entranceMusic.stopSound();
     1476                        break;
     1477                }
     1478        }
     1479        Neighborhood::doorOpened();
     1480}
     1481
    12611482CanMoveForwardReason FullTSA::canMoveForward(ExitTable::Entry &entry) {
    12621483        if (GameState.getCurrentRoomAndView() == MakeRoomView(kTSA25Red, kNorth))
    12631484                return kCantMoveBlocked;
    CanMoveForwardReason FullTSA::canMoveForward(ExitTable::Entry &entry) {  
    12651486        return Neighborhood::canMoveForward(entry);
    12661487}
    12671488
     1489void FullTSA::moveForward() {
     1490        ExitTable::Entry exitEntry;
     1491        CanMoveForwardReason moveReason = kCanMoveForward;
     1492        FaderMoveSpec spec;
     1493
     1494        if (_vm->isDVD()) {
     1495                moveReason = canMoveForward(exitEntry);
     1496                if (moveReason == kCanMoveForward &&
     1497                        GameState.getCurrentRoomAndView() == MakeRoomView(kTSA02, kNorth) &&
     1498                        !GameState.allTimeZonesFinished()) {
     1499                        _entranceMusic.playSound();
     1500                        spec.makeOneKnotFaderSpec(255);
     1501                        _entranceFader.startFader(spec);
     1502                }
     1503        }
     1504        Neighborhood::moveForward();
     1505        if (moveReason == kCanMoveForward && GameState.getCurrentRoomAndView() == MakeRoomView(kTSA01, kSouth) &&
     1506                GameState.allTimeZonesFinished() && g_arthurChip)
     1507                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA51", kArthurTSALeaving);
     1508}
     1509
    12681510CanOpenDoorReason FullTSA::canOpenDoor(DoorTable::Entry &entry) {
    12691511        switch (GameState.getCurrentRoomAndView()) {
    12701512        case MakeRoomView(kTSA02, kNorth):
    void FullTSA::activateHotspots() {  
    13381580                if (!GameState.getTSAFrontDoorUnlockedOutside())
    13391581                        _vm->getAllHotspots().activateOneHotspot(kTSA02DoorSpotID);
    13401582                break;
     1583        case MakeRoomView(kTSA0A, kEast):
     1584                if (GameState.getTSAState() == kRobotsAtCommandCenter ||
     1585                        GameState.getTSAState() == kRobotsAtFrontDoor ||
     1586                        GameState.getTSAState() == kRobotsAtReadyRoom)
     1587                        _vm->getAllHotspots().deactivateOneHotspot(kTSA0AEastSpotID);
     1588                break;
     1589        case MakeRoomView(kTSA0A, kWest):
     1590                if (GameState.getTSAState() == kRobotsAtCommandCenter ||
     1591                        GameState.getTSAState() == kRobotsAtFrontDoor ||
     1592                        GameState.getTSAState() == kRobotsAtReadyRoom)
     1593                        _vm->getAllHotspots().deactivateOneHotspot(kTSA0AWastSpotID);
     1594                break;
    13411595        case MakeRoomView(kTSA0B, kEast):
    13421596                if (GameState.getTSA0BZoomedIn())
    13431597                        switch (GameState.getTSAState()) {
    void FullTSA::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {  
    13821636                Neighborhood::clickInHotspot(input, clickedSpot);
    13831637                break;
    13841638        case kTSA03EastJimenezSpotID:
    1385                 startExtraLongSequence(kTSA03JimenezZoomIn, kTSA03JimenezZoomOut, kExtraCompletedFlag, kFilterNoInput);
     1639                if (_vm->isDVD() && JMPPPInput::isEasterEggModifierInput(input))
     1640                        startExtraSequence(kEasterEggJimenez, kExtraCompletedFlag, kFilterNoInput);
     1641                else
     1642                        startExtraLongSequence(kTSA03JimenezZoomIn, kTSA03JimenezZoomOut, kExtraCompletedFlag, kFilterNoInput);
    13861643                break;
    13871644        case kTSA03WestCrenshawSpotID:
    13881645                startExtraLongSequence(kTSA03CrenshawZoomIn, kTSA03CrenshawZoomOut, kExtraCompletedFlag, kFilterNoInput);
    void FullTSA::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {  
    13911648                startExtraLongSequence(kTSA04MatsumotoZoomIn, kTSA04MatsumotoZoomOut, kExtraCompletedFlag, kFilterNoInput);
    13921649                break;
    13931650        case kTSA04WestCastilleSpotID:
    1394                 startExtraLongSequence(kTSA04CastilleZoomIn, kTSA04CastilleZoomOut, kExtraCompletedFlag, kFilterNoInput);
     1651                if (_vm->isDVD() && JMPPPInput::isEasterEggModifierInput(input))
     1652                        startExtraSequence(kEasterEggCastillo, kExtraCompletedFlag, kFilterNoInput);
     1653                else
     1654                        startExtraLongSequence(kTSA04CastilleZoomIn, kTSA04CastilleZoomOut, kExtraCompletedFlag, kFilterNoInput);
    13951655                break;
    13961656        case kTSA05EastSinclairSpotID:
    1397                 startExtraLongSequence(kTSA05SinclairZoomIn, kTSA05SinclairZoomOut, kExtraCompletedFlag, kFilterNoInput);
     1657                if (_vm->isDVD() && JMPPPInput::isEasterEggModifierInput(input))
     1658                        startExtraSequence(kEasterEggSinclair, kExtraCompletedFlag, kFilterNoInput);
     1659                else
     1660                        startExtraLongSequence(kTSA05SinclairZoomIn, kTSA05SinclairZoomOut, kExtraCompletedFlag, kFilterNoInput);
    13981661                break;
    13991662        case kTSA05WestWhiteSpotID:
    14001663                startExtraLongSequence(kTSA05WhiteZoomIn, kTSA05WhiteZoomOut, kExtraCompletedFlag, kFilterNoInput);
    void FullTSA::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {  
    15511814        // Pegasus
    15521815        case kTSA37NorthJumpToPrehistoricSpotID:
    15531816                startExtraSequence(kTSA37PegasusDepart, kExtraCompletedFlag, kFilterNoInput);
     1817                if (g_arthurChip) {
     1818                        if (_vm->getRandomBit())
     1819                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA30", kArthurTSAUsedPegasus);
     1820                        else
     1821                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA35", kArthurTSAUsedPegasus);
     1822                }
    15541823                break;
    15551824        case kTSA37NorthExitSpotID:
    15561825                _sprite2.setCurrentFrameIndex(1);
    void FullTSA::playRightComparison() {  
    18862155// TSA state is kTSABossSawHistoricalLog.
    18872156void FullTSA::startRobotGame() {
    18882157        requestExtraSequence(kTSA0BNorthCantChangeHistory, 0, kFilterNoInput);
    1889         requestExtraSequence(kTSA0BAIInterruption, 0, kFilterNoInput);
     2158        requestExtraSequence(kTSA0BAIInterruption, kExtraCompletedFlag, kFilterNoInput);
    18902159        requestExtraSequence(kTSA0BShowGuardRobots, 0, kFilterNoInput);
    18912160        requestExtraSequence(kTSA0BRobotsToCommandCenter, kExtraCompletedFlag, kFilterNoInput);
    18922161}
    void FullTSA::startUpRobotMonitor() {  
    19002169        _sprite1.addPICTResourceFrame(kRedirectionRRRolloverPICTID, true,
    19012170                        kRedirectionRRRolloverLeft - kRedirectionSprite1Left,
    19022171                        kRedirectionRRRolloverTop - kRedirectionSprite1Top);
    1903         _sprite1.addPICTResourceFrame(kRedirectionFDRolloverPICTID, false,
     2172        _sprite1.addPICTResourceFrame(kRedirectionFDRolloverPICTID, true,
    19042173                        kRedirectionFDRolloverLeft - kRedirectionSprite1Left,
    19052174                        kRedirectionFDRolloverTop - kRedirectionSprite1Top);
    19062175        _sprite1.addPICTResourceFrame(kRedirectionCCDoorPICTID, true,
    void FullTSA::startUpRobotMonitor() {  
    19092178        _sprite1.addPICTResourceFrame(kRedirectionRRDoorPICTID, true,
    19102179                        kRedirectionRRDoorLeft - kRedirectionSprite1Left,
    19112180                        kRedirectionRRDoorTop - kRedirectionSprite1Top);
    1912         _sprite1.addPICTResourceFrame(kRedirectionFDDoorPICTID, false,
     2181        _sprite1.addPICTResourceFrame(kRedirectionFDDoorPICTID, true,
    19132182                        kRedirectionFDDoorLeft - kRedirectionSprite1Left,
    19142183                        kRedirectionFDDoorTop - kRedirectionSprite1Top);
    19152184        _sprite1.addPICTResourceFrame(kRedirectionClosePICTID, false,
    void FullTSA::arriveAt(const RoomID room, const DirectionConstant direction) {  
    19942263                        loopExtraSequence(kTSATransporterArrowLoop, 0);
    19952264                }
    19962265                break;
     2266        case MakeRoomView(kTSA01, kNorth):
     2267                if (g_arthurChip)
     2268                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA22", kArthurTSAEnteredCave);
     2269                break;
    19972270        case MakeRoomView(kTSA03, kNorth):
    19982271        case MakeRoomView(kTSA05, kNorth):
    19992272        case MakeRoomView(kTSA0A, kNorth):
    20002273        case MakeRoomView(kTSA06, kNorth):
    2001         case MakeRoomView(kTSA07, kNorth):
    20022274                if (_utilityFuse.isFuseLit())
    20032275                        _utilityFuse.stopFuse();
    20042276                GameState.setScoringEnterTSA(true);
    void FullTSA::arriveAt(const RoomID room, const DirectionConstant direction) {  
    20092281                if (!GameState.getTSASeenRobotGreeting())
    20102282                        startExtraSequence(kTSA04NorthRobotGreeting, kExtraCompletedFlag, kFilterNoInput);
    20112283                break;
     2284        case MakeRoomView(kTSA07, kNorth):
     2285                if (_utilityFuse.isFuseLit())
     2286                        _utilityFuse.stopFuse();
     2287                GameState.setScoringEnterTSA(true);
     2288                if (g_arthurChip)
     2289                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA23", kArthurTSAReachedJunction);
     2290                break;
    20122291        case MakeRoomView(kTSA03, kSouth):
    20132292                GameState.setTSAFrontDoorUnlockedInside(GameState.getTSAState() == kRobotsAtFrontDoor || GameState.allTimeZonesFinished());
    20142293                break;
    void FullTSA::arriveAt(const RoomID room, const DirectionConstant direction) {  
    20932372                arriveAtTSA25Red();
    20942373                break;
    20952374        case MakeRoomView(kTSA34, kSouth):
    2096                 if (GameState.getLastRoom() == kTSA37)
     2375                if (GameState.getLastRoom() == kTSA37) {
    20972376                        closeDoorOffScreen(kTSA37, kNorth);
     2377                        if (_vm->isDVD() && GameState.allTimeZonesFinished() && !_playedSolvedMusicCue) {
     2378                                _solvedMusicCue.initFromAIFFFile("Sounds/TSA/TSA NORM.32K.AIFF");
     2379                                _solvedMusicCue.setVolume(_vm->getAmbienceLevel());
     2380                                _solvedMusicCue.playSound();
     2381                                _playedSolvedMusicCue = true;
     2382                        }
     2383                }
    20982384                break;
    20992385        case MakeRoomView(kTSA37, kNorth):
    21002386                arriveAtTSA37();
    void FullTSA::checkRobotLocations(const RoomID room, const DirectionConstant dir  
    21322418                        switch (GameState.getTSAState()) {
    21332419                        case kRobotsAtCommandCenter:
    21342420                                if (!_privateFlags.getFlag(kTSAPrivateSeenRobotWarningFlag)) {
    2135                                         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/TSA/XT11WB", false, kWarningInterruption);
     2421                                        if (g_AIArea->isChattyAI())
     2422                                                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/TSA/XT11WB", false, kWarningInterruption);
    21362423                                        _privateFlags.setFlag(kTSAPrivateSeenRobotWarningFlag, true);
    21372424                                }
    21382425                                break;
    void FullTSA::turnTo(const DirectionConstant newDirection) {  
    22862573                switch (GameState.getTSAState()) {
    22872574                case kRobotsAtCommandCenter:
    22882575                        if (!_privateFlags.getFlag(kTSAPrivateSeenRobotWarningFlag)) {
    2289                                 g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/TSA/XT11WB", false, kWarningInterruption);
     2576                                if (g_AIArea->isChattyAI())
     2577                                        g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/TSA/XT11WB", false, kWarningInterruption);
    22902578                                _privateFlags.setFlag(kTSAPrivateSeenRobotWarningFlag, true);
    22912579                        }
    22922580                        break;
    void FullTSA::closeDoorOffScreen(const RoomID room, const DirectionConstant) {  
    23552643        }
    23562644}
    23572645
     2646void FullTSA::startExtraSequence(const ExtraID extraID, const NotificationFlags flags, const InputBits interruptionFilter) {
     2647        static const TimeValue times[3][2] = {
     2648                { 0, 11720 },
     2649                { 11720, 19840 },
     2650                { 19840, 29960 }
     2651        };
     2652        TimeValue segmentStart = 0, segmentStop = 0;
     2653        bool loopSequence = false;
     2654        Common::Rect pushBounds;
     2655        NotificationFlags extraFlags;
     2656
     2657        switch (extraID) {
     2658        case kEasterEggJimenez:
     2659        case kEasterEggCastillo:
     2660        case kEasterEggSinclair:
     2661                _turnPush.getBounds(pushBounds);
     2662                _extraMovie.initFromMovieFile("Images/TSA/Wacky TSA.movie");
     2663                segmentStart = times[extraID - 1000][0];
     2664                segmentStop = times[extraID - 1000][1];
     2665                loopSequence = false;
     2666               
     2667                _lastExtra = extraID;
     2668                _turnPush.hide();
     2669               
     2670                if (!loopSequence && g_AIArea)
     2671                        g_AIArea->lockAIOut();
     2672               
     2673                extraFlags = flags;
     2674                _interruptionFilter = interruptionFilter;
     2675                // Stop the nav movie before doing anything else
     2676                _navMovie.stop();
     2677                _navMovie.stopDisplaying();
     2678               
     2679                _extraMovie.setVolume(_vm->getSoundFXLevel());
     2680                _extraMovie.moveElementTo(pushBounds.left, pushBounds.top);
     2681                _extraMovie.setDisplayOrder(kNavMovieOrder + 1);
     2682                _extraMovie.startDisplaying();
     2683                _extraMovie.show();
     2684                _extraMovie.setFlags(0);
     2685                _extraMovie.setSegment(segmentStart, segmentStop);
     2686                _extraMovie.setTime(segmentStart);
     2687                if (loopSequence)
     2688                        _extraMovie.setFlags(kLoopTimeBase);
     2689                else
     2690                        extraFlags |= kNeighborhoodMovieCompletedFlag;
     2691                _extraMovieCallBack.cancelCallBack();
     2692                _extraMovieCallBack.initCallBack(&_extraMovie, kCallBackAtExtremes);
     2693                if (extraFlags != 0) {
     2694                        _extraMovieCallBack.setCallBackFlag(extraFlags);
     2695                        _extraMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     2696                }
     2697                _extraMovie.start();
     2698                break;
     2699        default:
     2700                Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
     2701                break;
     2702        }
     2703}
     2704
    23582705void FullTSA::receiveNotification(Notification *notification, const NotificationFlags flags) {
    23592706        ExtraID lastExtra = _lastExtra;
    23602707
    void FullTSA::receiveNotification(Notification *notification, const Notification  
    23722719        Neighborhood::receiveNotification(notification, flags);
    23732720
    23742721        InventoryItem *item;
     2722        bool doArthurSawBustMovie, doArthurRedirectedRobotsMovie;
    23752723
    23762724        if ((flags & kExtraCompletedFlag) != 0) {
    23772725                // Only allow input if we're not in the middle of series of queue requests.
    23782726                if (actionQueueEmpty())
    23792727                        _interruptionFilter = kFilterAllInput;
    23802728
     2729                doArthurSawBustMovie = false;
     2730                doArthurRedirectedRobotsMovie = false;
    23812731                switch (lastExtra) {
    23822732                case kTSAGTCardSwipe:
    23832733                        item = (InventoryItem *)_vm->getAllItems().findItemByID(kKeyCard);
    void FullTSA::receiveNotification(Notification *notification, const Notification  
    24082758                        break;
    24092759                case kTSA03JimenezZoomIn:
    24102760                        GameState.setScoringSawBust1(true);
     2761                        doArthurSawBustMovie = true;
    24112762                        break;
    24122763                case kTSA03CrenshawZoomIn:
    24132764                        GameState.setScoringSawBust2(true);
     2765                        doArthurSawBustMovie = true;
    24142766                        break;
    24152767                case kTSA04MatsumotoZoomIn:
    24162768                        GameState.setScoringSawBust3(true);
     2769                        doArthurSawBustMovie = true;
    24172770                        break;
    24182771                case kTSA04CastilleZoomIn:
    24192772                        GameState.setScoringSawBust4(true);
     2773                        doArthurSawBustMovie = true;
    24202774                        break;
    24212775                case kTSA05SinclairZoomIn:
    24222776                        GameState.setScoringSawBust5(true);
     2777                        doArthurSawBustMovie = true;
    24232778                        break;
    24242779                case kTSA05WhiteZoomIn:
    24252780                        GameState.setScoringSawBust6(true);
     2781                        doArthurSawBustMovie = true;
     2782                        break;
     2783                case kEasterEggJimenez:
     2784                case kEasterEggCastillo:
     2785                case kEasterEggSinclair:
     2786                        _extraMovie.stopDisplaying();
     2787                        _extraMovie.releaseMovie();
     2788                        _navMovie.startDisplaying();
     2789                        doArthurSawBustMovie = true;
     2790                        break;
     2791                case kTSA0AEastRobot:
     2792                        if (g_arthurChip)
     2793                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA48", kArthurTSAClickedRobot1);
     2794                        break;
     2795                case kTSA0AWestRobot:
     2796                        if (g_arthurChip)
     2797                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA53", kArthurTSAClickedRobot2);
    24262798                        break;
    24272799
    24282800                // Command center
    void FullTSA::receiveNotification(Notification *notification, const Notification  
    25262898                case kTSA0BShowGuardRobots:
    25272899                        startUpRobotMonitor();
    25282900                        // Fall through
     2901                case kTSA0BRobotsFromCommandCenterToFrontDoor:
     2902                case kTSA0BRobotsFromReadyRoomToFrontDoor:
     2903                        doArthurRedirectedRobotsMovie = true;
    25292904                case kTSA0BRobotsFromCommandCenterToReadyRoom:
    25302905                case kTSA0BRobotsFromReadyRoomToCommandCenter:
    2531                 case kTSA0BRobotsFromCommandCenterToFrontDoor:
    25322906                case kTSA0BRobotsFromFrontDoorToCommandCenter:
    25332907                case kTSA0BRobotsFromFrontDoorToReadyRoom:
    2534                 case kTSA0BRobotsFromReadyRoomToFrontDoor:
    25352908                        _sprite2.setCurrentFrameIndex(kRedirectionSecuredSprite);
    25362909                        _sprite2.show();
    25372910                        break;
     2911                case kTSA0BAIInterruption:
     2912                        if (g_arthurChip)
     2913                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA52", kArthurTSAConfinedByBaldwin);
     2914                        break;
    25382915
    25392916                // TBP monitor.
    25402917                case kTSA0BWestZoomIn:
    void FullTSA::receiveNotification(Notification *notification, const Notification  
    25482925                        }
    25492926
    25502927                        initializeTBPMonitor(kMonitorNeutral, 0);
     2928                        if (GameState.getTSAState() == kTSAPlayerForcedReview && g_arthurChip)
     2929                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA55", kArthurTSAOpenTBPMonitor);
    25512930                        break;
    25522931                case kTSA0BWestZoomOut:
    25532932                        GameState.setTSA0BZoomedIn(false);
    void FullTSA::receiveNotification(Notification *notification, const Notification  
    25742953                case kTSA22RedEastZoomInSequence:
    25752954                        _privateFlags.setFlag(kTSAPrivateKeyVaultOpenFlag, true);
    25762955                        setCurrentActivation(kActivationKeyVaultOpen);
     2956                        if (g_arthurChip)
     2957                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA50", kArthurTSASawJourneymanKey);
    25772958                        break;
    25782959                case kTSA23RedWestVaultZoomInSequence:
    25792960                        _privateFlags.setFlag(kTSAPrivateChipVaultOpenFlag, true);
    25802961                        setCurrentActivation(kActivationChipVaultOpen);
     2962                        if (g_arthurChip)
     2963                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA54", kArthurTSASawBiochips);
    25812964                        break;
    25822965                case kTSA25NorthPutOnSuit:
    25832966                        GameState.setTSABiosuitOn(true);
    25842967                        GameState.setScoringGotBiosuit(true);
    25852968                        // Fall through...
    25862969                case kTSA25NorthAlreadyHaveSuit:
    2587                         requestExtraSequence(kTSA25NorthDescending1, 0, kFilterNoInput);
     2970                        requestExtraSequence(kTSA25NorthDescending1, kExtraCompletedFlag, kFilterNoInput);
     2971                        break;
     2972                case kTSA25NorthDescending1:
    25882973                        requestExtraSequence(kTSA25NorthDescending2, kExtraCompletedFlag, kFilterNoInput);
     2974                        if (GameState.getTSAState() != kTSAPlayerNeedsHistoricalLog && g_arthurChip)
     2975                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA04", kArthurTSAUsedTurbolift);
    25892976                        break;
    25902977                case kTSA25NorthDescending2:
    25912978                        arriveAt(kTSA26, kNorth);
    void FullTSA::receiveNotification(Notification *notification, const Notification  
    27453132                case kTSA37CongratulationsToExit:
    27463133                        GameState.setTSAState(kPlayerFinishedWithTSA);
    27473134                        initializePegasusButtons(true);
     3135                        if (g_arthurChip) {
     3136                                if (_vm->getRandomBit())
     3137                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA49", kArthurTSASawBaldwinSayGo);
     3138                                else
     3139                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB22", kArthurTSASawBaldwinSayGo);
     3140                        }
    27483141                        break;
    27493142                }
     3143                if (g_arthurChip) {
     3144                        if (doArthurSawBustMovie)
     3145                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA21", kArthurTSASawBust);
     3146                        else if (doArthurRedirectedRobotsMovie && GameState.getTSAState() == kRobotsAtFrontDoor)
     3147                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA02", kArthurTSARedirectedRobots);
     3148                }
    27503149        }
    27513150
    27523151        g_AIArea->checkMiddleArea();
    27533152}
    27543153
     3154void FullTSA::setAmbienceLevel(const uint16 level) {
     3155        Neighborhood::setAmbienceLevel(level);
     3156        if (_entranceMusic.isSoundLoaded())
     3157                _entranceFader.setMasterVolume(level);
     3158}
     3159
    27553160void FullTSA::arriveFromPrehistoric() {
    27563161        if (_vm->playerHasItemID(kHistoricalLog)) {
    27573162                GameState.setScoringFinishedPrehistoric();
  • engines/pegasus/neighborhood/tsa/fulltsa.h

    diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.h b/engines/pegasus/neighborhood/tsa/fulltsa.h
    index a646d57..8f8bacf 100644
    a b public:  
    6868
    6969        void checkContinuePoint(const RoomID, const DirectionConstant);
    7070
     71        void setAmbienceLevel(const uint16);
     72
    7173        bool canSolve();
    7274        void doSolve();
    7375
    protected:  
    99101        void downButton(const Input &);
    100102        void startDoorOpenMovie(const TimeValue, const TimeValue);
    101103        TimeValue getViewTime(const RoomID, const DirectionConstant);
     104        void showViewFrame(TimeValue);
    102105        void findSpotEntry(const RoomID, const DirectionConstant, SpotFlags, SpotTable::Entry &);
    103106        void turnTo(const DirectionConstant);
    104107        CanMoveForwardReason canMoveForward(ExitTable::Entry &);
     108        void moveForward();
    105109        CanOpenDoorReason canOpenDoor(DoorTable::Entry &);
    106110        void bumpIntoWall();
    107111        void initializeTBPMonitor(const int, const ExtraID);
    protected:  
    109113        void getExtraCompassMove(const ExtraTable::Entry &, FaderMoveSpec &);
    110114        Hotspot *getItemScreenSpot(Item *, DisplayElement *);
    111115        void openDoor();
     116        void doorOpened();
    112117        void turnRight();
    113118        void turnLeft();
    114119        void closeDoorOffScreen(const RoomID, const DirectionConstant);
     120        void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits);
    115121        void playExtraMovie(const ExtraTable::Entry &, const NotificationFlags, const InputBits interruptionInput);
     122        void startTurnPush(const TurnDirection, const TimeValue, const DirectionConstant);
    116123        void handleInput(const Input &, const Hotspot *);
    117124        void arriveAtTSA25Red();
    118125        void startUpComparisonMonitor();
    protected:  
    142149        void checkRobotLocations(const RoomID, const DirectionConstant);
    143150        void getExtraEntry(const uint32, ExtraTable::Entry &);
    144151
     152        Movie _extraMovie;
     153        NotificationCallBack _extraMovieCallBack;
     154        Movie _blankMovie;
     155
     156        Sound _entranceMusic;
     157        SoundFader _entranceFader;
     158        bool _playedSolvedMusicCue;
     159        Sound _solvedMusicCue;
     160
    145161        Sprite _sprite1, _sprite2, _sprite3;
    146162        FuseFunction _utilityFuse;
    147163        RipTimer _ripTimer;
  • engines/pegasus/neighborhood/tsa/tinytsa.cpp

    diff --git a/engines/pegasus/neighborhood/tsa/tinytsa.cpp b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
    index 0326c7f..e703929 100644
    a b  
    2828#include "pegasus/pegasus.h"
    2929#include "pegasus/ai/ai_area.h"
    3030#include "pegasus/items/biochips/aichip.h"
     31#include "pegasus/items/biochips/arthurchip.h"
    3132#include "pegasus/items/biochips/opticalchip.h"
    3233#include "pegasus/neighborhood/mars/constants.h"
    3334#include "pegasus/neighborhood/norad/constants.h"
    Common::String TinyTSA::getEnvScanMovie() {  
    179180}
    180181
    181182void TinyTSA::loadAmbientLoops() {
    182         loadLoopSound1("Sounds/TSA/T01NAE.NEW.22K.AIFF");
     183        if (_vm->isDVD()) // Updated sound in the DVD version
     184                loadLoopSound1("Sounds/TSA/T01NAE.NEW.32K.AIFF");
     185        else
     186                loadLoopSound1("Sounds/TSA/T01NAE.NEW.22K.AIFF");
    183187}
    184188
    185189int16 TinyTSA::getStaticCompassAngle(const RoomID room, const DirectionConstant dir) {
    void TinyTSA::receiveNotification(Notification *notification, const Notification  
    385389                                        break;
    386390                                }
    387391                        }
     392                        if (((GameState.getNoradFinished() && !(GameState.getMarsFinished() || GameState.getWSCFinished())) ||
     393                                (GameState.getMarsFinished() && !(GameState.getNoradFinished() || GameState.getWSCFinished())) ||
     394                                (GameState.getWSCFinished() && !(GameState.getNoradFinished() || GameState.getMarsFinished()))) &&
     395                                g_arthurChip)
     396                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB43", kArthurTSASawFirstOpMemMovie);                     
    388397
    389398                        requestExtraSequence(kTinyTSA37OpMemReviewToMainMenu, kExtraCompletedFlag, kFilterNoInput);
    390399                        break;
    void TinyTSA::receiveNotification(Notification *notification, const Notification  
    393402                        GameState.setTSAState(kPlayerLockedInPegasus);
    394403                        showMainJumpMenu();
    395404                        makeContinuePoint();
     405                        if (g_arthurChip)
     406                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA22", kArthurTSAInPegasusNoVideo);
    396407                        break;
    397408                case kTinyTSA37JumpToNoradMenu:
    398409                        setCurrentActivation(kActivationTinyTSAJumpToNorad);
  • engines/pegasus/neighborhood/wsc/wsc.cpp

    diff --git a/engines/pegasus/neighborhood/wsc/wsc.cpp b/engines/pegasus/neighborhood/wsc/wsc.cpp
    index 09e2a48..e7e212c 100644
    a b  
    2323 *
    2424 */
    2525
     26#include "pegasus/cursor.h"
    2627#include "pegasus/energymonitor.h"
    2728#include "pegasus/gamestate.h"
    2829#include "pegasus/pegasus.h"
    2930#include "pegasus/ai/ai_area.h"
     31#include "pegasus/items/biochips/arthurchip.h"
    3032#include "pegasus/items/biochips/opticalchip.h"
    3133#include "pegasus/items/biochips/shieldchip.h"
    3234#include "pegasus/neighborhood/wsc/wsc.h"
    static const CanTurnReason kCantTurnWatchingDiagnosis = kCantTurnLastReason + 1;  
    3941static const CanTurnReason kCantTurnWatchingAnalysis = kCantTurnWatchingDiagnosis + 1;
    4042static const CanTurnReason kCantTurnInMoleculeGame = kCantTurnWatchingAnalysis + 1;
    4143
     44static const ExtraID kImplantNoGun = 1000;
     45static const ExtraID kImplantWithGun = 1001;
     46static const ExtraID kEasterEggWalchek = 1002;
     47
     48static const HotSpotID kBiotechImplantHotSpotID = 10000;
     49
    4250static const TimeScale kMoleculesMovieScale = 600;
    4351static const TimeValue kMoleculeLoopTime = 4 * kMoleculesMovieScale;
    4452static const TimeValue kMoleculeFailTime = 2 * kMoleculesMovieScale;
    static const CoordType kMoleculesMovieLeft = kNavAreaLeft + 112;  
    473481static const CoordType kMoleculesMovieTop = kNavAreaTop + 40;
    474482
    475483WSC::WSC(InputHandler *nextHandler, PegasusEngine *owner) : Neighborhood(nextHandler, owner, "WSC", kWSCID),
    476                 _moleculesMovie(kNoDisplayElement) {
     484                _biotechImplantSpot(kBiotechImplantHotSpotID), _extraMovie(kNoDisplayElement), _moleculesMovie(kNoDisplayElement) {
    477485        setIsItemTaken(kArgonCanister);
    478486        setIsItemTaken(kSinclairKey);
    479487        setIsItemTaken(kNitrogenCanister);
    WSC::WSC(InputHandler *nextHandler, PegasusEngine *owner) : Neighborhood(nextHan  
    486494                        GameState.isTakenItemID(kSinclairKey));
    487495}
    488496
     497WSC::~WSC() {
     498        if (_vm->isDVD())
     499                _vm->getAllHotspots().remove(&_biotechImplantSpot);
     500}
     501
    489502uint16 WSC::getDateResID() const {
    490503        return kDate2310ID;
    491504}
    uint16 WSC::getDateResID() const {  
    493506void WSC::init() {
    494507        Neighborhood::init();
    495508
     509        _extraMovieCallBack.setNotification(&_neighborhoodNotification);
     510
    496511        _cachedZoomSpot = 0;
    497512        _argonSprite = 0;
    498513
    499514        // HACK: Fix the drag item for picking up the Sinclair Key Card
    500515        HotspotInfoTable::Entry *entry = findHotspotEntry(kWSC02SouthTakeArgonSpotID);
    501516        entry->hotspotItem = kArgonPickup;
     517
     518        if (_vm->isDVD()) {
     519                Hotspot *aSpot = _vm->getAllHotspots().findHotspotByID(kW61TimeBendingSpotID);
     520                aSpot->setArea(Common::Rect(97, 156, 275, 174));
     521
     522                _biotechImplantSpot.setArea(Common::Rect(kNavAreaLeft + 97, kNavAreaTop + 174, kNavAreaLeft + 275, kNavAreaTop + 182));
     523                _biotechImplantSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
     524                _vm->getAllHotspots().push_back(&_biotechImplantSpot);
     525        }
    502526}
    503527
    504528void WSC::flushGameState() {
    void WSC::getExtraEntry(const uint32 id, ExtraTable::Entry &extraEntry) {  
    10021026                break;
    10031027        case kW61SouthScreenOnWithGun:
    10041028                if (GameState.isTakenItemID(kMachineGun))
    1005                         Neighborhood::getExtraEntry(id, extraEntry);
    1006                 else
    10071029                        Neighborhood::getExtraEntry(kW61SouthScreenOnNoGun, extraEntry);
     1030                else
     1031                        Neighborhood::getExtraEntry(id, extraEntry);
    10081032                break;
    10091033        case kW61SouthSmartAlloysWithGun:
    10101034                if (GameState.isTakenItemID(kMachineGun))
    1011                         Neighborhood::getExtraEntry(id, extraEntry);
    1012                 else
    10131035                        Neighborhood::getExtraEntry(kW61SouthSmartAlloysNoGun, extraEntry);
     1036                else
     1037                        Neighborhood::getExtraEntry(id, extraEntry);
    10141038                break;
    10151039        case kW61SouthMorphingWithGun:
    10161040                if (GameState.isTakenItemID(kMachineGun))
    1017                         Neighborhood::getExtraEntry(id, extraEntry);
    1018                 else
    10191041                        Neighborhood::getExtraEntry(kW61SouthMorphingNoGun, extraEntry);
     1042                else
     1043                        Neighborhood::getExtraEntry(id, extraEntry);
    10201044                break;
    10211045        case kW61SouthTimeBendingWithGun:
    10221046                if (GameState.isTakenItemID(kMachineGun))
    1023                         Neighborhood::getExtraEntry(id, extraEntry);
    1024                 else
    10251047                        Neighborhood::getExtraEntry(kW61SouthTimeBendingNoGun, extraEntry);
     1048                else
     1049                        Neighborhood::getExtraEntry(id, extraEntry);
    10261050                break;
    10271051        case kW98RobotHeadOpensLight:
    10281052                if (GameState.getWSCCatwalkDark())
    void WSC::bumpIntoWall() {  
    10841108        Neighborhood::bumpIntoWall();
    10851109}
    10861110
     1111void WSC::spotCompleted() {
     1112        Neighborhood::spotCompleted();
     1113        if (_vm->isDVD() && GameState.getCurrentRoomAndView() == MakeRoomView(kWSC58, kSouth) && g_arthurChip) {
     1114                g_AIArea->checkRules();
     1115                if (GameState.isTakenItemID(kCrowbar)) {
     1116                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA94", kArthurWSCSawBrokenDoor);
     1117                } else {
     1118                        if (_vm->getRandomBit())
     1119                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA95", kArthurWSCSawBrokenDoorNoCrowBar);
     1120                        else
     1121                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA39", kArthurWSCSawBrokenDoorNoCrowBar);
     1122                }
     1123        }
     1124}
     1125
    10871126void WSC::closeDoorOffScreen(const RoomID room, const DirectionConstant) {
    10881127        Item *keyCard;
    10891128
    void WSC::cantOpenDoor(CanOpenDoorReason reason) {  
    11301169        switch (GameState.getCurrentRoomAndView()) {
    11311170        case MakeRoomView(kWSC22, kWest):
    11321171                playSpotSoundSync(kNakamuraNotHomeIn, kNakamuraNotHomeOut);
     1172                if (g_arthurChip)
     1173                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11331174                break;
    11341175        case MakeRoomView(kWSC23, kEast):
    11351176                playSpotSoundSync(kHernandezNotHomeIn, kHernandezNotHomeOut);
     1177                if (g_arthurChip)
     1178                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11361179                break;
    11371180        case MakeRoomView(kWSC26, kWest):
    11381181                playSpotSoundSync(kGrailisNotHomeIn, kGrailisNotHomeOut);
     1182                if (g_arthurChip)
     1183                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11391184                break;
    11401185        case MakeRoomView(kWSC27, kEast):
    11411186                playSpotSoundSync(kWashingtonNotHomeIn, kWashingtonNotHomeOut);
     1187                if (g_arthurChip)
     1188                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11421189                break;
    11431190        case MakeRoomView(kWSC32, kWest):
    11441191                playSpotSoundSync(kTheriaultNotHomeIn, kTheriaultNotHomeOut);
     1192                if (g_arthurChip)
     1193                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11451194                break;
    11461195        case MakeRoomView(kWSC33, kEast):
    11471196                playSpotSoundSync(kSullivanNotHomeIn, kSullivanNotHomeOut);
     1197                if (g_arthurChip)
     1198                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11481199                break;
    11491200        case MakeRoomView(kWSC41, kWest):
    11501201                playSpotSoundSync(kGlennerNotHomeIn, kGlennerNotHomeOut);
     1202                if (g_arthurChip)
     1203                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11511204                break;
    11521205        case MakeRoomView(kWSC42, kEast):
    11531206                playSpotSoundSync(kSinclairNotHomeIn, kSinclairNotHomeOut);
     1207                if (!GameState.isTakenItemID(kSinclairKey) && g_arthurChip)
     1208                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA91", kArthurWSCAttemptedSinclairDoorNoKey);
    11541209                break;
    11551210        case MakeRoomView(kWSC15, kWest):
    11561211        case MakeRoomView(kWSC25, kWest):
    void WSC::cantOpenDoor(CanOpenDoorReason reason) {  
    11581213        case MakeRoomView(kWSC41, kEast):
    11591214        case MakeRoomView(kWSC46, kWest):
    11601215                playSpotSoundSync(kWSCLabClosedIn, kWSCLabClosedOut);
     1216                if (g_arthurChip)
     1217                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA98", kArthurWSCAttemptedLockedDoor);
    11611218                break;
    11621219        default:
    11631220                Neighborhood::cantOpenDoor(reason);
    void WSC::zoomTo(const Hotspot *hotspot) {  
    12941351}
    12951352
    12961353void WSC::startExtraSequence(const ExtraID extraID, const NotificationFlags flags, const InputBits interruptionFilter) {
    1297         if (extraID == kW61Brochure)
    1298                 loadLoopSound1("");
     1354        TimeValue segmentStart = 0, segmentStop = 0;
     1355        bool loopSequence = false;
     1356        Common::Rect pushBounds;
     1357        NotificationFlags extraFlags;
     1358
     1359        switch (extraID) {
     1360        case kImplantNoGun:
     1361        case kImplantWithGun:
     1362        case kEasterEggWalchek:
     1363                _turnPush.getBounds(pushBounds);
     1364               
     1365                switch (extraID) {
     1366                case kImplantNoGun:
     1367                        _extraMovie.initFromMovieFile("Images/World Science Center/W61SNF.movie");
     1368                        break;
     1369                case kImplantWithGun:
     1370                        _extraMovie.initFromMovieFile("Images/World Science Center/W61SZF.movie");
     1371                        break;
     1372                case kEasterEggWalchek:
     1373                        _extraMovie.initFromMovieFile("Images/World Science Center/W61WZF.movie");
     1374                        break;
     1375                default:
     1376                        break;
     1377                }
     1378                segmentStart = 0;
     1379                segmentStop = _extraMovie.getDuration();
     1380                loopSequence = false;
     1381               
     1382                _lastExtra = extraID;
     1383                _turnPush.hide();
     1384               
     1385                if (!loopSequence && g_AIArea)
     1386                        g_AIArea->lockAIOut();
     1387               
     1388                extraFlags = flags;
     1389                _interruptionFilter = interruptionFilter;
     1390                // Stop the nav movie before doing anything else
     1391                _navMovie.stop();
     1392                _navMovie.stopDisplaying();
     1393               
     1394                _extraMovie.setVolume(_vm->getSoundFXLevel());
     1395                _extraMovie.moveElementTo(pushBounds.left, pushBounds.top);
     1396                _extraMovie.setDisplayOrder(kNavMovieOrder + 1);
     1397                _extraMovie.startDisplaying();
     1398                _extraMovie.show();
     1399                _extraMovie.setFlags(0);
     1400                _extraMovie.setSegment(segmentStart, segmentStop);
     1401                _extraMovie.setTime(segmentStart);
     1402                if (loopSequence)
     1403                        _extraMovie.setFlags(kLoopTimeBase);
     1404                else
     1405                        extraFlags |= kNeighborhoodMovieCompletedFlag;
     1406                _extraMovieCallBack.cancelCallBack();
     1407                _extraMovieCallBack.initCallBack(&_extraMovie, kCallBackAtExtremes);
     1408                if (extraFlags != 0) {
     1409                        _extraMovieCallBack.setCallBackFlag(extraFlags);
     1410                        _extraMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
     1411                }
     1412                _extraMovie.start();
     1413                break;
     1414        default:
     1415                switch (extraID) {
     1416                case kW61Brochure:
     1417                        loadLoopSound1("");
     1418                        break;
     1419                }
     1420                Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
     1421                if (extraID == kWSCSpinRobot && g_arthurChip) {
     1422                        if (_vm->getRandomBit())
     1423                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA93", kArthurWSCSawAresHologram);
     1424                        else
     1425                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB08", kArthurWSCSawAresHologram);
     1426                }
     1427                break;
     1428        }
     1429}
    12991430
    1300         Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
     1431void WSC::startDoorOpenMovie(const TimeValue startTime, const TimeValue stopTime) {
     1432        Neighborhood::startDoorOpenMovie(startTime, stopTime);
     1433        if (GameState.getCurrentRoomAndView() == MakeRoomView(kWSC58, kSouth) && g_arthurChip)
     1434                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA19", kArthurWSCUsedCrowBar);
    13011435}
    13021436
    13031437int16 WSC::getStaticCompassAngle(const RoomID room, const DirectionConstant dir) {
    void WSC::loadAmbientLoops() {  
    13711505        RoomID room = GameState.getCurrentRoom();
    13721506
    13731507        if (room >= kWSC01 && room <= kWSC04) {
    1374                 if (GameState.getWSCSeenTimeStream())
    1375                         loadLoopSound1("Sounds/World Science Center/WLabLoop.22K.AIFF", 0x100 / 2);
    1376         } else if ((room >= kWSC06 && room <= kWSC58) || (room >= kWSC62 && room <= kWSC63))
    1377                 loadLoopSound1("Sounds/World Science Center/Organic Walls.22K.AIFF", 0x100 / 2);
    1378         else if (room >= kWSC82 && room <= kWSC92)
    1379                 loadLoopSound1("Sounds/World Science Center/Creature Feature.22K.AIFF");
    1380         else if ((room >= kWSC60 && room <= kWSC61West) || (room >= kWSC64 && room <= kWSC81) ||
    1381                         (room >= kWSC93 && room <= kWSC97))
    1382                 loadLoopSound1("Sounds/World Science Center/The Other Side.22K.AIFF", 0x100 / 12);
    1383         else if (room == kWSC98)
    1384                 loadLoopSound1("Sounds/World Science Center/WCatLoop.22K.AIFF");
     1508                if (GameState.getWSCSeenTimeStream()) {
     1509                        if (_vm->isDVD())
     1510                                loadLoopSound1("Sounds/World Science Center/WLabLoop.32K.AIFF", 0x100 / 4);
     1511                        else
     1512                                loadLoopSound1("Sounds/World Science Center/WLabLoop.22K.AIFF", 0x100 / 2);
     1513                        if (_vm->isDVD()) {
     1514                                if (GameState.getWSCPoisoned())
     1515                                        loadLoopSound2("Sounds/World Science Center/Poisoned.32K.16.AIFF", 0x100 / 4);
     1516                                else
     1517                                        loadLoopSound2("");
     1518                        }
     1519                }
     1520        } else {
     1521                if ((room >= kWSC06 && room <= kWSC58) || (room >= kWSC62 && room <= kWSC63)) {
     1522                        if (_vm->isDVD()) // Updated for the DVD version
     1523                                loadLoopSound1("Sounds/World Science Center/Organic Walls.32K.16.AIFF", 205); // ~80%
     1524                        else
     1525                                loadLoopSound1("Sounds/World Science Center/Organic Walls.22K.AIFF", 0x100 / 2);
     1526                } else if (room >= kWSC82 && room <= kWSC92) {
     1527                        if (_vm->isDVD()) // Updated for the DVD version
     1528                                loadLoopSound1("Sounds/World Science Center/Creature Feature.32K.16.AIFF");
     1529                        else
     1530                                loadLoopSound1("Sounds/World Science Center/Creature Feature.22K.AIFF");
     1531                } else if ((room >= kWSC60 && room <= kWSC61West) || (room >= kWSC64 && room <= kWSC81) ||
     1532                                        (room >= kWSC93 && room <= kWSC97)) {
     1533                        if (_vm->isDVD()) // Updated for the DVD version
     1534                                loadLoopSound1("Sounds/World Science Center/The Other Side.32K.16.AIFF", 51); // ~20%
     1535                        else
     1536                                loadLoopSound1("Sounds/World Science Center/The Other Side.22K.AIFF", 0x100 / 12);
     1537                } else if (room == kWSC98) {
     1538                        loadLoopSound1("Sounds/World Science Center/WCatLoop.22K.AIFF");
     1539                }
     1540                loadLoopSound2("");
     1541        }
    13851542}
    13861543
    13871544void WSC::checkContinuePoint(const RoomID room, const DirectionConstant direction) {
    void WSC::arriveAt(const RoomID room, const DirectionConstant dir) {  
    14981655                if (GameState.getWSCDesignedAntidote() && !GameState.getWSCPickedUpAntidote())
    14991656                        setCurrentActivation(kActivationReadyForSynthesis);
    15001657                break;
     1658        case MakeRoomView(kWSC19, kWest):
     1659                if (!(GameState.isTakenItemID(kSinclairKey) && GameState.isTakenItemID(kArgonCanister) &&
     1660                        GameState.isTakenItemID(kNitrogenCanister)) && g_arthurChip)
     1661                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA34", kArthurWSCLeftLabNoKeyOrCanisters);
     1662                break;
    15011663        case MakeRoomView(kWSC16, kNorth):
    15021664                if (getCurrentAlternate() == kAltWSCPeopleAtW19North) {
    15031665                        setCurrentAlternate(kAltWSCNormal);
    15041666                        _privateFlags.setFlag(kWSCPrivateSeenPeopleAt19NorthFlag, true);
    15051667                }
    15061668                break;
     1669        case MakeRoomView(kWSC06, kNorth):
     1670                if (g_arthurChip)
     1671                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA81", kArthurWSCAtOppositeDoor);
     1672                break;
    15071673        case MakeRoomView(kWSC07, kSouth):
    15081674        case MakeRoomView(kWSC56, kNorth):
    15091675                setCurrentActivation(kActivationReadyForMap);
    void WSC::arriveAt(const RoomID room, const DirectionConstant dir) {  
    15141680        case MakeRoomView(kWSC42, kEast):
    15151681                _privateFlags.setFlag(kWSCPrivateSinclairOfficeOpenFlag, false);
    15161682                setCurrentActivation(kActivationSinclairOfficeLocked);
     1683                if (g_arthurChip) {
     1684                        if (GameState.isTakenItemID(kSinclairKey))
     1685                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA99", kArthurWSCSawSinclairDoor);
     1686                        else
     1687                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA92", kArthurWSCSawSinclairDoorNoKey);
     1688                }
    15171689                break;
    15181690        case MakeRoomView(kWSC58, kSouth):
    15191691                setCurrentActivation(kActivationW58SouthDoorLocked);
    void WSC::arriveAt(const RoomID room, const DirectionConstant dir) {  
    15221694        case MakeRoomView(kWSC60, kEast):
    15231695                GameState.setScoringEnteredSinclairOffice();
    15241696                break;
     1697        case MakeRoomView(kWSC60East, kEast):
     1698                if (g_arthurChip)
     1699                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB03", kArthurWSCZoomedToSnake);
     1700                break;
    15251701        case MakeRoomView(kWSC61West, kWest):
    15261702                setCurrentActivation(kActivationW61MessagesOff);
     1703                if (g_arthurChip)
     1704                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB00", kArthurWSCZoomedToSinclairMessages);
    15271705                break;
    15281706        case MakeRoomView(kWSC61South, kSouth):
    15291707                setCurrentActivation(kActivationW61SouthOff);
    void WSC::arriveAt(const RoomID room, const DirectionConstant dir) {  
    15311709        case MakeRoomView(kWSC62, kSouth):
    15321710                if (!GameState.getWSCDidPlasmaDodge()) {
    15331711                        g_AIArea->lockAIOut();
    1534                         loadLoopSound1("Sounds/World Science Center/Plasma Rock.22K.AIFF");
     1712
     1713                        if (_vm->isDVD())
     1714                                loadLoopSound1("Sounds/World Science Center/Plasma Rock.44K.16.AIFF");
     1715                        else
     1716                                loadLoopSound1("Sounds/World Science Center/Plasma Rock.22K.AIFF");
     1717
    15351718                        requestExtraSequence(kW62SouthPlasmaRobotAppears, 0, kFilterNoInput);
    15361719                        requestExtraSequence(kW62ZoomToRobot, 0, kFilterNoInput);
    15371720                        requestExtraSequence(kW62ZoomOutFromRobot, kExtraCompletedFlag, kFilterNoInput);
    15381721                }
    15391722                break;
     1723        case MakeRoomView(kWSC64, kSouth):
     1724                if (g_arthurChip)
     1725                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB06", kArthurWSCEnteredAuditorium);
     1726                break;
    15401727        case MakeRoomView(kWSC65Screen, kSouth):
    15411728                if (!GameState.getWSCSeenSinclairLecture()) {
    15421729                        GameState.setWSCSeenSinclairLecture(true);
    void WSC::arriveAt(const RoomID room, const DirectionConstant dir) {  
    15621749                if (getCurrentAlternate() == kAltWSCW0ZDoorOpen)
    15631750                        turnLeft();
    15641751                break;
     1752        case MakeRoomView(kWSC82, kSouth):
     1753        case MakeRoomView(kWSC82, kEast):
     1754                if (g_arthurChip)
     1755                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB05", kArthurWSCEnteredPassage);
     1756                break;
     1757        case MakeRoomView(kWSC90, kEast):
     1758        case MakeRoomView(kWSC91, kEast):
     1759                if (g_arthurChip)
     1760                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA90", kArthurWSCInPassage);
     1761                break;
    15651762        case MakeRoomView(kWSC93, kEast):
    15661763                GameState.setWSCBeenAtWSC93(true);
     1764        case MakeRoomView(kWSC93, kNorth):
     1765                if (g_arthurChip)
     1766                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA38", kArthurWSCExitedPassage);
     1767                break;
     1768        case MakeRoomView(kWSC95, kWest):
     1769                if (g_arthurChip)
     1770                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA92", kArthurWSCSawCatwalkDoor);
    15671771                break;
    15681772        case MakeRoomView(kWSC98, kWest):
    15691773                if (!GameState.getWSCRobotDead()) {
     1774                        if (_vm->isDVD()) {
     1775                                _welcomeSound.initFromAIFFFile("Sounds/World Science Center/Welcome Enrique.22K.AIFF");
     1776                                _welcomeSound.setVolume(_vm->getSoundFXLevel());
     1777                                _welcomeSound.playSound();
     1778                        }
    15701779                        scheduleEvent(kGawkAtRobotTime2, 1, kTimerEventPlayerGawkingAtRobot2);
    15711780                        setCurrentActivation(kActivationRobotTurning);
    15721781                        if (g_AIArea)
    void WSC::turnTo(const DirectionConstant direction) {  
    16091818                if (GameState.getWSCDesignedAntidote() && !GameState.getWSCPickedUpAntidote())
    16101819                        setCurrentActivation(kActivationReadyForSynthesis);
    16111820                break;
     1821        case MakeRoomView(kWSC06, kNorth):
     1822                if (g_arthurChip)
     1823                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA81", kArthurWSCAtOppositeDoor);
     1824                break;
    16121825        case MakeRoomView(kWSC07, kSouth):
    16131826        case MakeRoomView(kWSC56, kNorth):
    16141827                setCurrentActivation(kActivationReadyForMap);
    void WSC::turnTo(const DirectionConstant direction) {  
    16311844        case MakeRoomView(kWSC42, kEast):
    16321845                _privateFlags.setFlag(kWSCPrivateSinclairOfficeOpenFlag, false);
    16331846                setCurrentActivation(kActivationSinclairOfficeLocked);
     1847                if (GameState.getCurrentRoom() == kWSC42 && g_arthurChip) {
     1848                        if (GameState.isTakenItemID(kSinclairKey))
     1849                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA99", kArthurWSCSawSinclairDoor);
     1850                        else
     1851                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA92", kArthurWSCSawSinclairDoorNoKey);
     1852                }
    16341853                break;
    16351854        case MakeRoomView(kWSC58, kSouth):
    16361855                setCurrentActivation(kActivationW58SouthDoorLocked);
    16371856                _privateFlags.setFlag(kWSCPrivate58SouthOpenFlag, false);
    16381857                break;
     1858        case MakeRoomView(kWSC64, kSouth):
     1859                if (g_arthurChip)
     1860                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB06", kArthurWSCEnteredAuditorium);
     1861                break;
    16391862        case MakeRoomView(kWSC73, kWest):
    16401863                setCurrentAlternate(kAltWSCNormal);
    16411864                break;
    void WSC::turnTo(const DirectionConstant direction) {  
    16431866                if (getCurrentAlternate() == kAltWSCW0ZDoorOpen)
    16441867                        startExtraSequence(kW0ZSpottedByWomen, kExtraCompletedFlag, kFilterNoInput);
    16451868                break;
     1869        case MakeRoomView(kWSC82, kSouth):
     1870        case MakeRoomView(kWSC82, kEast):
     1871                if (g_arthurChip)
     1872                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB05", kArthurWSCEnteredPassage);
     1873                break;
     1874        case MakeRoomView(kWSC95, kWest):
     1875                if (g_arthurChip)
     1876                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA92", kArthurWSCSawCatwalkDoor);
     1877                break;
    16461878        }
    16471879
    16481880        checkPeopleCrossing();
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    16641896                        setCurrentActivation(kActivationShotByRobot);
    16651897                        GameState.setWSCPoisoned(true);
    16661898                        setUpPoison();
     1899                        loadAmbientLoops();
    16671900                        makeContinuePoint();
    16681901                        break;
    16691902                case kWSCDartScan2:
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    16711904                        GameState.setScoringRemovedDart();
    16721905                        GameState.setWSCRemovedDart(true);
    16731906                        setUpPoison();
    1674                         g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XW1WB2", false, kHintInterruption);
    1675                         // Fall through...
    1676                 case kWSCDartScanNo:
     1907                        if (g_AIArea->isChattyAI())
     1908                                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XW1WB2", false, kHintInterruption);
    16771909                        GameState.setWSCAnsweredAboutDart(true);
    16781910                        startExtraSequence(kWSCDartScan3, kExtraCompletedFlag, kFilterNoInput);
    16791911                        break;
    16801912                case kWSCDartScan3:
    16811913                        setCurrentActivation(kActivateHotSpotAlways);
     1914                        if (g_arthurChip)
     1915                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB02", kArthurWSCRemovedDart);
     1916                        break;
     1917                case kWSCDartScanNo:
     1918                        die(kDeathDidntStopPoison);
    16821919                        break;
    16831920                case kWSCAnalyzerPowerUp:
    16841921                case kWSCAnalyzerPowerUpWithDart:
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    17121949                        break;
    17131950                case kWSC02TurnOnMorphScreen:
    17141951                        setCurrentActivation(kActivationReadyForMorph);
     1952                        if (g_arthurChip)
     1953                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA29", kArthurWSCLookAtMorphExperiment);
    17151954                        break;
    17161955                case kWSC02DropToMorphExperiment:
    17171956                        loopExtraSequence(kWSC02MorphLoop, kExtraCompletedFlag);
    17181957                        setCurrentActivation(kActivationMorphLooping);
     1958                        if (g_arthurChip) {
     1959                                if (_vm->getRandomBit())
     1960                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA97", kArthurWSCStartMorphExperiment);
     1961                                else
     1962                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB04", kArthurWSCStartMorphExperiment);
     1963                        }
    17191964                        break;
    17201965                case kWSC02MorphLoop:
    17211966                        if (_privateFlags.getFlag(kWSCPrivateInterruptedMorphFlag))
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    17301975                case kWSC02TurnOffMorphScreen:
    17311976                        setCurrentActivation(kActivationMorphScreenOff);
    17321977                        GameState.setWSCSawMorph(true);
     1978                        if (!(GameState.isTakenItemID(kSinclairKey) && GameState.isTakenItemID(kArgonCanister)) && g_arthurChip)
     1979                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA96", kArthurWSCSawMorphExperiment);
    17331980                        break;
    17341981                case kW03NorthActivate:
    17351982                        if (GameState.getWSCAnalyzedDart() && !GameState.getWSCDesignedAntidote())
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    17552002                        _privateFlags.setFlag(kWSCPrivateInMoleculeGameFlag, false);
    17562003                        GameState.setWSCDesignedAntidote(true);
    17572004                        GameState.setScoringBuiltAntidote();
     2005                        if (g_arthurChip)
     2006                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA02", kArthurWSCDesignedAntidote);
    17582007                        break;
    17592008                case kW03SouthCreateAntidote:
    17602009                        setCurrentActivation(kActivationSynthesizerLooping);
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    17672016                case kWSC56SouthMap:
    17682017                        setCurrentActivation(kActivateHotSpotAlways);
    17692018                        GameState.setScoringSawWSCDirectory();
     2019                        if (g_arthurChip)
     2020                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA33", kArthurWSCReadyForMap);
    17702021                        break;
    17712022                case kNerdAtTheDoor1:
    17722023                        GameState.setWSCSeenNerd(true);
     2024                        if (g_arthurChip)
     2025                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA28", kArthurWSCSeenNerd);
    17732026                        break;
    17742027                case kNerdAtTheDoor2:
    17752028                        die(kDeathArrestedInWSC);
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    17902043                case kW61SouthTimeBendingNoGun:
    17912044                        GameState.setScoringSawSinclairEntry3();
    17922045                        break;
     2046                case kImplantWithGun:
     2047                case kImplantNoGun:
     2048                case kEasterEggWalchek:
     2049                        _extraMovie.stopDisplaying();
     2050                        _extraMovie.releaseMovie();
     2051                        _navMovie.startDisplaying();
     2052                        break;
    17932053                case kW61MessagesOn:
    17942054                        GameState.setWSCOfficeMessagesOpen(true);
    17952055                        setCurrentActivation(kActivationW61MessagesOn);
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    18062066                case kW61SouthScreenOnNoGun:
    18072067                        _privateFlags.setFlag(kWSCPrivateOfficeLogOpenFlag, true);
    18082068                        setCurrentActivation(kActivationW61SouthOn);
     2069                        if (g_arthurChip)
     2070                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA89", kArthurWSCActivatedComputer);
    18092071                        break;
    18102072                case kW61SouthScreenOffWithGun:
    18112073                case kW61SouthScreenOffNoGun:
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    18192081                case kW62ZoomOutFromRobot:
    18202082                        // Handle action queue before starting new movie sequences.
    18212083                        Neighborhood::receiveNotification(notification, flags);
    1822                         _energyDrainRate = g_energyMonitor->getEnergyDrainRate();
    18232084                        g_energyMonitor->setEnergyDrainRate(0);
    18242085                        currentEnergy = g_energyMonitor->getCurrentEnergy();
    18252086                        _vm->setEnergyDeathReason(kDeathHitByPlasma);
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    18472108                                g_energyMonitor->drainEnergy(kPlasmaEnergyNoShield);
    18482109                        }
    18492110
    1850                         g_energyMonitor->setEnergyDrainRate(_energyDrainRate);
     2111                        setUpPoison();
    18512112                        g_AIArea->unlockAI();
    18522113                        GameState.setScoringFinishedPlasmaDodge();
    18532114                        GameState.setWSCDidPlasmaDodge(true);
    18542115                        restoreStriding(kWSC58, kSouth, kAltWSCNormal);
    18552116                        loadAmbientLoops();
     2117                        if (g_arthurChip) {
     2118                                if (_vm->getRandomBit())
     2119                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA11", kArthurWSCDidPlasmaDodge);
     2120                                else
     2121                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB07", kArthurWSCDidPlasmaDodge);
     2122                        }
     2123                        break;
     2124                case kW65SouthSinclairLecture:
     2125                        if (g_arthurChip)
     2126                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB29", kArthurWSCSawSinclairLecture);
    18562127                        break;
    18572128                case kW0ZSpottedByWomen:
    18582129                        die(kDeathArrestedInWSC);
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    19162187                        GameState.setWSCRobotDead(true);
    19172188                        GameState.setScoringStoppedWSCRobot();
    19182189
    1919                         // Video is not present
    1920                         //g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XN59WD", false, kWarningInterruption);
     2190                        // Video is erroneously not present in the CD version
     2191                        if (_vm->isDVD() && g_AIArea->isChattyAI())
     2192                                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XN59WD", false, kWarningInterruption);
    19212193                        break;
    19222194                case kW98RobotGassed:
    19232195                        item = (Item *)_vm->getAllItems().findItemByID(kArgonCanister);
    void WSC::receiveNotification(Notification *notification, const NotificationFlag  
    19262198                        GameState.setWSCRobotDead(true);
    19272199                        GameState.setScoringStoppedWSCRobot();
    19282200
    1929                         // Video is not present
    1930                         //g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XN59WD", false, kWarningInterruption);
     2201                        // Video is erroneously not present in the CD version
     2202                        if (_vm->isDVD() && g_AIArea->isChattyAI())
     2203                                g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XN59WD", false, kWarningInterruption);
    19312204                        break;
    19322205                case kW98RobotHeadOpensLight:
    19332206                case kW98RobotHeadOpensDark:
    19342207                        setCurrentActivation(kActivationWSCRobotHeadOpen);
    19352208                        _privateFlags.setFlag(kWSCPrivateRobotHeadOpenFlag, true);
     2209                        if (g_arthurChip) {
     2210                                switch (_vm->getRandomNumber(2)) {
     2211                                case 0:
     2212                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA36", kArthurWSCRobotHeadOpen);
     2213                                        break;
     2214                                case 1:
     2215                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA37", kArthurWSCRobotHeadOpen);
     2216                                        break;
     2217                                case 2:
     2218                                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA40", kArthurWSCRobotHeadOpen);
     2219                                        break;
     2220                                }
     2221                        }                       
    19362222                        break;
    19372223                case kW98RobotHeadClosesDark:
    19382224                case kW98RobotHeadClosesLight:
    19392225                        setCurrentActivation(kActivationRobotGone);
    19402226                        _privateFlags.setFlag(kWSCPrivateRobotHeadOpenFlag, false);
    19412227                        GameState.setWSCRobotGone(true);
     2228                        if (GameState.isTakenItemID(kStunGun)) {
     2229                                GameState.setWSCFinished(true);
     2230
     2231                                if (!GameState.getWSCCatwalkDark())
     2232                                        GameState.setScoringWSCGandhi();
     2233
     2234                                recallToTSASuccess();
     2235                        }
    19422236                        break;
    19432237                }
     2238                if ((_lastExtra == kW61WalchekEasterEgg1 || _lastExtra == kEasterEggWalchek) && g_arthurChip)
     2239                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA09", kArthurWSCPlayedEasterEggMessage);
    19442240        }
    19452241
    19462242        Neighborhood::receiveNotification(notification, flags);
    void WSC::startMoleculeGameLevel() {  
    20072303        }
    20082304
    20092305        _moleculesMovie.start();
     2306        if (_moleculeGameLevel == 3 && g_arthurChip)
     2307                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA90", kArthurWSCPoisonedDuringGame);
    20102308}
    20112309
    20122310void WSC::moleculeGameClick(const HotSpotID id) {
    void WSC::moleculeGameClick(const HotSpotID id) {  
    20832381
    20842382                _moleculesMovie.stop();
    20852383                startMoleculeGameLevel();
     2384                if (g_arthurChip)
     2385                        g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB38", kArthurWSCFailedMolecule);         
    20862386        }
    20872387}
    20882388
    void WSC::activateOneHotspot(HotspotInfoTable::Entry &entry, Hotspot *hotspot) {  
    21262426}
    21272427
    21282428void WSC::activateHotspots() {
     2429        Input input;
     2430
    21292431        Neighborhood::activateHotspots();
    21302432
    2131         if (GameState.getCurrentRoomAndView() == MakeRoomView(kWSC98, kWest) && _privateFlags.getFlag(kWSCPrivateRobotHeadOpenFlag)) {
    2132                 if (_privateFlags.getFlag(kWSCPrivateGotRetScanChipFlag))
    2133                         _vm->getAllHotspots().deactivateOneHotspot(kW98RetinalChipSpotID);
    2134                 else
    2135                         _vm->getAllHotspots().activateOneHotspot(kW98RetinalChipSpotID);
     2433        switch (GameState.getCurrentRoomAndView()) {
     2434        case MakeRoomView(kWSC61South, kSouth):
     2435                if (_vm->isDVD()) {
     2436                        InputDevice.getInput(input, kFilterAllInput);
     2437                        if (_privateFlags.getFlag(kWSCPrivateOfficeLogOpenFlag) &&
     2438                                JMPPPInput::isEasterEggModifierInput(input))
     2439                                _vm->getAllHotspots().activateOneHotspot(kBiotechImplantHotSpotID);
     2440                }
     2441                break;
     2442        case MakeRoomView(kWSC98, kWest):
     2443                if (_privateFlags.getFlag(kWSCPrivateRobotHeadOpenFlag)) {
     2444                        if (_privateFlags.getFlag(kWSCPrivateGotRetScanChipFlag))
     2445                                _vm->getAllHotspots().deactivateOneHotspot(kW98RetinalChipSpotID);
     2446                        else
     2447                                _vm->getAllHotspots().activateOneHotspot(kW98RetinalChipSpotID);
    21362448
    2137                 if (_privateFlags.getFlag(kWSCPrivateGotMapChipFlag))
    2138                         _vm->getAllHotspots().deactivateOneHotspot(kW98MapChipSpotID);
    2139                 else
    2140                         _vm->getAllHotspots().activateOneHotspot(kW98MapChipSpotID);
     2449                        if (_privateFlags.getFlag(kWSCPrivateGotMapChipFlag))
     2450                                _vm->getAllHotspots().deactivateOneHotspot(kW98MapChipSpotID);
     2451                        else
     2452                                _vm->getAllHotspots().activateOneHotspot(kW98MapChipSpotID);
    21412453
    2142                 if (_privateFlags.getFlag(kWSCPrivateGotOpticalChipFlag))
    2143                         _vm->getAllHotspots().deactivateOneHotspot(kW98OpticalChipSpotID);
    2144                 else
    2145                         _vm->getAllHotspots().activateOneHotspot(kW98OpticalChipSpotID);
     2454                        if (_privateFlags.getFlag(kWSCPrivateGotOpticalChipFlag))
     2455                                _vm->getAllHotspots().deactivateOneHotspot(kW98OpticalChipSpotID);
     2456                        else
     2457                                _vm->getAllHotspots().activateOneHotspot(kW98OpticalChipSpotID);
     2458                }
     2459                break;
    21462460        }
    21472461}
    21482462
    21492463void WSC::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {
     2464        Movie movie(kNoDisplayElement);
     2465        Input movieInput;
     2466
    21502467        if (JMPPPInput::isEasterEggModifierInput(input))
    21512468                GameState.setEasterEgg(true);
    21522469
    void WSC::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {  
    21922509
    21932510                        _privateFlags.setFlag(kWSCPrivateClickedCatwalkCableFlag, true);
    21942511                        break;
     2512                case kBiotechImplantHotSpotID:
     2513                        if (GameState.isTakenItemID(kMachineGun))
     2514                                startExtraSequence(kImplantNoGun, kExtraCompletedFlag, kFilterNoInput);
     2515                        else
     2516                                startExtraSequence(kImplantWithGun, kExtraCompletedFlag, kFilterNoInput);
     2517                        break;
     2518                case kW61WalchekMessageSpotID:
     2519                        if (_vm->isDVD() && GameState.getEasterEgg() && _vm->getRandomBit())
     2520                                startExtraSequence(kEasterEggWalchek, kExtraCompletedFlag, kFilterNoInput);
     2521                        else
     2522                                Neighborhood::clickInHotspot(input, clickedSpot);
     2523                        break;
    21952524                default:
    21962525                        Neighborhood::clickInHotspot(input, clickedSpot);
    21972526                        break;
    void WSC::pickedUpItem(Item *item) {  
    23432672                _privateFlags.setFlag(kWSCDraggingAntidoteFlag, false);
    23442673                playSpotSoundSync(kDrinkAntidoteIn, kDrinkAntidoteOut);
    23452674                setUpPoison();
     2675                loadAmbientLoops();
    23462676
    23472677                if (!GameState.getWSCPickedUpAntidote()) {
    23482678                        GameState.setWSCPickedUpAntidote(true);
    23492679                        startExtraSequence(kW03SouthDeactivate, kExtraCompletedFlag, kFilterNoInput);
    23502680                }
    23512681                break;
     2682        case kMachineGun:
     2683                if (g_arthurChip) {
     2684                        if (_vm->getRandomBit())
     2685                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB01", kArthurWSCGotMachineGun);
     2686                        else
     2687                                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB09", kArthurWSCGotMachineGun);
     2688                }
     2689                break;
    23522690        case kArgonPickup:
    23532691                _vm->removeItemFromInventory((InventoryItem *)item);
    23542692                item = (Item *)_vm->getAllItems().findItemByID(kArgonCanister);
  • engines/pegasus/neighborhood/wsc/wsc.h

    diff --git a/engines/pegasus/neighborhood/wsc/wsc.h b/engines/pegasus/neighborhood/wsc/wsc.h
    index d9634b3..8685115 100644
    a b static const RoomID kWSC62 = 62;  
    4242class WSC : public Neighborhood {
    4343public:
    4444        WSC(InputHandler *, PegasusEngine *);
    45         virtual ~WSC() {}
     45        virtual ~WSC();
    4646
    4747        void flushGameState();
    4848
    protected:  
    126126        void pickedUpItem(Item *);
    127127        void doorOpened();
    128128        void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits);
     129        void startDoorOpenMovie(const TimeValue, const TimeValue);
    129130        void getExtraEntry(const uint32, ExtraTable::Entry &);
    130131        void takeItemFromRoom(Item *item);
    131132        void checkPeopleCrossing();
    protected:  
    137138        void getExitCompassMove(const ExitTable::Entry &exitEntry, FaderMoveSpec &compassMove);
    138139        void getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove);
    139140        void bumpIntoWall();
     141        void spotCompleted();
    140142        void activateHotspots();
    141143        void setUpAIRules();
    142144        Common::String getBriefingMovie();
    protected:  
    153155
    154156        FlagsArray<byte, kNumWSCPrivateFlags> _privateFlags;
    155157        const Hotspot *_cachedZoomSpot;
     158        Hotspot _biotechImplantSpot;
     159        Movie _extraMovie;
     160        NotificationCallBack _extraMovieCallBack;
    156161        MoleculeBin _moleculeBin;
    157162        int32 _moleculeGameLevel, _numCorrect;
    158163        Movie _moleculesMovie;
    159164        uint32 _levelArray[6];
    160         Common::Rational _energyDrainRate;
    161165        Sprite *_argonSprite;
     166        Sound _welcomeSound;
    162167};
    163168
    164169} // End of namespace Pegasus
  • engines/pegasus/pegasus.cpp

    diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp
    index c5edd34..e50dd7e 100644
    a b  
    2323 *
    2424 */
    2525
     26#ifdef MACOSX
     27#define FORBIDDEN_SYMBOL_ALLOW_ALL
     28#endif
     29
    2630#include "common/config-manager.h"
    2731#include "common/error.h"
    2832#include "common/events.h"
     
    5256#include "pegasus/ai/ai_area.h"
    5357#include "pegasus/items/itemlist.h"
    5458#include "pegasus/items/biochips/aichip.h"
     59#include "pegasus/items/biochips/arthurchip.h"
    5560#include "pegasus/items/biochips/biochipitem.h"
    5661#include "pegasus/items/biochips/mapchip.h"
    5762#include "pegasus/items/biochips/opticalchip.h"
     
    7378#include "pegasus/neighborhood/tsa/tinytsa.h"
    7479#include "pegasus/neighborhood/wsc/wsc.h"
    7580
     81#ifdef MACOSX
     82#include <CoreServices/CoreServices.h>
     83#endif
     84
    7685namespace Pegasus {
    7786
    7887PegasusEngine::PegasusEngine(OSystem *syst, const PegasusGameDescription *gamedesc) : Engine(syst), InputHandler(0), _gameDescription(gamedesc),
    PegasusEngine::PegasusEngine(OSystem *syst, const PegasusGameDescription *gamede  
    93102        _idlerHead = 0;
    94103        _currentCD = 1;
    95104        _introTimer = 0;
     105        _toggleRequested = false;
    96106        _aiSaveStream = 0;
     107        _heardOverviewVoice = false;
    97108}
    98109
    99110PegasusEngine::~PegasusEngine() {
    void PegasusEngine::createItems() {  
    261272void PegasusEngine::createItem(ItemID itemID, NeighborhoodID neighborhoodID, RoomID roomID, DirectionConstant direction) {
    262273        switch (itemID) {
    263274        case kInterfaceBiochip:
    264                 // Unused in game, but still in the data and we need to create
    265                 // it because it's saved/loaded from save files.
    266                 new BiochipItem(itemID, neighborhoodID, roomID, direction);
     275                if (isDVD()) {
     276                        new ArthurChip(itemID, neighborhoodID, roomID, direction);
     277                } else {
     278                        // Unused in game, but still in the data and we need to create
     279                        // it because it's saved/loaded from save files.
     280                        new BiochipItem(itemID, neighborhoodID, roomID, direction);
     281                }
    267282                break;
    268283        case kAIBiochip:
    269284                new AIChip(itemID, neighborhoodID, roomID, direction);
    void PegasusEngine::runIntro() {  
    332347        if (shouldQuit() || skipped)
    333348                return;
    334349
     350#ifdef USE_THEORADEC
     351        if (isDVD() && Common::File::exists(_introDirectory + "/BigMovie_hq.ogg")) {
     352                Video::TheoraDecoder hqVideo(Audio::Mixer::kPlainSoundType);
     353
     354                if (hqVideo.loadFile(_introDirectory + "/BigMovie_hq.ogg")) {
     355                        hqVideo.start();
     356                        playMovieScaled(&hqVideo, 0, 0);
     357                        return;
     358                }
     359        }
     360#endif
     361
    335362        video = new Video::QuickTimeDecoder();
    336363
    337364        if (!video->loadFile(_introDirectory + "/Big Movie.movie"))
    338                 error("Could not load intro movie");
     365                if (!video->loadFile(_introDirectory + "/BigMovie.movie"))
     366                        error("Could not load intro movie");
    339367
    340368        video->seek(Audio::Timestamp(0, 10 * 600, 600));
    341369        video->start();
    bool PegasusEngine::loadFromStream(Common::SeekableReadStream *stream) {  
    553581                }
    554582        }
    555583
     584        if (isDVD()) {
     585                Arthur.resetArthurState();
     586                _screenDimmer.hide();
     587                _screenDimmer.stopDisplaying();
     588        }
    556589        startNeighborhood();
     590        if (g_arthurChip)
     591                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB24", kArthurLoadedSavedGame);
    557592
    558593        // Make a new continue point if this isn't already one
    559594        if (saveType == kNormalSave)
    Common::Error PegasusEngine::saveGameState(int slot, const Common::String &desc)  
    716751        bool valid = writeToStream(saveFile, kNormalSave);
    717752        delete saveFile;
    718753
     754#ifdef MACOSX
     755        // HACK HACK HACK HACK: Beyond horrible hack
     756        // clone2727 just died on the inside
     757        if (!valid)
     758                return Common::kUnknownError;
     759
     760        Common::String savePath = ConfMan.get("savepath");
     761        Common::String filePath = savePath + "/" + output;
     762
     763        FSCatalogInfo catInfo;
     764        FSRef ref;
     765
     766        if (!FSPathMakeRef((const UInt8 *)filePath.c_str(), &ref, false)) {
     767                FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catInfo, 0, 0, 0);
     768                FileInfo *info = (FileInfo *)catInfo.finderInfo;
     769                info->fileCreator = kPegasusPrimeCreator;
     770                info->fileType = kPegasusPrimeDisk1GameType + _currentCD - 1;
     771                FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catInfo);
     772        }
     773#endif
     774
    719775        return valid ? Common::kNoError : Common::kUnknownError;
    720776}
    721777
    void PegasusEngine::introTimerExpired() {  
    788844
    789845                bool skipped = false;
    790846
    791                 Video::VideoDecoder *video = new Video::QuickTimeDecoder();
    792                 if (!video->loadFile(_introDirectory + "/LilMovie.movie"))
    793                         error("Failed to load little movie");
     847                Video::VideoDecoder *video = 0;
     848
     849#ifdef USE_THEORADEC
     850                if (isDVD()) {
     851                        video = new Video::TheoraDecoder();
     852
     853                        if (!video->loadFile(_introDirectory + "/LilMovie_hq.ogg")) {
     854                                delete video;
     855                                video = 0;
     856                        }
     857                }
     858#endif
     859
     860                if (!video) {
     861                        video = new Video::QuickTimeDecoder();
     862                        if (!video->loadFile(_introDirectory + "/LilMovie.movie"))
     863                                error("Failed to load little movie");
     864                }
    794865
    795866                bool saveAllowed = swapSaveAllowed(false);
    796867                bool openAllowed = swapLoadAllowed(false);
    void PegasusEngine::doGameMenuCommand(const GameMenuCommand command) {  
    885956                        _gfx->doFadeOutSync();
    886957                        useMenu(new CreditsMenu());
    887958                        _gfx->updateDisplay();
     959                        ((CreditsMenu *)_gameMenu)->startCreditsMenuLoop();
    888960                        _gfx->doFadeInSync();
    889961                }
    890962                break;
    void PegasusEngine::doGameMenuCommand(const GameMenuCommand command) {  
    9291001                                _gfx->updateDisplay();
    9301002                                _gfx->doFadeInSync();
    9311003                        } else {
     1004                                Input input;
     1005                                if (isDVD()) {
     1006                                        InputDevice.getInput(input, kFilterAllInput);
     1007                                        if (JMPPPInput::isEasterEggModifierInput(input))
     1008                                                GameState.setEasterEgg(true);
     1009                                }
     1010
    9321011                                _gfx->doFadeOutSync();
    9331012                                useMenu(0);
    9341013                                _gfx->clearScreen();
    9351014                                _gfx->updateDisplay();
    9361015
    937                                 Video::VideoDecoder *video = new Video::QuickTimeDecoder();
    938                                 if (!video->loadFile(_introDirectory + "/Closing.movie"))
    939                                         error("Could not load closing movie");
     1016                                Video::VideoDecoder *video = 0;
     1017                                if (GameState.getEasterEgg()) {
     1018#ifdef USE_THEORADEC
     1019                                        video = new Video::TheoraDecoder();
     1020                                        if (!video->loadFile(_introDirectory + "/Closing_hq2.ogg")) {
     1021                                                delete video;
     1022                                                video = 0;
     1023                                        }
     1024#endif
     1025                                        if (!video) {
     1026                                                video = new Video::QuickTimeDecoder();
     1027                                                if (!video->loadFile(_introDirectory + "/Closing2.movie"))
     1028                                                        error("Could not load alternate closing movie");
     1029                                        }
     1030                                } else {
     1031#ifdef USE_THEORADEC
     1032                                        video = new Video::TheoraDecoder();
     1033                                        if (!video->loadFile(_introDirectory + "/Closing_hq1.ogg")) {
     1034                                                delete video;
     1035                                                video = 0;
     1036                                        }
     1037#endif
     1038                                        if (!video) {
     1039                                                video = new Video::QuickTimeDecoder();
     1040                                                if (!video->loadFile(_introDirectory + "/Closing.movie"))
     1041                                                        error("Could not load closing movie");
     1042                                        }
     1043                                }
    9401044
    941                                 uint16 x = (640 - video->getWidth() * 2) / 2;
    942                                 uint16 y = (480 - video->getHeight() * 2) / 2;
     1045                                uint16 newHeight = (uint16)((640.0f / (float)video->getWidth()) * (float)video->getHeight());
     1046                                uint16 x = 0;
     1047                                uint16 y = (480 - newHeight) / 2;
    9431048
    9441049                                video->start();
    945                                 playMovieScaled(video, x, y);
     1050                                bool interrupted = playMovieScaled(video, x, y);
    9461051
    9471052                                delete video;
    9481053
     1054                                if (isDVD() && !interrupted) {
     1055                                        // Display new post credits movie
     1056#ifdef USE_THEORADEC
     1057                                        video = new Video::TheoraDecoder();
     1058                                        if (!video->loadFile(_introDirectory + "/Closing_hq3.ogg")) {
     1059                                                delete video;
     1060                                                video = 0;
     1061                                        }
     1062#endif
     1063                                        if (!video) {
     1064                                                video = new Video::QuickTimeDecoder();
     1065                                                if (!video->loadFile(_introDirectory + "/Closing3.movie"))
     1066                                                        error("Could not load closing 3 movie");
     1067                                        }
     1068
     1069                                        video->start();
     1070                                        interrupted = playMovieScaled(video, 0, 0);
     1071                                        delete video;
     1072                                }
     1073
    9491074                                if (shouldQuit())
    9501075                                        return;
    9511076
    952                                 useMenu(new MainMenu());
    953                                 _gfx->updateDisplay();
    954                                 ((MainMenu *)_gameMenu)->startMainMenuLoop();
    955                                 _gfx->doFadeInSync();
    956                                 resetIntroTimer();
     1077                                if (isDVD()) {
     1078                                        useMenu(new CreditsMenu());
     1079                                        _gfx->updateDisplay();
     1080                                        ((CreditsMenu *)_gameMenu)->startCreditsMenuLoop();
     1081                                        if (!interrupted)
     1082                                                _gfx->doFadeInSync();
     1083                                        else
     1084                                                _gfx->enableUpdates();
     1085                                } else {
     1086                                        useMenu(new MainMenu());
     1087                                        _gfx->updateDisplay();
     1088                                        ((MainMenu *)_gameMenu)->startMainMenuLoop();
     1089                                        if (!interrupted)
     1090                                                _gfx->doFadeInSync();
     1091                                        else
     1092                                                _gfx->enableUpdates();
     1093                                        resetIntroTimer();
     1094                                }
     1095                                GameState.setEasterEgg(false);
    9571096                        }
    9581097                } else {
    9591098                        loadFromContinuePoint();
    void PegasusEngine::doInterfaceOverview() {  
    10811220                Common::Rect(542, 36, 542 + 58, 36 + 20)
    10821221        };
    10831222
     1223        static const Common::Rect hiddenSpot = Common::Rect(595, 417, 595 + 4, 417 + 5);
     1224
    10841225        _gfx->doFadeOutSync();
    10851226        useMenu(0);
    10861227
    void PegasusEngine::doInterfaceOverview() {  
    11191260        controllerHighlight.startDisplaying();
    11201261
    11211262        Movie overviewText(kNoDisplayElement);
    1122         overviewText.initFromMovieFile("Images/Interface/Overview Mac.movie");
     1263
     1264        if (isDVD()) {
     1265                if (isLinux() && Common::File::exists("Images/Interface/Overview Linux.movie"))
     1266                        overviewText.initFromMovieFile("Images/Interface/Overview Linux.movie");
     1267                else if (isLinux() || isWindows())
     1268                        overviewText.initFromMovieFile("Images/Interface/Overview PC.movie");
     1269                else
     1270                        overviewText.initFromMovieFile("Images/Interface/Overview ScummVM.movie");
     1271        } else {
     1272                overviewText.initFromMovieFile("Images/Interface/Overview Mac.movie");
     1273        }
     1274
    11231275        overviewText.setDisplayOrder(0);
    11241276        overviewText.moveElementTo(kNavAreaLeft, kNavAreaTop);
    11251277        overviewText.startDisplaying();
    void PegasusEngine::doInterfaceOverview() {  
    11551307        if (time == 2) {
    11561308                highlight.hide();
    11571309                controllerHighlight.show();
     1310
     1311                // Hidden message in the DVD version
     1312                if (isDVD() && hiddenSpot.contains(cursorLoc))
     1313                        time = 12;
    11581314        } else if (i != kNumOverviewSpots) {
    11591315                controllerHighlight.hide();
    11601316                Common::Rect r = overviewSpots[i];
    void PegasusEngine::doInterfaceOverview() {  
    11751331        _gfx->updateDisplay();
    11761332        _gfx->doFadeInSync();
    11771333
     1334        Sound overviewVoice, overviewMusic;
     1335        SoundFader overviewMusicFader;
     1336
     1337        // In the DVD version, play the voice and some background sound
     1338        if (isDVD()) {
     1339                if (!_heardOverviewVoice) {
     1340                        _heardOverviewVoice = true;
     1341                        overviewVoice.initFromAIFFFile("Sounds/Overview.aiff");
     1342                        overviewVoice.playSound();
     1343                }
     1344
     1345                overviewMusic.attachFader(&overviewMusicFader);
     1346                overviewMusic.initFromAIFFFile("Sounds/TSA/T01NAE.NEW.32K.AIFF");
     1347                overviewMusic.loopSound();
     1348
     1349                FaderMoveSpec spec;
     1350                spec.makeTwoKnotFaderSpec(30, 0, 0, 30, 255);
     1351                overviewMusicFader.startFaderSync(spec);
     1352        }
     1353
    11781354        for (;;) {
    11791355                InputDevice.getInput(input, kFilterAllInput);
    11801356
    void PegasusEngine::doInterfaceOverview() {  
    11961372                if (time == 2) {
    11971373                        highlight.hide();
    11981374                        controllerHighlight.show();
     1375
     1376                        // Hidden message in the DVD version
     1377                        if (isDVD() && hiddenSpot.contains(cursorLoc))
     1378                                time = 12;
    11991379                } else if (i != kNumOverviewSpots) {
    12001380                        controllerHighlight.hide();
    12011381                        Common::Rect r = overviewSpots[i];
    void PegasusEngine::doInterfaceOverview() {  
    12241404        highlight.hide();
    12251405        _cursor->hide();
    12261406
     1407        // Make sure we cut off the music and sound
     1408        overviewVoice.stopSound();
     1409
     1410        if (overviewMusic.isPlaying()) {
     1411                FaderMoveSpec spec;
     1412                spec.makeTwoKnotFaderSpec(30, 0, 255, 30, 0);
     1413                overviewMusicFader.startFaderSync(spec);
     1414                overviewMusic.stopSound();
     1415        }
     1416
    12271417        _gfx->doFadeOutSync();
    12281418        useMenu(new MainMenu());
    12291419        _gfx->updateDisplay();
    void PegasusEngine::checkFlashlight() {  
    13891579bool PegasusEngine::playMovieScaled(Video::VideoDecoder *video, uint16 x, uint16 y) {
    13901580        bool skipped = false;
    13911581
     1582        assert(video->isPlaying());
     1583
    13921584        while (!shouldQuit() && !video->endOfVideo() && !skipped) {
    13931585                if (video->needsUpdate()) {
    13941586                        const Graphics::Surface *frame = video->decodeNextFrame();
    void PegasusEngine::doDeath() {  
    14421634        useMenu(new DeathMenu(_deathReason));
    14431635        _gfx->updateDisplay();
    14441636        _gfx->doFadeInSync();
     1637        _deathReason = kDeathStranded;
    14451638}
    14461639
    14471640void PegasusEngine::throwAwayEverything() {
    InputBits PegasusEngine::getInputFilter() {  
    14721665}
    14731666
    14741667void PegasusEngine::processShell() {
    1475         checkCallBacks();
    14761668        checkNotifications();
    14771669        InputHandler::pollForInput();
     1670        checkCallBacks();
    14781671        refreshDisplay();
    14791672}
    14801673
    void PegasusEngine::startNewGame() {  
    16331826        bool isWalkthrough = GameState.getWalkthroughMode();
    16341827        GameState.resetGameState();
    16351828        GameState.setWalkthroughMode(isWalkthrough);
     1829        if (isDVD())
     1830                Arthur.resetArthurState();
    16361831
    16371832        // TODO: Enable erase
    16381833        _gfx->doFadeOutSync();
    void PegasusEngine::dragTerminated(const Input &) {  
    19112106                        delete _draggingSprite;
    19122107        } else if (_dragType == kDragInventoryUse) {
    19132108                if (finalSpot && (finalSpot->getHotspotFlags() & kDropItemSpotFlag) != 0) {
     2109                        delete _draggingSprite;
    19142110                        // *** Need to decide on a case by case basis what to do here.
    19152111                        // the crowbar should break the cover off the Mars reactor if its frozen, the
    19162112                        // global transport card should slide through the slot, the oxygen mask should
    19172113                        // attach to the filling station, and so on...
    19182114                        _neighborhood->dropItemIntoRoom(_draggingItem, finalSpot);
    1919                         delete _draggingSprite;
    19202115                } else {
    19212116                        autoDragItemIntoInventory(_draggingItem, _draggingSprite);
    19222117                }
    void PegasusEngine::autoDragItemIntoRoom(Item *item, Sprite *draggingSprite) {  
    21642359                _system->delayMillis(10);
    21652360        }
    21662361
     2362        delete _draggingSprite;
    21672363        _neighborhood->dropItemIntoRoom(_draggingItem, dropSpot);
    21682364        allowInput(true);
    2169         delete _draggingSprite;
    21702365
    21712366        if (g_AIArea)
    21722367                g_AIArea->unlockAI();
    void PegasusEngine::autoDragItemIntoInventory(Item *, Sprite *draggingSprite) {  
    21972392                _system->delayMillis(10);
    21982393        }
    21992394
     2395        delete _draggingSprite;
    22002396        addItemToInventory((InventoryItem *)_draggingItem);
    22012397        allowInput(true);
    2202         delete _draggingSprite;
    22032398
    22042399        if (g_AIArea)
    22052400                g_AIArea->unlockAI();
    void PegasusEngine::doSubChase() {  
    22642459                if (video->needsUpdate()) {
    22652460                        const Graphics::Surface *frame = video->decodeNextFrame();
    22662461
    2267                         if (frame)
    2268                                 drawScaledFrame(frame, 0, 0);
     2462                        if (frame) {
     2463                                if (frame->w <= 320 && frame->h <= 240) {
     2464                                        drawScaledFrame(frame, 0, 0);
     2465                                } else {
     2466                                        _system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, 0, 0, frame->w, frame->h);
     2467                                        _system->updateScreen();
     2468                                }
     2469                        }
    22692470                }
    22702471
    22712472                Common::Event event;
    void PegasusEngine::destroyInventoryItem(const ItemID itemID) {  
    23672568        g_interface->setCurrentInventoryItemID(itemID);
    23682569        g_AIArea->playAIAreaSequence(kInventorySignature, kMiddleAreaSignature, entry.extraStart, entry.extraStop);
    23692570        removeItemFromInventory(item);
     2571        if (g_arthurChip)
     2572                g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA26", kArthurDestroyedInventoryItem);
    23702573}
    23712574
    23722575ItemID PegasusEngine::pickItemToDestroy() {
  • engines/pegasus/pegasus.h

    diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h
    index fb66eb7..a0d8322 100644
    a b public:  
    9999        bool isDVDDemo() const;
    100100        bool isOldDemo() const;
    101101        bool isWindows() const;
     102        bool isLinux() const;
    102103        void addIdler(Idler *idler);
    103104        void removeIdler(Idler *idler);
    104105        void addTimeBase(TimeBase *timeBase);
    public:  
    124125        int32 getSavedEnergyValue() { return _savedEnergyValue; }
    125126
    126127        // Death
     128        Sound &getDeathSound() { return _deathSound; }
    127129        void setEnergyDeathReason(const DeathReason reason) { _deathReason = reason; }
    128130        DeathReason getEnergyDeathReason() { return _deathReason; }
    129131        void resetEnergyDeathReason();
    130132        void die(const DeathReason);
     133        DeathReason getDeathReason() { return _deathReason; }
    131134        void playEndMessage();
    132135
    133136        // Volume
    public:  
    169172        bool canSolve();
    170173        void prepareForAIHint(const Common::String &);
    171174        void cleanUpAfterAIHint(const Common::String &);
     175        void requestToggle(bool request = true) { _toggleRequested = request; }
     176        bool toggleRequested() const { return _toggleRequested; }
    172177        Common::SeekableReadStream *_aiSaveStream;
    173178
    174179        // Neighborhood
    private:  
    280285        void doInterfaceOverview();
    281286        ScreenDimmer _screenDimmer;
    282287        void pauseMenu(bool menuUp);
     288        bool _heardOverviewVoice;
    283289
    284290        // Energy
    285291        int32 _savedEnergyValue;
    286292
    287293        // Death
    288294        DeathReason _deathReason;
     295        Sound _deathSound;
    289296        void doDeath();
    290297
     298        // AI
     299        bool _toggleRequested;
     300
    291301        // Neighborhood
    292302        Neighborhood *_neighborhood;
    293303        void useNeighborhood(Neighborhood *neighborhood);
  • engines/pegasus/timers.cpp

    diff --git a/engines/pegasus/timers.cpp b/engines/pegasus/timers.cpp
    index 5fb2551..e923a57 100644
    a b void TimeBase::checkCallBacks() {  
    265265                        setTime(_stopTime, _stopScale);
    266266                else if (getRate() > 0 && time == stopTime)
    267267                        setTime(_startTime, _startScale);
    268         } else {
    269                 // Stop at the end
    270                 if ((getRate() > 0 && time == stopTime) || (getRate() < 0 && time == startTime))
    271                         stop();
    272268        }
    273269}
    274270
  • gui/credits.h

    diff --git a/gui/credits.h b/gui/credits.h
    index bcace12..ffcd227 100644
    a b static const char *credits[] = {  
    650650"C0""Jeroen Janssen",
    651651"C2""Numerous readability and bugfix patches",
    652652"C0""Keith Kaisershot",
    653 "C2""Several Pegasus Prime patches",
     653"C2""Several Pegasus Prime patches and DVD additions",
    654654"C0""Andreas Karlsson",
    655655"C2""Initial port for SymbianOS",
    656656"C0""Claudio Matsuoka",
  • ports.mk

    diff --git a/ports.mk b/ports.mk
    index 306e0f0..085f1bd 100644
    a b install:  
    99        $(INSTALL) -d "$(DESTDIR)$(bindir)"
    1010        $(INSTALL) -c -m 755 "./$(EXECUTABLE)" "$(DESTDIR)$(bindir)/$(EXECUTABLE)"
    1111        $(INSTALL) -d "$(DESTDIR)$(mandir)/man6/"
    12         $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/scummvm.6"
     12        $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/PegasusPrime.6"
     13        $(INSTALL) -d "$(DESTDIR)$(datarootdir)/icons/"
     14        $(INSTALL) -c -m 644 "$(srcdir)/dists/pegasus/pegasus.xpm" "$(DESTDIR)$(datarootdir)/icons/pegasus.xpm"
    1315        $(INSTALL) -d "$(DESTDIR)$(datarootdir)/pixmaps/"
    14         $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm"
     16        $(INSTALL) -c -m 644 "$(srcdir)/dists/pegasus/pegasus.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/pegasus.xpm"
    1517        $(INSTALL) -d "$(DESTDIR)$(docdir)"
    1618        $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)"
    1719        $(INSTALL) -d "$(DESTDIR)$(datadir)"
    18         $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/"
     20        $(INSTALL) -c -m 644 $(srcdir)/gui/themes/translations.dat "$(DESTDIR)$(datadir)/"
     21        $(INSTALL) -c -m 644 $(srcdir)/dists/pegasus/scummpegasus.zip "$(DESTDIR)$(datadir)/"
    1922ifdef DYNAMIC_MODULES
    20         $(INSTALL) -d "$(DESTDIR)$(libdir)/scummvm/"
    21         $(INSTALL) -c -m 644 $(PLUGINS) "$(DESTDIR)$(libdir)/scummvm/"
     23        $(INSTALL) -d "$(DESTDIR)$(libdir)/PegasusPrime/"
     24        $(INSTALL) -c -m 644 $(PLUGINS) "$(DESTDIR)$(libdir)/PegasusPrime/"
    2225endif
     26        $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications/"
     27        $(INSTALL) -c -m 644 $(srcdir)/dists/pegasus/PegasusPrime.desktop "$(DESTDIR)$(datarootdir)/applications/"
    2328
    2429install-strip:
    2530        $(INSTALL) -d "$(DESTDIR)$(bindir)"
    2631        $(INSTALL) -c -s -m 755 "./$(EXECUTABLE)" "$(DESTDIR)$(bindir)/$(EXECUTABLE)"
    2732        $(INSTALL) -d "$(DESTDIR)$(mandir)/man6/"
    28         $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/scummvm.6"
     33        $(INSTALL) -c -m 644 "$(srcdir)/dists/scummvm.6" "$(DESTDIR)$(mandir)/man6/PegasusPrime.6"
     34        $(INSTALL) -d "$(DESTDIR)$(datarootdir)/icons/"
     35        $(INSTALL) -c -m 644 "$(srcdir)/dists/pegasus/pegasus.xpm" "$(DESTDIR)$(datarootdir)/icons/pegasus.xpm"
    2936        $(INSTALL) -d "$(DESTDIR)$(datarootdir)/pixmaps/"
    30         $(INSTALL) -c -m 644 "$(srcdir)/icons/scummvm.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm"
     37        $(INSTALL) -c -m 644 "$(srcdir)/dists/pegasus/pegasus.xpm" "$(DESTDIR)$(datarootdir)/pixmaps/pegasus.xpm"
    3138        $(INSTALL) -d "$(DESTDIR)$(docdir)"
    3239        $(INSTALL) -c -m 644 $(DIST_FILES_DOCS) "$(DESTDIR)$(docdir)"
    3340        $(INSTALL) -d "$(DESTDIR)$(datadir)"
    34         $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) "$(DESTDIR)$(datadir)/"
     41        $(INSTALL) -c -m 644 $(srcdir)/gui/themes/translations.dat "$(DESTDIR)$(datadir)/"
     42        $(INSTALL) -c -m 644 $(srcdir)/dists/pegasus/scummpegasus.zip "$(DESTDIR)$(datadir)/"
    3543ifdef DYNAMIC_MODULES
    36         $(INSTALL) -d "$(DESTDIR)$(libdir)/scummvm/"
    37         $(INSTALL) -c -s -m 644 $(PLUGINS) "$(DESTDIR)$(libdir)/scummvm/"
     44        $(INSTALL) -d "$(DESTDIR)$(libdir)/PegasusPrime/"
     45        $(INSTALL) -c -s -m 644 $(PLUGINS) "$(DESTDIR)$(libdir)/PegasusPrime/"
    3846endif
     47        $(INSTALL) -d "$(DESTDIR)$(datarootdir)/applications/"
     48        $(INSTALL) -c -m 644 $(srcdir)/dists/pegasus/PegasusPrime.desktop "$(DESTDIR)$(datarootdir)/applications/"
    3949
    4050uninstall:
    4151        rm -f "$(DESTDIR)$(bindir)/$(EXECUTABLE)"
    42         rm -f "$(DESTDIR)$(mandir)/man6/scummvm.6"
    43         rm -f "$(DESTDIR)$(datarootdir)/pixmaps/scummvm.xpm"
     52        rm -f "$(DESTDIR)$(mandir)/man6/PegasusPrime.6"
     53        rm -f "$(DESTDIR)$(datarootdir)/icons/pegasus.xpm"
     54        rm -f "$(DESTDIR)$(datarootdir)/pixmaps/pegasus.xpm"
    4455        rm -rf "$(DESTDIR)$(docdir)"
    4556        rm -rf "$(DESTDIR)$(datadir)"
    4657ifdef DYNAMIC_MODULES
    47         rm -rf "$(DESTDIR)$(libdir)/scummvm/"
     58        rm -rf "$(DESTDIR)$(libdir)/PegasusPrime/"
    4859endif
     60        rm -f "$(DESTDIR)$(datarootdir)/applications/PegasusPrime.desktop"
    4961
    5062# Special target to create a application wrapper for Mac OS X
    51 bundle_name = ScummVM.app
     63bundle_name = "Pegasus Prime™ OSX.app"
    5264bundle: scummvm-static
    5365        mkdir -p $(bundle_name)/Contents/MacOS
    5466        mkdir -p $(bundle_name)/Contents/Resources
    5567        echo "APPL????" > $(bundle_name)/Contents/PkgInfo
    56         cp $(srcdir)/dists/macosx/Info.plist $(bundle_name)/Contents/
     68        cp $(srcdir)/dists/pegasus/Info.plist $(bundle_name)/Contents/
    5769ifdef USE_SPARKLE
    5870        mkdir -p $(bundle_name)/Contents/Frameworks
    5971        cp $(srcdir)/dists/macosx/dsa_pub.pem $(bundle_name)/Contents/Resources/
    6072        cp -R $(STATICLIBPATH)/Sparkle.framework $(bundle_name)/Contents/Frameworks/
    6173endif
    62         cp $(srcdir)/icons/scummvm.icns $(bundle_name)/Contents/Resources/
     74        cp $(srcdir)/dists/pegasus/pegasus.icns $(bundle_name)/Contents/Resources/
    6375        cp $(DIST_FILES_DOCS) $(bundle_name)/
    64         cp $(DIST_FILES_THEMES) $(bundle_name)/Contents/Resources/
     76        cp $(srcdir)/gui/themes/translations.dat $(bundle_name)/Contents/Resources/
     77        cp $(srcdir)/dists/pegasus/scummpegasus.zip $(bundle_name)/Contents/Resources/
    6578ifdef DIST_FILES_ENGINEDATA
    6679        cp $(DIST_FILES_ENGINEDATA) $(bundle_name)/Contents/Resources/
    6780endif
    osxsnap: bundle  
    235248# Windows specific
    236249#
    237250
    238 scummvmwinres.o: $(srcdir)/icons/scummvm.ico $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(srcdir)/dists/scummvm.rc
     251scummvmwinres.o: $(srcdir)/dists/pegasus/pegasus.ico $(srcdir)/dists/pegasus/scummpegasus.zip $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(srcdir)/dists/scummvm.rc
    239252        $(QUIET_WINDRES)$(WINDRES) -DHAVE_CONFIG_H $(WINDRESFLAGS) $(DEFINES) -I. -I$(srcdir) $(srcdir)/dists/scummvm.rc scummvmwinres.o
    240253
    241254# Special target to create a win32 snapshot binary (for Inno Setup)