Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "asylum/views/insertdisc.h"
#include "asylum/system/cursor.h"
#include "asylum/system/graphics.h"
#include "asylum/system/screen.h"
#include "asylum/system/text.h"
#include "asylum/asylum.h"
namespace Asylum {
InsertDisc::InsertDisc(AsylumEngine *engine) : _vm(engine) {
_handler = nullptr;
_cdNumber = -1;
_frameIndex = _frameCount = 0;
}
void InsertDisc::init() {
getScreen()->setPalette(MAKE_RESOURCE(kResourcePackSound, 10 + _cdNumber));
getScreen()->setGammaLevel(MAKE_RESOURCE(kResourcePackSound, 10 + _cdNumber));
getText()->loadFont(MAKE_RESOURCE(kResourcePackSound, 19));
_frameIndex = 0;
_frameCount = GraphicResource::getFrameCount(_vm, MAKE_RESOURCE(kResourcePackSound, 13 + _cdNumber));
}
void InsertDisc::update() {
getCursor()->hide();
getScreen()->draw(MAKE_RESOURCE(kResourcePackSound, 7 + _cdNumber), 0, Common::Point( 0, 0));
getScreen()->draw(MAKE_RESOURCE(kResourcePackSound, 13 + _cdNumber), _frameIndex, Common::Point(295, 206));
getText()->drawCentered(Common::Point(0, 40), 640, MAKE_RESOURCE(kResourcePackText, 1416 + _cdNumber));
getScreen()->copyBackBufferToScreen();
_frameIndex = (_frameIndex + 1) % _frameCount;
}
bool InsertDisc::handleEvent(const AsylumEvent &evt) {
switch ((int32)evt.type) {
default:
break;
case EVENT_ASYLUM_INIT:
init();
return true;
case EVENT_ASYLUM_UPDATE:
update();
return true;
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_KEYDOWN:
case Common::EVENT_JOYBUTTON_DOWN:
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
_vm->switchEventHandler(_handler);
return true;
}
return false;
}
} // End of namespace Asylum

View File

@@ -0,0 +1,53 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ASYLUM_VIEWS_INSERTDISC_H
#define ASYLUM_VIEWS_INSERTDISC_H
#include "asylum/eventhandler.h"
namespace Asylum {
class AsylumEngine;
class InsertDisc : public EventHandler {
public:
InsertDisc(AsylumEngine *engine);
~InsertDisc() {};
void setCdNumber(int cdNumber) { _cdNumber = cdNumber; }
void setEventHandler(EventHandler *handler) { _handler = handler; }
bool handleEvent(const AsylumEvent &evt);
private:
AsylumEngine *_vm;
EventHandler *_handler;
int _cdNumber;
uint _frameIndex;
uint _frameCount;
void init();
void update();
};
} // End of namespace Asylum
#endif // ASYLUM_VIEWS_INSERTDISC_H

File diff suppressed because it is too large Load Diff

258
engines/asylum/views/menu.h Normal file
View File

