2011-02-14 09:37:27 +00:00
|
|
|
/* 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 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "tsage/scenes.h"
|
|
|
|
#include "tsage/globals.h"
|
2011-02-23 11:37:16 +00:00
|
|
|
#include "tsage/ringworld_logic.h"
|
2011-02-14 09:37:27 +00:00
|
|
|
#include "tsage/tsage.h"
|
2011-04-19 11:02:27 +00:00
|
|
|
#include "tsage/saveload.h"
|
2011-02-14 09:37:27 +00:00
|
|
|
|
|
|
|
namespace tSage {
|
|
|
|
|
2011-04-13 19:27:46 +00:00
|
|
|
SceneManager::SceneManager() {
|
2011-02-14 09:37:27 +00:00
|
|
|
_scene = NULL;
|
|
|
|
_hasPalette = false;
|
2011-04-13 19:27:46 +00:00
|
|
|
_sceneNumber = -1;
|
2011-02-14 09:37:27 +00:00
|
|
|
_nextSceneNumber = -1;
|
2011-04-09 11:27:25 +00:00
|
|
|
_previousScene = 0;
|
2011-02-27 11:52:35 +00:00
|
|
|
_fadeMode = FADEMODE_GRADUAL;
|
2011-02-14 09:37:27 +00:00
|
|
|
_scrollerRect = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
|
|
|
_saver->addListener(this);
|
2011-04-19 11:02:27 +00:00
|
|
|
_objectCount = 0;
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SceneManager::~SceneManager() {
|
|
|
|
delete _scene;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::setNewScene(int sceneNumber) {
|
2011-04-15 09:01:24 +00:00
|
|
|
warning("SetNewScene(%d)", sceneNumber);
|
2011-02-14 09:37:27 +00:00
|
|
|
_nextSceneNumber = sceneNumber;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::checkScene() {
|
|
|
|
if (_nextSceneNumber != -1) {
|
|
|
|
sceneChange();
|
|
|
|
_nextSceneNumber = -1;
|
|
|
|
}
|
|
|
|
|
2011-04-13 15:08:16 +00:00
|
|
|
Common::for_each(_globals->_sceneListeners.begin(), _globals->_sceneListeners.end(), SceneHandler::dispatchObject);
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::sceneChange() {
|
2011-05-03 10:13:53 +00:00
|
|
|
int activeScreenNumber = 0;
|
|
|
|
|
2011-03-23 08:16:09 +00:00
|
|
|
// Handle removing the scene
|
2011-05-03 10:13:53 +00:00
|
|
|
if (_scene) {
|
|
|
|
activeScreenNumber = _scene->_activeScreenNumber;
|
2011-03-23 08:16:09 +00:00
|
|
|
_scene->remove();
|
2011-05-03 10:13:53 +00:00
|
|
|
}
|
2011-03-23 08:16:09 +00:00
|
|
|
|
2011-02-14 09:37:27 +00:00
|
|
|
// Clear the scene objects
|
2011-05-04 08:47:12 +00:00
|
|
|
SynchronizedList<SceneObject *>::iterator io = _globals->_sceneObjects->begin();
|
2011-02-14 09:37:27 +00:00
|
|
|
while (io != _globals->_sceneObjects->end()) {
|
|
|
|
SceneObject *sceneObj = *io;
|
|
|
|
++io;
|
|
|
|
sceneObj->removeObject();
|
|
|
|
}
|
|
|
|
|
2011-04-05 10:58:05 +00:00
|
|
|
// Clear the secondary scene object list
|
|
|
|
io = _globals->_sceneManager._altSceneObjects.begin();
|
|
|
|
while (io != _globals->_sceneManager._altSceneObjects.end()) {
|
|
|
|
SceneObject *sceneObj = *io;
|
|
|
|
++io;
|
|
|
|
sceneObj->removeObject();
|
|
|
|
}
|
2011-02-14 09:37:27 +00:00
|
|
|
|
|
|
|
// Clear the hotspot list
|
2011-05-04 08:47:12 +00:00
|
|
|
SynchronizedList<SceneItem *>::iterator ii = _globals->_sceneItems.begin();
|
2011-02-14 09:37:27 +00:00
|
|
|
while (ii != _globals->_sceneItems.end()) {
|
|
|
|
SceneItem *sceneItem = *ii;
|
|
|
|
++ii;
|
|
|
|
sceneItem->remove();
|
|
|
|
}
|
2011-04-13 19:27:46 +00:00
|
|
|
|
2011-02-14 09:37:27 +00:00
|
|
|
// TODO: Clear _list_45BAA list
|
|
|
|
|
|
|
|
// If there is an active scene, deactivate it
|
|
|
|
if (_scene) {
|
|
|
|
_previousScene = _sceneNumber;
|
|
|
|
|
|
|
|
delete _scene;
|
|
|
|
_scene = NULL;
|
|
|
|
_sceneNumber = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the next scene to be active
|
|
|
|
_sceneNumber = _nextSceneNumber;
|
|
|
|
|
|
|
|
// TODO: Unknown check of word_45CD3 / call to saver method
|
|
|
|
|
|
|
|
// Free any regions
|
|
|
|
disposeRegions();
|
|
|
|
|
2011-04-19 11:02:27 +00:00
|
|
|
// Ensure that the same number of objects are registered now as when the scene started
|
|
|
|
if (_objectCount > 0) {
|
|
|
|
assert(_objectCount == _saver->getObjectCount());
|
|
|
|
}
|
|
|
|
_objectCount = _saver->getObjectCount();
|
2011-04-28 12:15:28 +00:00
|
|
|
_globals->_sceneHandler._delayTicks = 2;
|
2011-04-19 11:02:27 +00:00
|
|
|
|
2011-02-14 09:37:27 +00:00
|
|
|
// Instantiate and set the new scene
|
|
|
|
_scene = getNewScene();
|
2011-04-28 10:39:09 +00:00
|
|
|
|
|
|
|
if (!_saver->getMacroRestoreFlag())
|
|
|
|
_scene->postInit();
|
|
|
|
else
|
2011-05-03 10:13:53 +00:00
|
|
|
_scene->loadScene(activeScreenNumber);
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Scene *SceneManager::getNewScene() {
|
2011-05-14 08:20:56 +00:00
|
|
|
return _globals->_game->createScene(_nextSceneNumber);
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::fadeInIfNecessary() {
|
|
|
|
if (_hasPalette) {
|
|
|
|
uint32 adjustData = 0;
|
|
|
|
for (int percent = 0; percent < 100; percent += 5) {
|
2011-02-27 11:52:35 +00:00
|
|
|
if (_globals->_sceneManager._fadeMode == FADEMODE_IMMEDIATE)
|
2011-02-14 09:37:27 +00:00
|
|
|
percent = 100;
|
|
|
|
|
|
|
|
_globals->_scenePalette.fade((const byte *)&adjustData, false, percent);
|
2011-03-27 11:43:34 +00:00
|
|
|
g_system->updateScreen();
|
2011-02-14 09:37:27 +00:00
|
|
|
g_system->delayMillis(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
_globals->_scenePalette.refresh();
|
|
|
|
_hasPalette = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::changeScene(int newSceneNumber) {
|
2011-04-15 09:01:24 +00:00
|
|
|
warning("changeScene(%d)", newSceneNumber);
|
2011-02-14 09:37:27 +00:00
|
|
|
// Fade out the scene
|
|
|
|
ScenePalette scenePalette;
|
|
|
|
uint32 adjustData = 0;
|
2011-04-09 09:12:03 +00:00
|
|
|
_globals->_scenePalette.clearListeners();
|
2011-02-14 09:37:27 +00:00
|
|
|
scenePalette.getPalette();
|
|
|
|
|
|
|
|
for (int percent = 100; percent >= 0; percent -= 5) {
|
|
|
|
scenePalette.fade((byte *)&adjustData, false, percent);
|
|
|
|
g_system->delayMillis(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stop any objects that were animating
|
2011-05-04 08:47:12 +00:00
|
|
|
SynchronizedList<SceneObject *>::iterator i;
|
2011-02-14 09:37:27 +00:00
|
|
|
for (i = _globals->_sceneObjects->begin(); i != _globals->_sceneObjects->end(); ++i) {
|
|
|
|
SceneObject *sceneObj = *i;
|
|
|
|
Common::Point pt(0, 0);
|
|
|
|
sceneObj->addMover(NULL, &pt);
|
|
|
|
sceneObj->setObjectWrapper(NULL);
|
|
|
|
sceneObj->animate(ANIM_MODE_NONE, 0);
|
|
|
|
|
|
|
|
sceneObj->_flags &= !OBJFLAG_PANES;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Blank out the screen
|
|
|
|
_globals->_screenSurface.fillRect(_globals->_screenSurface.getBounds(), 0);
|
|
|
|
|
|
|
|
// Set the new scene to be loaded
|
|
|
|
setNewScene(newSceneNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::setup() {
|
|
|
|
_saver->addLoadNotifier(SceneManager::loadNotifier);
|
|
|
|
setBackSurface();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::setBackSurface() {
|
|
|
|
int size = _globals->_sceneManager._scene->_backgroundBounds.width() *
|
|
|
|
_globals->_sceneManager._scene->_backgroundBounds.height();
|
|
|
|
|
|
|
|
if (size > 96000) {
|
|
|
|
if (_globals->_sceneManager._scene->_backgroundBounds.width() <= SCREEN_WIDTH) {
|
|
|
|
// Standard size creation
|
2011-03-19 10:07:04 +00:00
|
|
|
_globals->_sceneManager._scene->_backSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT * 3 / 2);
|
2011-02-14 09:37:27 +00:00
|
|
|
_globals->_sceneManager._scrollerRect = Rect(0, 30, SCREEN_WIDTH, SCREEN_HEIGHT - 30);
|
|
|
|
} else {
|
2011-03-18 11:58:36 +00:00
|
|
|
// Wide screen needs extra space to allow for scrolling
|
|
|
|
_globals->_sceneManager._scene->_backSurface.create(SCREEN_WIDTH * 3 / 2, SCREEN_HEIGHT);
|
2011-02-14 09:37:27 +00:00
|
|
|
_globals->_sceneManager._scrollerRect = Rect(80, 0, SCREEN_WIDTH - 80, SCREEN_HEIGHT);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_globals->_sceneManager._scene->_backSurface.create(
|
|
|
|
_globals->_sceneManager._scene->_backgroundBounds.width(),
|
|
|
|
_globals->_sceneManager._scene->_backgroundBounds.height()
|
|
|
|
);
|
|
|
|
_globals->_sceneManager._scrollerRect = Rect(80, 20, SCREEN_WIDTH - 80, SCREEN_HEIGHT - 20);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::saveListener(int saveMode) {
|
|
|
|
warning("TODO: SceneManager::saveLIstener");
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::loadNotifier(bool postFlag) {
|
|
|
|
if (postFlag) {
|
|
|
|
if (_globals->_sceneManager._scene->_activeScreenNumber != -1)
|
|
|
|
_globals->_sceneManager._scene->loadSceneData(_globals->_sceneManager._scene->_activeScreenNumber);
|
|
|
|
_globals->_sceneManager._hasPalette = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SceneManager::setBgOffset(const Common::Point &pt, int loadCount) {
|
|
|
|
_sceneBgOffset = pt;
|
|
|
|
_sceneLoadCount = loadCount;
|
|
|
|
}
|
|
|
|
|
2011-05-04 08:47:12 +00:00
|
|
|
void SceneManager::listenerSynchronize(Serializer &s) {
|
2011-02-14 09:37:27 +00:00
|
|
|
s.validate("SceneManager");
|
2011-04-13 19:27:46 +00:00
|
|
|
|
2011-05-04 08:41:47 +00:00
|
|
|
_altSceneObjects.synchronize(s);
|
2011-02-14 09:37:27 +00:00
|
|
|
s.syncAsSint32LE(_sceneNumber);
|
2011-05-03 10:13:53 +00:00
|
|
|
s.syncAsUint16LE(_globals->_sceneManager._scene->_activeScreenNumber);
|
|
|
|
|
2011-02-14 09:37:27 +00:00
|
|
|
if (s.isLoading()) {
|
|
|
|
changeScene(_sceneNumber);
|
|
|
|
checkScene();
|
|
|
|
}
|
|
|
|
|
2011-05-04 08:41:47 +00:00
|
|
|
_globals->_sceneManager._scrollerRect.synchronize(s);
|
2011-02-14 09:37:27 +00:00
|
|
|
SYNC_POINTER(_globals->_scrollFollower);
|
2011-02-27 05:28:37 +00:00
|
|
|
s.syncAsSint16LE(_loadMode);
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
2011-04-13 19:27:46 +00:00
|
|
|
Scene::Scene() : _sceneBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT),
|
2011-02-14 09:37:27 +00:00
|
|
|
_backgroundBounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) {
|
|
|
|
_sceneMode = 0;
|
|
|
|
_oldSceneBounds = Rect(4000, 4000, 4100, 4100);
|
2011-04-18 10:13:30 +00:00
|
|
|
Common::set_to(&_zoomPercents[0], &_zoomPercents[256], 0);
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Scene::~Scene() {
|
|
|
|
}
|
|
|
|
|
2011-05-04 08:41:47 +00:00
|
|
|
void Scene::synchronize(Serializer &s) {
|
2011-05-04 07:52:36 +00:00
|
|
|
if (s.getVersion() >= 2)
|
2011-05-04 08:41:47 +00:00
|
|
|
StripCallback::synchronize(s);
|
2011-05-03 10:13:53 +00:00
|
|
|
|
2011-02-14 09:37:27 +00:00
|
|
|
s.syncAsSint32LE(_field12);
|
2011-04-19 11:07:37 +00:00
|
|
|
s.syncAsSint32LE(_screenNumber);
|
2011-02-14 09:37:27 +00:00
|
|
|
s.syncAsSint32LE(_activeScreenNumber);
|
|
|
|
s.syncAsSint32LE(_sceneMode);
|
2011-05-04 08:41:47 +00:00
|
|
|
_backgroundBounds.synchronize(s);
|
|
|
|
_sceneBounds.synchronize(s);
|
|
|
|
_oldSceneBounds.synchronize(s);
|
2011-04-03 07:25:07 +00:00
|
|
|
s.syncAsSint16LE(_fieldA);
|
|
|
|
s.syncAsSint16LE(_fieldE);
|
2011-02-14 09:37:27 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < 256; ++i)
|
2011-03-18 11:58:36 +00:00
|
|
|
s.syncAsUint16LE(_enabledSections[i]);
|
2011-02-14 09:37:27 +00:00
|
|
|
for (int i = 0; i < 256; ++i)
|
|
|
|
s.syncAsSint16LE(_zoomPercents[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::postInit(SceneObjectList *OwnerList) {
|
|
|
|
_action = NULL;
|
|
|
|
_field12 = 0;
|
|
|
|
_sceneMode = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::process(Event &event) {
|
|
|
|
if (_action)
|
|
|
|
_action->process(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::dispatch() {
|
|
|
|
if (_action)
|
|
|
|
_action->dispatch();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::loadScene(int sceneNum) {
|
2011-04-15 09:01:24 +00:00
|
|
|
warning("loadScene(%d)", sceneNum);
|
2011-04-19 11:07:37 +00:00
|
|
|
_screenNumber = sceneNum;
|
2011-02-14 09:37:27 +00:00
|
|
|
if (_globals->_scenePalette.loadPalette(sceneNum))
|
|
|
|
_globals->_sceneManager._hasPalette = true;
|
2011-04-13 19:27:46 +00:00
|
|
|
|
2011-02-14 09:37:27 +00:00
|
|
|
loadSceneData(sceneNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::loadSceneData(int sceneNum) {
|
2011-04-28 10:39:09 +00:00
|
|
|
_activeScreenNumber = sceneNum;
|
2011-02-14 09:37:27 +00:00
|
|
|
|
|
|
|
// Get the basic scene size
|
2011-04-25 07:06:35 +00:00
|
|
|
byte *data = _resourceManager->getResource(RES_BITMAP, sceneNum, 9999);
|
2011-02-14 09:37:27 +00:00
|
|
|
_backgroundBounds = Rect(0, 0, READ_LE_UINT16(data), READ_LE_UINT16(data + 2));
|
|
|
|
_globals->_sceneManager._scene->_sceneBounds.contain(_backgroundBounds);
|
|
|
|
DEALLOCATE(data);
|
|
|
|
|
|
|
|
// Set up a surface for storing the scene background
|
|
|
|
SceneManager::setBackSurface();
|
|
|
|
|
|
|
|
// Load the data lists for the scene
|
|
|
|
_globals->_walkRegions.load(sceneNum);
|
|
|
|
|
|
|
|
// Load the item regions of the scene
|
|
|
|
_globals->_sceneRegions.load(sceneNum);
|
|
|
|
|
|
|
|
// Load the priority regions
|
|
|
|
_priorities.load(sceneNum);
|
|
|
|
|
|
|
|
// Initialise the section enabled list
|
|
|
|
Common::set_to(&_enabledSections[0], &_enabledSections[16 * 16], 0xffff);
|
|
|
|
|
|
|
|
_globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160;
|
|
|
|
_globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100;
|
|
|
|
_globals->_paneRefreshFlag[0] = 1;
|
|
|
|
_globals->_paneRefreshFlag[1] = 1;
|
2011-02-27 05:28:37 +00:00
|
|
|
_globals->_sceneManager._loadMode = 1;
|
2011-02-14 09:37:27 +00:00
|
|
|
_globals->_sceneManager._sceneLoadCount = 0;
|
|
|
|
_globals->_sceneManager._sceneBgOffset = Common::Point(0, 0);
|
|
|
|
|
|
|
|
// Load the background for the scene
|
|
|
|
loadBackground(0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::loadBackground(int xAmount, int yAmount) {
|
|
|
|
// Adjust the scene bounds by the passed scroll amounts
|
|
|
|
_sceneBounds.translate(xAmount, yAmount);
|
|
|
|
_sceneBounds.contain(_backgroundBounds);
|
|
|
|
_sceneBounds.left &= ~3;
|
|
|
|
_sceneBounds.right &= ~3;
|
|
|
|
_globals->_sceneOffset.x &= ~3;
|
|
|
|
|
|
|
|
if ((_sceneBounds.top != _oldSceneBounds.top) || (_sceneBounds.left != _oldSceneBounds.left)) {
|
2011-02-27 05:28:37 +00:00
|
|
|
if (_globals->_sceneManager._loadMode == 0) {
|
2011-02-14 09:37:27 +00:00
|
|
|
_globals->_paneRefreshFlag[0] = 2;
|
|
|
|
_globals->_paneRefreshFlag[1] = 2;
|
2011-02-27 05:28:37 +00:00
|
|
|
_globals->_sceneManager._loadMode = 2;
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
_oldSceneBounds = _sceneBounds;
|
|
|
|
}
|
|
|
|
|
|
|
|
_globals->_sceneOffset.x = (_sceneBounds.left / 160) * 160;
|
|
|
|
_globals->_sceneOffset.y = (_sceneBounds.top / 100) * 100;
|
|
|
|
|
|
|
|
if ((_backgroundBounds.width() / 160) == 3)
|
|
|
|
_globals->_sceneOffset.x = 0;
|
|
|
|
if ((_backgroundBounds.height() / 100) == 3)
|
|
|
|
_globals->_sceneOffset.y = 0;
|
|
|
|
|
2011-04-13 19:27:46 +00:00
|
|
|
if ((_globals->_sceneOffset.x != _globals->_prevSceneOffset.x) ||
|
2011-03-18 11:58:36 +00:00
|
|
|
(_globals->_sceneOffset.y != _globals->_prevSceneOffset.y)) {
|
2011-02-14 09:37:27 +00:00
|
|
|
// Change has happend, so refresh background
|
2011-03-18 11:58:36 +00:00
|
|
|
_globals->_prevSceneOffset = _globals->_sceneOffset;
|
2011-02-14 09:37:27 +00:00
|
|
|
refreshBackground(xAmount, yAmount);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::refreshBackground(int xAmount, int yAmount) {
|
|
|
|
if (_globals->_sceneManager._scene->_activeScreenNumber == -1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Set the quadrant ranges
|
|
|
|
int xHalfCount = MIN(_backSurface.getBounds().width() / 160, _backgroundBounds.width() / 160);
|
|
|
|
int yHalfCount = MIN(_backSurface.getBounds().height() / 100, _backgroundBounds.height() / 100);
|
|
|
|
int xHalfOffset = (_backgroundBounds.width() / 160) == 3 ? 0 : _sceneBounds.left / 160;
|
|
|
|
int yHalfOffset = (_backgroundBounds.height() / 100) == 3 ? 0 : _sceneBounds.top / 100;
|
|
|
|
|
|
|
|
// Set the limits and increment amounts
|
2011-03-17 11:57:24 +00:00
|
|
|
int xInc = (xAmount < 0) ? -1 : 1;
|
2011-03-18 11:58:36 +00:00
|
|
|
int xSectionStart = (xAmount < 0) ? 15 : 0;
|
2011-02-14 09:37:27 +00:00
|
|
|
int xSectionEnd = (xAmount < 0) ? -1 : 16;
|
2011-03-17 11:57:24 +00:00
|
|
|
int yInc = (yAmount < 0) ? -1 : 1;
|
2011-03-18 11:58:36 +00:00
|
|
|
int ySectionStart = (yAmount < 0) ? 15 : 0;
|
2011-02-14 09:37:27 +00:00
|
|
|
int ySectionEnd = (yAmount < 0) ? -1 : 16;
|
|
|
|
bool changedFlag = false;
|
|
|
|
|
2011-03-18 11:58:36 +00:00
|
|
|
for (int yp = ySectionStart; yp != ySectionEnd; yp += yInc) {
|
|
|
|
for (int xp = xSectionStart; xp != xSectionEnd; xp += xInc) {
|
2011-02-14 09:37:27 +00:00
|
|
|
if ((yp < yHalfOffset) || (yp >= (yHalfOffset + yHalfCount)) ||
|
|
|
|
(xp < xHalfOffset) || (xp >= (xHalfOffset + xHalfCount))) {
|
|
|
|
// Flag section as enabled
|
|
|
|
_enabledSections[xp * 16 + yp] = 0xffff;
|
|
|
|
} else {
|
2011-03-18 11:58:36 +00:00
|
|
|
// Check if the section is already loaded
|
2011-03-19 03:20:15 +00:00
|
|
|
if ((_enabledSections[xp * 16 + yp] == 0xffff) || ((xAmount == 0) && (yAmount == 0))) {
|
|
|
|
// Chunk isn't loaded, so load it in
|
2011-02-14 09:37:27 +00:00
|
|
|
Graphics::Surface s = _backSurface.lockSurface();
|
|
|
|
GfxSurface::loadScreenSection(s, xp - xHalfOffset, yp - yHalfOffset, xp, yp);
|
|
|
|
_backSurface.unlockSurface();
|
|
|
|
changedFlag = true;
|
2011-03-19 03:20:15 +00:00
|
|
|
} else {
|
|
|
|
int yv = (_enabledSections[xp * 16 + yp] == ((xp - xHalfOffset) << 4)) ? 0 : 1;
|
|
|
|
if (yv | (yp - yHalfOffset)) {
|
2011-03-18 11:58:36 +00:00
|
|
|
// Copy an existing 160x100 screen section previously loaded
|
2011-03-19 03:20:15 +00:00
|
|
|
int xSectionDest = xp - xHalfOffset;
|
|
|
|
int ySectionDest = yp - yHalfOffset;
|
|
|
|
int xSectionSrc = _enabledSections[xp * 16 + yp] >> 4;
|
|
|
|
int ySectionSrc = _enabledSections[xp * 16 + yp] & 0xf;
|
2011-04-13 19:27:46 +00:00
|
|
|
|
|
|
|
Rect srcBounds(xSectionSrc * 160, ySectionSrc * 100,
|
2011-03-18 11:58:36 +00:00
|
|
|
(xSectionSrc + 1) * 160, (ySectionSrc + 1) * 100);
|
2011-04-13 19:27:46 +00:00
|
|
|
Rect destBounds(xSectionDest * 160, ySectionDest * 100,
|
2011-03-18 11:58:36 +00:00
|
|
|
(xSectionDest + 1) * 160, (ySectionDest + 1) * 100);
|
|
|
|
|
2011-04-13 19:27:46 +00:00
|
|
|
_backSurface.copyFrom(_backSurface, srcBounds, destBounds);
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
2011-03-19 03:20:15 +00:00
|
|
|
}
|
2011-02-14 09:37:27 +00:00
|
|
|
|
2011-04-13 19:27:46 +00:00
|
|
|
_enabledSections[xp * 16 + yp] =
|
2011-03-19 03:20:15 +00:00
|
|
|
((xp - xHalfOffset) << 4) | (yp - yHalfOffset);
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changedFlag) {
|
2011-04-05 10:58:05 +00:00
|
|
|
drawAltObjects();
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-05 10:58:05 +00:00
|
|
|
void Scene::drawAltObjects() {
|
|
|
|
Common::Array<SceneObject *> objList;
|
|
|
|
|
|
|
|
// Initial loop to set the priority for entries in the list
|
2011-05-04 08:47:12 +00:00
|
|
|
for (SynchronizedList<SceneObject *>::iterator i = _globals->_sceneManager._altSceneObjects.begin();
|
2011-04-05 10:58:05 +00:00
|
|
|
i != _globals->_sceneManager._altSceneObjects.end(); ++i) {
|
|
|
|
SceneObject *obj = *i;
|
|
|
|
objList.push_back(obj);
|
|
|
|
|
|
|
|
// Handle updating object priority
|
|
|
|
if (!(obj->_flags & OBJFLAG_FIXED_PRIORITY)) {
|
2011-04-13 19:27:46 +00:00
|
|
|
obj->_priority = MIN((int)obj->_position.y - 1,
|
2011-04-05 10:58:05 +00:00
|
|
|
(int)_globals->_sceneManager._scene->_backgroundBounds.bottom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort the list by priority
|
|
|
|
_globals->_sceneManager._altSceneObjects.sortList(objList);
|
|
|
|
|
|
|
|
// Drawing loop
|
|
|
|
for (uint objIndex = 0; objIndex < objList.size(); ++objIndex) {
|
|
|
|
SceneObject *obj = objList[objIndex];
|
|
|
|
|
|
|
|
obj->reposition();
|
|
|
|
obj->draw();
|
2011-04-13 19:27:46 +00:00
|
|
|
}
|
2011-02-14 09:37:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Scene::setZoomPercents(int yStart, int minPercent, int yEnd, int maxPercent) {
|
|
|
|
int var_6 = 0;
|
|
|
|
int v = 0;
|
|
|
|
while (v < yStart)
|
2011-02-26 13:28:38 +00:00
|
|
|
_zoomPercents[v++] = minPercent;
|
2011-02-14 09:37:27 +00:00
|
|
|
|
|
|
|
int diff1 = ABS(maxPercent - minPercent);
|
|
|
|
int diff2 = ABS(yEnd - yStart);
|
|
|
|
int var_8 = MAX(diff1, diff2);
|
|
|
|
|
|
|
|
while (var_8-- != 0) {
|
|
|
|
_zoomPercents[v] = minPercent;
|
|
|
|
if (diff2 <= diff1) {
|
|
|
|
++minPercent;
|
|
|
|
var_6 += diff2;
|
|
|
|
if (var_6 >= diff1) {
|
|
|
|
var_6 -= diff1;
|
|
|
|
++v;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
++v;
|
|
|
|
var_6 += diff1;
|
|
|
|
if (var_6 >= diff2) {
|
|
|
|
var_6 -= diff2;
|
|
|
|
++minPercent;
|
|
|
|
}
|
|
|
|
}
|
2011-04-13 19:27:46 +00:00
|
|
|
}
|
2011-02-14 09:37:27 +00:00
|
|
|
|
|
|
|
while (yEnd < 256)
|
|
|
|
_zoomPercents[yEnd++] = minPercent;
|
|
|
|
}
|
|
|
|
|
2011-05-14 08:20:56 +00:00
|
|
|
/*--------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
void Game::execute() {
|
|
|
|
// Main game loop
|
|
|
|
bool activeFlag = false;
|
|
|
|
do {
|
|
|
|
// Process all currently atcive game handlers
|
|
|
|
activeFlag = false;
|
|
|
|
for (SynchronizedList<GameHandler *>::iterator i = _handlers.begin(); i != _handlers.end(); ++i) {
|
|
|
|
GameHandler *gh = *i;
|
|
|
|
if (gh->_lockCtr.getCtr() == 0) {
|
|
|
|
gh->execute();
|
|
|
|
activeFlag = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (activeFlag && !_vm->getEventManager()->shouldQuit());
|
|
|
|
}
|
|
|
|
|
2011-02-14 09:37:27 +00:00
|
|
|
} // End of namespace tSage
|