@@ -0,0 +1,258 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ASYLUM_VIEWS_MENU_H
#define ASYLUM_VIEWS_MENU_H
#include "graphics/surface.h"
#include "asylum/eventhandler.h"
#include "asylum/shared.h"
namespace Asylum {
class AsylumEngine;
class Cursor;
class GraphicResource;
class ResourcePack;
class Scene;
class Text;
class Menu : public EventHandler {
public:
Menu(AsylumEngine *vm);
virtual ~Menu() {};
/**
* Shows the menu
*/
void show();
/**
* Handle event.
*
* @param evt The event.
*
* @return true if it succeeds, false if it fails.
*/
bool handleEvent(const AsylumEvent &evt);
/**
* Sets the game as started.
*/
void setGameStarted() { _gameStarted = true; }
// Savegames
void setDword455C78(bool state) { _dword_455C78 = state; }
void setDword455C80(bool state) { _dword_455C80 = state; }
void setLoadingDuringStartup() { _loadingDuringStartup = true; }
bool isEditingSavegameName() { return _activeScreen == kMenuSaveGame && _isEditingSavegameName; };
bool isConfiguringKeyboard() { return _activeScreen == kMenuKeyboardConfig && _selectedShortcutIndex != -1; }
private:
AsylumEngine *_vm;
enum MenuScreen {
kMenuNone = -1,
kMenuNewGame = 0,
kMenuLoadGame = 1,
kMenuSaveGame = 2,
kMenuDeleteGame = 3,
kMenuViewMovies = 4,
kMenuQuitGame = 5,
kMenuTextOptions = 6,
kMenuAudioOptions = 7,
kMenuSettings = 8,
kMenuKeyboardConfig = 9,
kMenuReturnToGame = 10,
kMenuShowCredits = 11
};
enum MenuResource {
kMenuResourceNone = 0,
kBackground = MAKE_RESOURCE(kResourcePackShared, 0),
kEye = MAKE_RESOURCE(kResourcePackShared, 1),
kFontBlue = MAKE_RESOURCE(kResourcePackShared, 22),
kFontYellow = MAKE_RESOURCE(kResourcePackShared, 16),
kSfxSound = MAKE_RESOURCE(kResourcePackShared, 41),
kAmbientSound = MAKE_RESOURCE(kResourcePackShared, 42),
kVoiceSound = MAKE_RESOURCE(kResourcePackShared, 43)
};
// Game initialization
bool _initGame;
// Data
MenuScreen _activeScreen;
ResourceId _soundResourceId;
ResourceId _musicResourceId;
bool _gameStarted;
MenuScreen _currentIcon;
int32 _selectedShortcutIndex;
int32 _dword_455C74;
bool _dword_455C78;
bool _dword_455C80;
bool _dword_455D4C;
bool _dword_455D5C;
bool _isEditingSavegameName;
bool _testSoundsPlaying;
int32 _dword_456288;
int32 _caretBlink;
int32 _startIndex;
int32 _creditsFrameIndex;
int32 _creditsNumSteps;
bool _showMovie;
uint32 _iconFrames[12];
// Movies
int32 _movieList[196];
uint32 _movieCount;
uint32 _movieIndex;
// Savegames
Common::String _previousName;
int32 _prefixWidth;
bool _loadingDuringStartup;
// Thumbnails
int _thumbnailIndex;
Graphics::Surface _thumbnailSurface;
/**
* Setups menu screen
*/
void setup();
/**
* Leaves an opened menu
*/
void leave();
/**
* Switch between fonts.
*
* @param condition if true, load kFontYellow, if false, load kFontBlue.
*/
void switchFont(bool condition);
/**
* Close the credits.
*/
void closeCredits();
/**
* Sets up the music.
*/
void setupMusic();
/**
* Find if the mouse if on an icon
*
* @return The icon identifier
*/
MenuScreen findMousePosition();
/**
* Play test sounds
*/
void playTestSounds();
/**
* Stop test sounds.
*/
void stopTestSounds();
/**
* Adjust volume.
*
* @param delta The delta.
*/
void adjustMasterVolume(int32 delta) const;
/**
* Adjust test sounds volume.
*/
void adjustTestVolume();
/**
* Adjust performance.
*/
void adjustPerformance();
/**
* Gets the chapter name.
*
* @return The chapter name.
*/
Common::String getChapterName();
//////////////////////////////////////////////////////////////////////////
// Message handling
bool init();
bool update();
bool music();
bool key(const AsylumEvent &evt);
bool click(const AsylumEvent &evt);
// Thumbnails
bool hasThumbnail(int index);
void readThumbnail();
void showThumbnail();
// Update handlers
void updateNewGame();
void updateLoadGame();
void updateSaveGame();
void updateDeleteGame();
void updateViewMovies();
void updateQuitGame();
void updateTextOptions();
void updateAudioOptions();
void updateSettings();
void updateKeyboardConfig();
void updateReturnToGame();
void updateShowCredits();
// Click handlers
void clickNewGame();
void clickLoadGame();
void clickSaveGame();
void clickDeleteGame();
void clickViewMovies();
void clickQuitGame();
void clickTextOptions();
void clickAudioOptions();
void clickSettings();
void clickKeyboardConfig();
void clickReturnToGame();
void clickShowCredits();
// Key handlers
void keySaveGame(const AsylumEvent &evt);
void keyKeyboardConfig(const AsylumEvent &evt);
void keyShowCredits();
}; // end of class MainMenu
} // end of namespace Asylum
#endif // ASYLUM_VIEWS_MENU_H

View File

@@ -0,0 +1,263 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "asylum/views/resviewer.h"
#include "asylum/system/cursor.h"
#include "asylum/system/screen.h"
#include "asylum/system/text.h"
#include "asylum/asylum.h"
#include "asylum/respack.h"
#include "backends/keymapper/keymap.h"
#include "backends/keymapper/keymapper.h"
namespace Asylum {
#define SCROLL_STEP 10
#define NOPALETTE {0, 0, 0, 0, 0, 0, 0, 0}
static int paletteIds[][8] {
NOPALETTE,
{0x0011, 0x001A, 0x001F, 0x003B, 0x003C},
NOPALETTE,
NOPALETTE,
NOPALETTE,
{0x0014, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x00B7, 0x00CD},
{0x0014, 0x0020, 0x026C, 0x0277, 0x02A6},
{0x0014, 0x0018, 0x0019, 0x001A, 0x0163, 0x0191},
{0x0014, 0x0018, 0x01BC},
{0x0014, 0x008C, 0x00AB, 0x00D4},
{0x0014, 0x001E, 0x001F, 0x0171, 0x0185, 0x01C0},
{0x0012, 0x001F, 0x011B, 0x011E, 0x0120, 0x0135, 0x0159},
{0x0014, 0x018F, 0x01A3, 0x01B0, 0x01C1},
{0x0014, 0x019D, 0x019E, 0x019F, 0x01A7},
{0x0014, 0x001E, 0x001F, 0x0121, 0x0124},
{0x0014, 0x00AD},
{0x0014, 0x0018, 0x0095},
{0x0014, 0x006B},
{0x000B, 0x000C, 0x000D}
};
static const int resPackSizes[] = {
4112, 61, 28, 534, 1, 215, 701, 418, 458, 230, 475, 354, 461, 459, 310, 176, 168, 121, 22
};
ResourceViewer::ResourceViewer(AsylumEngine *engine) : _vm(engine), _resource(_vm) {
_handler = nullptr;
_resourceId = kResourceNone;
_frameIndex = _frameCount = 0;
_frameIncrement = 1;
_x = _y = 0;
_width = _height = 0;
_scroll = false;
_resPack = -1;
_paletteIndex = 0;
_animate = true;
Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
_keymap = keymapper->getKeymap(resviewerKeyMapId);
}
bool ResourceViewer::setResourceId(ResourceId resourceId) {
if (resourceId == kResourceNone ||
!getResource()->get(resourceId) ||
strncmp((const char *)getResource()->get(resourceId)->data, "D3GR", 4))
return false;
_resourceId = resourceId;
_frameIndex = 0;
_frameCount = GraphicResource::getFrameCount(_vm, _resourceId);
_resource.load(_resourceId);
_frameIncrement = 1;
_x = _y = 0;
if (isPalette(_resourceId)) {
_width = 0;
_height = 0;
} else {
_width = _resource.getFrame(0)->getWidth();
_height = _resource.getFrame(0)->getHeight();
}
_scroll = _width > 640 || _height > 480;
_resPack = RESOURCE_PACK(_resourceId);
_paletteIndex = 0;
int fontIndex = 13;
if (_resPack == 1)
fontIndex = 16;
else if (_resPack == 18)
fontIndex = 19;
getText()->loadFont(MAKE_RESOURCE(_resPack, fontIndex));
return true;
}
void ResourceViewer::drawResource() {
int16 x, y;
GraphicFrame *frame = _resource.getFrame(_frameIndex);
if (_scroll) {
x = _x;
y = _y;
} else {
x = (640 - frame->getWidth()) / 2 - frame->x;
y = (480 - frame->getHeight()) / 2 - frame->y;
}
getScreen()->setPalette(MAKE_RESOURCE(_resPack, paletteIds[_resPack][_paletteIndex]));
getScreen()->draw(_resourceId, _frameIndex, Common::Point(x, y));
if (_frameCount > 1 && _animate) {
if (_frameIndex + 1 >= (int)_frameCount)
_frameIncrement = -1;
else if (_frameIndex == 0)
_frameIncrement = 1;
_frameIndex += _frameIncrement;
}
}
bool ResourceViewer::isPalette(ResourceId resourceId) {
return getResource()->get(resourceId)->size == 800;
}
void ResourceViewer::drawPalette() {
const int size = 20;
const int x0 = (640 - size * 16) / 2, y0 = (480 - size * 16) / 2;
getScreen()->setPalette(_resourceId);
for (int i = 0, color = 0; i < 16; i++)
for (int j = 0; j < 16; j++, color++)
getScreen()->fillRect(x0 + j * size, y0 + i * size, size, size, color);
}
void ResourceViewer::update() {
getCursor()->hide();
getScreen()->clear();
if (isPalette(_resourceId))
drawPalette();
else
drawResource();
getText()->draw(Common::Point(615, 440), Common::String::format("%X", _resourceId).c_str());
getScreen()->copyBackBufferToScreen();
}
void ResourceViewer::action(const AsylumEvent &evt) {
switch ((AsylumAction)evt.customType) {
default:
break;
case kAsylumActionShowMenu:
_vm->switchEventHandler(_handler);
break;
case kAsylumActionNextResource:
if (RESOURCE_INDEX(_resourceId) < resPackSizes[_resPack] - 1) {
int i = 1;
do {
if (setResourceId(_resourceId + i))
break;
i++;
} while (RESOURCE_INDEX(_resourceId + i) < resPackSizes[_resPack] - 1);
}
break;
case kAsylumActionPreviousResource:
if (RESOURCE_INDEX(_resourceId)) {
int i = 0;
do {
i++;
if (setResourceId(_resourceId - i))
break;
} while (RESOURCE_INDEX(_resourceId - i));
}
break;
case kAsylumActionAnimate:
_animate = !_animate;
break;
case kAsylumActionMoveUp:
case kAsylumActionMoveDown:
case kAsylumActionMoveRight:
case kAsylumActionMoveLeft:
if (_scroll) {
int16 x = _x, y = _y;
int dir = (int)(evt.customType - kAsylumActionMoveUp);
if (dir < 2)
y -= SCROLL_STEP * (2 * dir - 1);
else
x -= SCROLL_STEP * (1 - 2 * (dir - 2));
if (640 - x <= _width && x <= 0 && 480 - y <= _height && y <= 0) {
_x = x;
_y = y;
}
}
break;
case kAsylumActionPreviousPalette:
if (_paletteIndex)
_paletteIndex = _paletteIndex - 1;
break;
case kAsylumActionNextPalette:
if (_paletteIndex < 8 && paletteIds[_resPack][_paletteIndex + 1])
_paletteIndex = _paletteIndex + 1;
break;
}
}
bool ResourceViewer::handleEvent(const AsylumEvent &evt) {
switch ((int32)evt.type) {
default:
break;
case EVENT_ASYLUM_INIT:
_keymap->setEnabled(true);
return true;
case EVENT_ASYLUM_DEINIT:
_keymap->setEnabled(false);
return true;
case EVENT_ASYLUM_UPDATE:
update();
return true;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
action(evt);
return true;
}
return false;
}
} // End of namespace Asylum

View File

@@ -0,0 +1,73 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ASYLUM_VIEWS_RESVIEWER_H
#define ASYLUM_VIEWS_RESVIEWER_H
#include "asylum/system/graphics.h"
#include "asylum/eventhandler.h"
#include "asylum/shared.h"
namespace Common {
class Keymap;
}
namespace Asylum {
class AsylumEngine;
class ResourceViewer : public EventHandler {
public:
ResourceViewer(AsylumEngine *engine);
~ResourceViewer() {};
void setEventHandler(EventHandler *handler) { _handler = handler; }
bool setResourceId(ResourceId resourceId);
bool handleEvent(const AsylumEvent &evt);
private:
AsylumEngine *_vm;
EventHandler *_handler;
Common::Keymap *_keymap;
ResourceId _resourceId;
GraphicResource _resource;
int _frameIndex;
uint _frameCount;
int _frameIncrement;
int16 _x, _y;
uint16 _width, _height;
bool _scroll;
int _resPack;
int _paletteIndex;
bool _animate;
bool isPalette(ResourceId resourceId);
void drawPalette();
void drawResource();
void action(const AsylumEvent &evt);
void update();
};
} // End of namespace Asylum
#endif // ASYLUM_VIEWS_RESVIEWER_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,492 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ASYLUM_VIEWS_SCENE_H
#define ASYLUM_VIEWS_SCENE_H
#include "common/array.h"
#include "common/events.h"
#include "common/rational.h"
#include "graphics/surface.h"
#include "asylum/system/screen.h"
#include "asylum/eventhandler.h"
#include "asylum/shared.h"
#define SCENE_FILE_MASK "scn.%03d"
#define MUSIC_FILE_MASK "mus.%03d"
// If defined, will show the scene update times on the debugger output
//#define DEBUG_SCENE_TIMES
namespace Asylum {
class Actor;
class AsylumEngine;
class Puzzle;
class Cursor;
class GraphicResource;
class Polygons;
class Polygon;
class ResourcePack;
class SceneTitle;
class Screen;
class Special;
class Speech;
class Sound;
class Text;
class VideoPlayer;
class WorldStats;
struct ActionArea;
struct AmbientSoundItem;
struct GraphicFrame;
struct ObjectItem;
enum HitType {
kHitNone = -1,
kHitActionArea = 2,
kHitObject = 3,
kHitActor = 4
};
enum ActionAreaType {
kActionAreaType1 = 1,
kActionAreaType2 = 2
};
enum KeyDirection {
kWalkUp = 1,
kWalkDown = 2,
kWalkLeft = 4,
kWalkRight = 8
};
class Scene : public EventHandler {
public:
Scene(AsylumEngine *engine);
virtual ~Scene();
/**
* Load the scene data
*
* @param packId Package id for the scene.
*/
void load(ResourcePackId packId);
/**
* Enter a scene
*
* @param packId Package id for the scene.
*/
void enter(ResourcePackId packId);
/**
* Enter the scene after a loaded game
*/
void enterLoad();
/**
* Handle events
*
* @param ev The event
*
* @return true if it succeeds, false if it fails.
*/
bool handleEvent(const AsylumEvent &ev);
/**
* Gets the current scene pack identifier.
*
* @return The pack identifier.
*/
ResourcePackId getPackId() { return _packId; }
/**
* Get a reference to an actor object from the
* WorldStats actor list. Default parameter just
* gets the instance associated with _playerActorIdx
*/
Actor *getActor(ActorIndex index = kActorInvalid);
/**
* Change player actor
*
* @param index new index for the player actor
*/
void changePlayer(ActorIndex index);
/**
* Update player position when changing current player
*
* @param index Zero-based index of the actor
*/
void changePlayerUpdate(ActorIndex index);
/**
* Updates the scene coordinates.
*
* @param targetX Target x coordinate.
* @param targetY Target y coordinate.
* @param val The value.
* @param checkSceneCoords true to check scene coordinates.
* @param [in,out] param If non-null, the parameter.
*
* @return true if it succeeds, false if it fails.
*/
bool updateSceneCoordinates(int32 targetX, int32 targetY, int32 val, bool checkSceneCoords = false, int32 *param = NULL);
/**
* Updates the screen
*
* @return true if it succeeds, false if it fails.
*/
bool updateScreen();
/**
* Updates the ambient sounds.
*/
void updateAmbientSounds();
/**
* Rain drawing function for chapter 5.
*/
void drawRain();
/**
* Determine if the supplied point intersects an action area's active region.
*
* @param type The type.
* @param pt The point.
* @param highlight (optional) whether to highlight the polygons as they are checked.
*
* @return The found action area.
*/
int32 findActionArea(ActionAreaType type, const Common::Point &pt, bool highlight = false);
/**
* Check if rectangles intersect.
*
* @param x The x coordinate.
* @param y The y coordinate.
* @param x1 The first x value.
* @param y1 The first y value.
* @param x2 The second x value.
* @param y2 The second y value.
* @param x3 The third int32.
* @param y3 The third int32.
*
* @return true if it succeeds, false if it fails.
*/
bool rectIntersect(int32 x, int32 y, int32 x1, int32 y1, int32 x2, int32 y2, int32 x3, int32 y3) const;
Polygons *polygons() { return _polygons; }
WorldStats *worldstats() { return _ws; }
uint32 getFrameCounter() { return _frameCounter; }
const byte *getSavedPalette() { return _savedPalette; }
const Graphics::Surface &getSavedScreen() { return _savedScreen; }
private:
AsylumEngine *_vm;
ResourcePackId _packId;
Polygons *_polygons;
WorldStats *_ws;
struct UpdateItem {
ActorIndex index;
int32 priority;
};
// Music volume
int32 _musicVolume;
Common::Array<UpdateItem> _updateList;
uint32 _frameCounter;
Graphics::Surface _savedScreen;
byte _savedPalette[PALETTE_SIZE];
bool _debugShowVersion;
byte _keyState;
bool _rightButtonDown;
//////////////////////////////////////////////////////////////////////////
// Message handling
void activate();
bool init();
bool update();
bool actionDown(AsylumAction a);
bool actionUp(AsylumAction a);
bool key(const AsylumEvent &evt);
bool clickDown(const AsylumEvent &evt);
//////////////////////////////////////////////////////////////////////////
// Scene update
//////////////////////////////////////////////////////////////////////////
/**
* Loop through the various update blocks (actors, objects, mouse, music, sfx, coordinates), then process the current action script.
*
* @return true if the script is done executing, false otherwise
*/
bool updateScene();
/**
* Updates the mouse.
*/
void updateMouse();
/**
* Updates the actors.
*/
void updateActors();
/**
* Updates the objects.
*/
void updateObjects();
/**
* Updates the music.
*/
void updateMusic();
/**
* Updates the screen
*
* - update coordinates or allow scrolling if the proper debug option is set
*/
void updateAdjustScreen();
/**
* Updates the screen coordinates.
*/
void updateCoordinates();
/**
* Update cursor
*
* @param direction The direction.
* @param rect The rectangle.
*/
void updateCursor(ActorDirection direction, const Common::Rect &rect);
//////////////////////////////////////////////////////////////////////////
// Scene drawing
//////////////////////////////////////////////////////////////////////////
/**
* Draw the loading screen
*/
void preload();
/**
* Draw the scene
*
* @return true if it succeeds, false if it fails.
*/
bool drawScene();
/**
* Builds the update list.
*/
void buildUpdateList();
/**
* Process the update list.
*/
void processUpdateList();
/**
* Compare two items priority on the update list
*
* @param item1 The first item.
* @param item2 The second item.
*
* @return true item1 priority is superior to item2 priority, false otherwise
*/
static bool updateListCompare(const UpdateItem &item1, const UpdateItem &item2);
/**
* Check visible actors priority.
*/
void checkVisibleActorsPriority();
/**
* Adjust actor priority.
*
* @param index Zero-based index of the actor
*/
void adjustActorPriority(ActorIndex index);
int32 _chapter5RainFrameIndex;
//////////////////////////////////////////////////////////////////////////
// HitTest
//////////////////////////////////////////////////////////////////////////
/**
* Run various hit tests and return the index, and a reference to the located type.
*
* @param [in,out] type The type.
*
* @return The index
*/
int32 hitTest(HitType &type);
/**
* Checks if the supplied coordinates are inside an action area, object or actor, and returns -1 if nothing was found, or the type of hit if
* found.
*
* @param [in,out] type The type.
*
* @return The Index
*/
int32 hitTestScene(HitType &type);
/**
* Check if the mouse cursor is currently intersecting an action area
*
* @return the index
*/
int32 hitTestActionArea();
/**
* Check if the mouse cursor is currently intersecting the currently active actor.
*
* @return The actor index
*/
ActorIndex hitTestActor();
/**
* Check if the mouse cursor is currently intersecting the player.
*
* @return true if it succeeds, false if it fails.
*/
bool hitTestPlayer();
/**
* Check if a object exist at the supplied coordinates. If so, return it's index within the objects array, if not, return -1.
*
* @return the object index
*/
int32 hitTestObject();
/**
* Check if the mouse cursor is currently intersecting a graphic resource at the supplied coordinates.
*
* @param resourceId Identifier for the resource.
* @param frame The frame.
* @param x The x coordinate.
* @param y The y coordinate.
* @param flipped true to flipped.
*
* @return true if it succeeds, false if it fails.
*/
bool hitTestPixel(ResourceId resourceId, uint32 frame, int16 x, int16 y, bool flipped);
//////////////////////////////////////////////////////////////////////////
// Hit actions
//////////////////////////////////////////////////////////////////////////
/**
* Handle hit
*
* @param index The index
* @param type The type.
*/
void handleHit(int32 index, HitType type);
void clickInventory();
void hitAreaChapter2(int32 id);
bool _isCTRLPressed;
int32 _hitAreaChapter7Counter;
void hitAreaChapter7(int32 id);
void hitAreaChapter11(int32 id);
void hitActorChapter2(ActorIndex index);
void hitActorChapter11(ActorIndex index);
//////////////////////////////////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////////////////////////////////
/**
* Play intro speech.
*/
void playIntroSpeech();
/**
* Stop speech.
*/
void stopSpeech();
/**
* Play specific speech.
*
* @param code The key code.
*
* @return true if it succeeds, false if it fails.
*/
bool speak(Common::KeyCode code);
/**
* Check if a point lies below the rectangle's top-left to bottom-right diagonal.
*
* @param point The point.
* @param rect The rectangle.
*
* @return true if below, false if above.
*/
bool pointBelowLine(const Common::Point &point, const Common::Rect &rect) const;
/**
* Adjust coordinates.
*
* @param point The point.
*/
void adjustCoordinates(Common::Point *point);
//////////////////////////////////////////////////////////////////////////
// Scene debugging
//////////////////////////////////////////////////////////////////////////
void debugShowActors();
void debugShowObjects();
void debugShowPolygons();
void debugShowPolygon(uint32 index, uint32 color = 0xFF);
void debugHighlightPolygon(uint32 index);
void debugShowSceneRects();
void debugScreenScrolling();
void debugShowWalkRegion(Polygon *poly);
friend class SceneTitle;
};
} // end of namespace Asylum
#endif // ASYLUM_VIEWS_SCENE_H

View File

@@ -0,0 +1,106 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "asylum/views/scenetitle.h"
#include "asylum/resources/worldstats.h"
#include "asylum/system/graphics.h"
#include "asylum/system/screen.h"
#include "asylum/system/text.h"
#include "asylum/views/scene.h"
#include "asylum/asylum.h"
#include "asylum/respack.h"
namespace Asylum {
SceneTitle::SceneTitle(AsylumEngine *engine): _vm(engine),
_start(0), _done(false), _spinnerFrameIndex(0), _spinnerProgress(0), _spinnerFrameCount(0) {
switch (_vm->getLanguage()) {
default:
case Common::EN_ANY:
_chapterTitlesOffset = 1811;
break;
case Common::DE_DEU:
_chapterTitlesOffset = 1734;
break;
case Common::FR_FRA:
_chapterTitlesOffset = 1715;
break;
}
}
void SceneTitle::load() {
_start = _vm->getTick();
getScreen()->clear();
getScreen()->setPalette(getWorld()->sceneTitlePaletteResourceId);
getScreen()->paletteFade(0, 1, 1);
getScreen()->setGammaLevel(getWorld()->sceneTitlePaletteResourceId);
getText()->loadFont(MAKE_RESOURCE(kResourcePackSound, 18));
_spinnerProgress = 0;
_spinnerFrameIndex = 0;
_spinnerFrameCount = GraphicResource::getFrameCount(_vm, MAKE_RESOURCE(kResourcePackSound, 17));
_done = false;
update(_start);
getScreen()->stopPaletteFadeAndSet(getWorld()->sceneTitlePaletteResourceId, 5, 50);
}
void SceneTitle::update(int32 tick) {
if (_done)
return;
getScreen()->draw(getWorld()->sceneTitleGraphicResourceId);
getScreen()->draw(MAKE_RESOURCE(kResourcePackSound, 17), _spinnerFrameIndex, Common::Point((int16)(((_spinnerProgress / 590.0) * 580.0) - 290), 0), kDrawFlagNone, false);
getText()->drawCentered(Common::Point(320, 30), 24, MAKE_RESOURCE(kResourcePackText, getWorld()->chapter + _chapterTitlesOffset));
getScreen()->copyBackBufferToScreen();
// This is not from the original. It's just some arbitrary math to throttle the progress indicator.
//
// In the game, the scene loading progress indicated how far the engine had progressed in terms
// of buffering the various scene resource. Since we don't actually buffer content like the original,
// but load on demand from offset/length within a ResourcePack, the progress indicator is effectively
// useless. It's just in here as "eye candy" :P
if ((tick - _start) % 500 > 100)
_spinnerProgress += 10;
_spinnerFrameIndex++;
if (_spinnerFrameIndex > _spinnerFrameCount - 1)
_spinnerFrameIndex = 0;
if (_spinnerProgress > 590) {
_done = true;
getScreen()->paletteFade(0, 5, 80);
}
}
} // End of namespace Asylum

View File

@@ -0,0 +1,55 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ASYLUM_VIEWS_SCENETITLE_H
#define ASYLUM_VIEWS_SCENETITLE_H
#include "common/scummsys.h"
namespace Asylum {
class AsylumEngine;
class GraphicResource;
class SceneTitle {
public:
SceneTitle(AsylumEngine *engine);
~SceneTitle() {};
void load();
void update(int32 tick);
bool loadingComplete() { return _done; }
private:
AsylumEngine *_vm;
int32 _start;
bool _done;
uint32 _spinnerFrameIndex;
int32 _spinnerProgress;
uint32 _spinnerFrameCount;
uint32 _chapterTitlesOffset;
};
} // End of namespace Asylum
#endif // ASYLUM_VIEWS_SCENETITLE_H

View File

@@ -0,0 +1,319 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "engines/util.h"
#include "video/avi_decoder.h"
#include "video/smk_decoder.h"
#include "video/theora_decoder.h"
#include "asylum/views/video.h"
#include "asylum/system/config.h"
#include "asylum/system/cursor.h"
#include "asylum/system/graphics.h"
#include "asylum/system/savegame.h"
#include "asylum/system/screen.h"
#include "asylum/system/sound.h"
#include "asylum/system/text.h"
#include "asylum/asylum.h"
#include "asylum/respack.h"
#include "asylum/staticres.h"
namespace Asylum {
VideoPlayer::VideoPlayer(AsylumEngine *engine, Audio::Mixer *mixer) : _vm(engine),
_currentMovie(0), _subtitleIndex(0), _subtitleCounter(0), _previousFont(kResourceNone), _done(false) {
memset(_subtitlePalette, 0, sizeof(_subtitlePalette));
if (_vm->checkGameVersion("Steam")) {
#ifdef USE_THEORADEC
_decoder = new Video::TheoraDecoder();
Common::File paletteFile;
paletteFile.open("palette");
paletteFile.read(_subtitlePalette, PALETTE_SIZE);
paletteFile.close();
#else
error("The Steam version of the game uses Theora videos but ScummVM has been compiled without Theora support");
#endif
} else if (_vm->isAltDemo()) {
_decoder = new Video::AVIDecoder();
} else {
_decoder = new Video::SmackerDecoder();
}
}
VideoPlayer::~VideoPlayer() {
delete _decoder;
}
//////////////////////////////////////////////////////////////////////////
// Event Handler
//////////////////////////////////////////////////////////////////////////
bool VideoPlayer::handleEvent(const AsylumEvent &evt) {
switch ((int32)evt.type) {
default:
break;
case EVENT_ASYLUM_INIT:
if (!_vm->checkGameVersion("Demo"))
_previousFont = getText()->loadFont(MAKE_RESOURCE(kResourcePackShared, 57));
_subtitleCounter = 0;
_subtitleIndex = -1;
break;
case EVENT_ASYLUM_DEINIT:
getScreen()->clear();
if (!_vm->checkGameVersion("Demo"))
getText()->loadFont(_previousFont);
break;
case EVENT_ASYLUM_SUBTITLE: {
int32 newIndex = (evt.param2 == 1) ? evt.param1 : -1;
if (_subtitleIndex != newIndex) {
_subtitleIndex = newIndex;
_subtitleCounter = 2;
}
if (_subtitleCounter > 0) {
getScreen()->fillRect(0, 400, 640, 80, 0);
if (_subtitleIndex >= 0) {
char *text = getText()->get(_subtitles[_subtitleIndex].resourceId);
int16 y = (int16)(10 * (44 - getText()->draw(0, 99, kTextCalculate, Common::Point(10, 400), 20, 620, text)));
if (y <= 400)
y = 405;
getText()->draw(0, 99, kTextCenter, Common::Point(10, y), 20, 620, text);
if (_vm->checkGameVersion("Steam")) {
Graphics::Surface *st = getScreen()->getSurface()->convertTo(g_system->getScreenFormat(), _subtitlePalette);
g_system->copyRectToScreen((const byte *)st->getBasePtr(0, 400), st->pitch, 0, 400, 640, 80);
st->free();
delete st;
}
}
--_subtitleCounter;
}
return true;
}
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_KEYDOWN:
case Common::EVENT_JOYBUTTON_DOWN:
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
_done = true;
if (!_vm->checkGameVersion("Steam") && !_vm->isAltDemo())
getScreen()->clear();
// Original set a value that does not seems to be used anywhere
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
// Playing
//////////////////////////////////////////////////////////////////////////
void VideoPlayer::play(uint32 videoNumber, EventHandler *handler) {
getSaveLoad()->setMovieViewed(videoNumber);
_currentMovie = videoNumber;
// Prepare
getCursor()->hide();
getSharedData()->setFlag(kFlag1, true);
getScreen()->paletteFade(0, 25, 10);
getSound()->stopAll();
// Play movie
_vm->switchEventHandler(this);
Common::String filename;
if (_vm->checkGameVersion("Steam"))
filename = videoNumber == 0 ? "mov000_2_smk.ogv" : Common::String::format("mov%03d_smk.ogv", videoNumber);
else if (_vm->isAltDemo())
filename = Common::String::format("mov%03d.avi", videoNumber);
else
filename = Common::String::format("mov%03d.smk", videoNumber);
play(Common::Path(filename), Config.showMovieSubtitles);
// Cleanup and switch to previous event handler
getCursor()->show();
getSharedData()->setFlag(kFlag1, false);
_vm->switchEventHandler(handler);
}
void VideoPlayer::play(const Common::Path &filename, bool showSubtitles) {
if (!_decoder->loadFile(filename))
error("[Video::playVideo] Invalid video index (%d)", _currentMovie);
int16 x = (int16)Common::Rational(g_system->getWidth() - _decoder->getWidth(), 2).toInt();
int16 y = (int16)Common::Rational(g_system->getHeight() - _decoder->getHeight(), 2).toInt();
getScreen()->clear();
// TODO check flags and setup volume panning
// Load subtitles
if (showSubtitles && !_vm->checkGameVersion("Demo"))
loadSubtitles();
// Setup playing
_done = false;
uint32 index = 0;
int32 frameStart = 0;
int32 frameEnd = 0;
int32 currentSubtitle = 0;
if (_vm->checkGameVersion("Steam") || _vm->isAltDemo()) {
_decoder->setOutputPixelFormats(g_system->getSupportedFormats());
Graphics::PixelFormat decoderFormat = _decoder->getPixelFormat();
initGraphics(640, 480, &decoderFormat);
}
_decoder->start();
while (!_done && !Engine::shouldQuit() && !_decoder->endOfVideo()) {
_vm->handleEvents();
if (_decoder->needsUpdate()) {
const Graphics::Surface *frame = _decoder->decodeNextFrame();
if (!frame)
continue;
if (_vm->checkGameVersion("Steam") || _vm->isAltDemo()) {
g_system->copyRectToScreen((const byte *)frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
} else {
if (_decoder->hasDirtyPalette())
setupPalette();
getScreen()->copyToBackBuffer((const byte *)frame->getPixels(), frame->pitch, x, y, frame->w, frame->h);
}
if (showSubtitles) {
int32 currentFrame = _decoder->getCurFrame() + 1;
debugC(kDebugLevelVideo, "[Video] {%s} Playing Frame %d", filename.toString(Common::Path::kNativeSeparator).c_str(), currentFrame);
// Check for next frame
if (currentFrame > frameEnd) {
if (index < _subtitles.size()) {
frameStart = _subtitles[index].frameStart;
frameEnd = _subtitles[index].frameEnd;
currentSubtitle = index;
++index;
}
}
if (currentFrame < frameStart || currentFrame > frameEnd)
_vm->notify(EVENT_ASYLUM_SUBTITLE, 0, 0);
else
_vm->notify(EVENT_ASYLUM_SUBTITLE, currentSubtitle, 1);
}
if (!_vm->checkGameVersion("Steam") && !_vm->isAltDemo())
getScreen()->copyBackBufferToScreen();
g_system->updateScreen();
}
if (!_vm->checkGameVersion("Steam") && !_vm->isAltDemo())
g_system->delayMillis(10);
}
if (_vm->checkGameVersion("Steam") || _vm->isAltDemo())
initGraphics(640, 480);
_decoder->close();
_subtitles.clear();
}
void VideoPlayer::setupPalette() {
getScreen()->setMainPalette(_decoder->getPalette());
getScreen()->setupPalette(nullptr, 0, 0);
}
void VideoPlayer::loadSubtitles() {
char movieToken[10];
snprintf(movieToken, 10, "[MOV%03d]", _currentMovie);
Common::File subsFile;
subsFile.open("vids.cap");
uint32 fileSize = (uint32)subsFile.size();
char *buffer = new char[fileSize + 1];
subsFile.read(buffer, fileSize);
subsFile.close();
buffer[fileSize] = 0;
char *start = strstr(buffer, movieToken);
char *line = nullptr;
if (start) {
start += 20; // skip token, newline and "CAPTION = "
uint32 count = strcspn(start, "\r\n");
line = new char[count + 1];
strncpy(line, start, count);
line[count] = 0;
char *tok = strtok(line, " ");
while (tok) {
VideoSubtitle newSubtitle;
newSubtitle.frameStart = atoi(tok);
tok = strtok(nullptr, " ");
if (!tok)
error("[Video::loadSubtitles] Invalid subtitle (frame end missing)!");
newSubtitle.frameEnd = atoi(tok);
tok = strtok(nullptr, " ");
if (!tok)
error("[Video::loadSubtitles] Invalid subtitle (resource id missing)!");
int index = atoi(tok);
// Original bug: index starts from 1 instead of 0
if (_currentMovie == 36)
index--;
newSubtitle.resourceId = (ResourceId)(index + video_subtitle_resourceIds[_currentMovie]);
tok = strtok(nullptr, " ");
_subtitles.push_back(newSubtitle);
}
delete [] line;
}
delete [] buffer;
}
} // end of namespace Asylum

View File

@@ -0,0 +1,110 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ASYLUM_VIEWS_VIDEO_H
#define ASYLUM_VIEWS_VIDEO_H
#include "common/array.h"
#include "common/events.h"
#include "common/system.h"
#include "common/list.h"
#include "audio/mixer.h"
#include "graphics/surface.h"
#include "video/video_decoder.h"
#include "asylum/eventhandler.h"
#include "asylum/shared.h"
#include "asylum/system/screen.h"
namespace Asylum {
class AsylumEngine;
class GraphicResource;
class VideoText;
struct GraphicFrame;
struct VideoSubtitle {
int frameStart;
int frameEnd;
ResourceId resourceId;
};
class VideoPlayer : public EventHandler {
public:
VideoPlayer(AsylumEngine *engine, Audio::Mixer *mixer);
virtual ~VideoPlayer();
/**
* Plays a video.
*
* @param videoNumber The video number.
* @param handler The previous event handler.
*/
void play(uint32 videoNumber, EventHandler *handler);
/**
* Handle event.
*
* @param evt The event.
*
* @return true if it succeeds, false if it fails.
*/
bool handleEvent(const AsylumEvent &evt);
private:
AsylumEngine *_vm;
Video::VideoDecoder *_decoder;
Common::Array<VideoSubtitle> _subtitles;
int32 _currentMovie;
int32 _subtitleIndex;
int32 _subtitleCounter;
ResourceId _previousFont;
bool _done;
byte _subtitlePalette[PALETTE_SIZE];
/**
* Plays the given file.
*
* @param filename Filename of the file.
* @param showSubtitles true to show, false to hide the subtitles.
*/
void play(const Common::Path &filename, bool showSubtitles);
/**
* Sets up the palette.
*/
void setupPalette();
/**
* Loads the subtitles (vids.cap)
*/
void loadSubtitles();
};
} // end of namespace Asylum
#endif // ASYLUM_VIEWS_VIDEO_H