mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
MADS: Refactor camera code
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
/* 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 "mads/mads.h"
|
||||
#include "mads/camera.h"
|
||||
|
||||
namespace MADS {
|
||||
|
||||
Camera::Camera(MADSEngine *vm) : _vm(vm) {
|
||||
_panAllowedFl = false;
|
||||
_activeFl = false;
|
||||
_currentFrameFl = false;
|
||||
_manualFl = false;
|
||||
_speed = -1;
|
||||
_rate = -1;
|
||||
_target = -1;
|
||||
_distOffCenter = -1;
|
||||
_startTolerance = -1;
|
||||
_endTolerance = -1;
|
||||
_direction = -1;
|
||||
_timer = 0;
|
||||
}
|
||||
|
||||
void Camera::setDefaultPanX() {
|
||||
_activeFl = false;
|
||||
Scene &scene = _vm->_game->_scene;
|
||||
_panAllowedFl = (scene._sceneInfo->_width > MADS_SCREEN_WIDTH);
|
||||
|
||||
if (_panAllowedFl) {
|
||||
_manualFl = false;
|
||||
_rate = 4;
|
||||
_speed = 4;
|
||||
_target = 0;
|
||||
_distOffCenter = 80;
|
||||
_startTolerance = 80;
|
||||
_endTolerance = 4;
|
||||
_timer = scene._frameStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::setDefaultPanY() {
|
||||
_activeFl = false;
|
||||
Scene &scene = _vm->_game->_scene;
|
||||
_panAllowedFl = (scene._sceneInfo->_height > MADS_SCENE_HEIGHT);
|
||||
|
||||
if (_panAllowedFl) {
|
||||
_manualFl = true;
|
||||
_rate = 4;
|
||||
_speed = 2;
|
||||
_target = 0;
|
||||
_distOffCenter = 80;
|
||||
_startTolerance = 60;
|
||||
_endTolerance = 4;
|
||||
_timer = scene._frameStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
void Camera::camPanTo(int target) {
|
||||
if (_panAllowedFl) {
|
||||
_activeFl = true;
|
||||
_manualFl = true;
|
||||
_target = target;
|
||||
_timer = _vm->_game->_scene._frameStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
bool Camera::camPan(int16 *picture_view, int16 *player_loc, int display_size, int picture_size) {
|
||||
bool panningFl = false;
|
||||
if (_panAllowedFl) {
|
||||
Scene &scene = _vm->_game->_scene;
|
||||
Player &player = _vm->_game->_player;
|
||||
|
||||
_currentFrameFl = false;
|
||||
|
||||
uint32 timer;
|
||||
if ((abs((int32) (_timer - player._priorTimer)) < _rate) && (player._ticksAmount == _rate))
|
||||
timer = player._priorTimer;
|
||||
else
|
||||
timer = _timer;
|
||||
|
||||
if (_activeFl && (scene._frameStartTime < timer))
|
||||
return (panningFl);
|
||||
|
||||
_timer = scene._frameStartTime + _rate;
|
||||
|
||||
if (_manualFl) {
|
||||
if (_activeFl) {
|
||||
int diff = _target - *picture_view;
|
||||
int direction = 0;
|
||||
if (diff < 0)
|
||||
direction = -1;
|
||||
else if (diff > 0)
|
||||
direction = 1;
|
||||
|
||||
int magnitude = MIN(abs(diff), _speed);
|
||||
|
||||
if (magnitude == 0)
|
||||
_activeFl = false;
|
||||
else {
|
||||
int panAmount;
|
||||
if (direction < 0)
|
||||
panAmount = -magnitude;
|
||||
else
|
||||
panAmount = magnitude;
|
||||
|
||||
*picture_view += panAmount;
|
||||
|
||||
panningFl = true;
|
||||
_currentFrameFl = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!_activeFl) {
|
||||
int lowEdge = *picture_view + _startTolerance;
|
||||
int highEdge = *picture_view - _startTolerance + display_size - 1;
|
||||
|
||||
if ((*player_loc < lowEdge) && (picture_view > 0)) {
|
||||
_activeFl = true;
|
||||
_direction = -1;
|
||||
}
|
||||
|
||||
if ((*player_loc > highEdge) && (*picture_view < (picture_size - display_size))) {
|
||||
_activeFl = true;
|
||||
_direction = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int newTarget = *player_loc - (display_size >> 1);
|
||||
|
||||
if (_direction < 0)
|
||||
newTarget -= _distOffCenter;
|
||||
else
|
||||
newTarget += _distOffCenter;
|
||||
|
||||
newTarget = MAX(0, newTarget);
|
||||
newTarget = MIN(newTarget, (picture_size - display_size));
|
||||
|
||||
_target = newTarget;
|
||||
|
||||
int diff = newTarget - *picture_view;
|
||||
int magnitude = abs(diff);
|
||||
|
||||
int direction = 0;
|
||||
if (diff < 0)
|
||||
direction = -1;
|
||||
else if (diff > 0)
|
||||
direction = 1;
|
||||
|
||||
if (_activeFl && (magnitude <= _endTolerance))
|
||||
_activeFl = false;
|
||||
|
||||
if (_activeFl) {
|
||||
magnitude = MIN(magnitude, _speed);
|
||||
|
||||
int panAmount;
|
||||
if (direction < 0)
|
||||
panAmount = -magnitude;
|
||||
else
|
||||
panAmount = magnitude;
|
||||
|
||||
if (panAmount) {
|
||||
*picture_view += panAmount;
|
||||
panningFl = true;
|
||||
_currentFrameFl = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (panningFl);
|
||||
}
|
||||
|
||||
} // End of namespace MADS
|
||||
@@ -0,0 +1,63 @@
|
||||
/* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MADS_CAMERA_H
|
||||
#define MADS_CAMERA_H
|
||||
|
||||
#include "mads/scene.h"
|
||||
#include "mads/player.h"
|
||||
#include "mads/camera.h"
|
||||
|
||||
namespace MADS {
|
||||
|
||||
class MADSEngine;
|
||||
|
||||
class Camera {
|
||||
private:
|
||||
MADSEngine *_vm;
|
||||
|
||||
public:
|
||||
bool _panAllowedFl;
|
||||
bool _activeFl;
|
||||
bool _currentFrameFl;
|
||||
bool _manualFl;
|
||||
|
||||
int _speed;
|
||||
int _rate;
|
||||
int _target;
|
||||
int _distOffCenter;
|
||||
int _startTolerance;
|
||||
int _endTolerance;
|
||||
int _direction;
|
||||
uint32 _timer;
|
||||
|
||||
Camera(MADSEngine *vm);
|
||||
|
||||
void camPanTo(int target);
|
||||
bool camPan(int16 *picture_view, int16 *player_loc, int display_size, int picture_size);
|
||||
void setDefaultPanX();
|
||||
void setDefaultPanY();
|
||||
};
|
||||
|
||||
} // End of namespace MADS
|
||||
|
||||
#endif /* MADS_CAMERA_H */
|
||||
+5
-175
@@ -57,8 +57,7 @@ Game *Game::init(MADSEngine *vm) {
|
||||
}
|
||||
|
||||
Game::Game(MADSEngine *vm)
|
||||
: _vm(vm), _surface(nullptr), _objects(vm), _scene(vm),
|
||||
_screenObjects(vm), _player(vm) {
|
||||
: _vm(vm), _surface(nullptr), _objects(vm), _scene(vm), _screenObjects(vm), _player(vm), _camX(vm), _camY(vm) {
|
||||
_sectionNumber = 1;
|
||||
_priorSectionNumber = 0;
|
||||
_loadGameSlot = -1;
|
||||
@@ -92,32 +91,6 @@ Game::Game(MADSEngine *vm)
|
||||
|
||||
// Load the quotes
|
||||
loadQuotes();
|
||||
|
||||
_camX._panAllowedFl = false;
|
||||
_camX._activeFl = false;
|
||||
_camX._currentFrameFl = false;
|
||||
_camX._manualFl = false;
|
||||
_camX._speed = -1;
|
||||
_camX._rate = -1;
|
||||
_camX._target = -1;
|
||||
_camX._distOffCenter = -1;
|
||||
_camX._startTolerance = -1;
|
||||
_camX._endTolerance = -1;
|
||||
_camX._direction = -1;
|
||||
_camX._timer = 0;
|
||||
|
||||
_camY._panAllowedFl = false;
|
||||
_camY._activeFl = false;
|
||||
_camY._currentFrameFl = false;
|
||||
_camY._manualFl = false;
|
||||
_camY._speed = -1;
|
||||
_camY._rate = -1;
|
||||
_camY._target = -1;
|
||||
_camY._distOffCenter = -1;
|
||||
_camY._startTolerance = -1;
|
||||
_camY._endTolerance = -1;
|
||||
_camY._direction = -1;
|
||||
_camY._timer = 0;
|
||||
}
|
||||
|
||||
Game::~Game() {
|
||||
@@ -670,46 +643,9 @@ void Game::syncTimers(SyncType slaveType, int slaveId, SyncType masterType, int
|
||||
}
|
||||
}
|
||||
|
||||
void Game::camPanTo(Camera *camera, int target) {
|
||||
if (!camera)
|
||||
return;
|
||||
|
||||
if (camera->_panAllowedFl) {
|
||||
camera->_activeFl = true;
|
||||
camera->_manualFl = true;
|
||||
camera->_target = target;
|
||||
camera->_timer = _scene._frameStartTime;
|
||||
}
|
||||
}
|
||||
|
||||
void Game::camInitDefault() {
|
||||
_camX._activeFl = false;
|
||||
_camY._activeFl = false;
|
||||
|
||||
_camX._panAllowedFl = (_scene._sceneInfo->_width > MADS_SCREEN_WIDTH);
|
||||
_camY._panAllowedFl = (_scene._sceneInfo->_height > MADS_SCENE_HEIGHT);
|
||||
|
||||
if (_camX._panAllowedFl) {
|
||||
_camX._manualFl = false;
|
||||
_camX._rate = 4;
|
||||
_camX._speed = 4;
|
||||
_camX._target = 0;
|
||||
_camX._distOffCenter = 80;
|
||||
_camX._startTolerance = 80;
|
||||
_camX._endTolerance = 4;
|
||||
_camX._timer = _scene._frameStartTime;
|
||||
}
|
||||
|
||||
if (_camY._panAllowedFl) {
|
||||
_camY._manualFl = true;
|
||||
_camY._rate = 4;
|
||||
_camY._speed = 2;
|
||||
_camY._target = 0;
|
||||
_camY._distOffCenter = 80;
|
||||
_camY._startTolerance = 60;
|
||||
_camY._endTolerance = 4;
|
||||
_camY._timer = _scene._frameStartTime;
|
||||
}
|
||||
_camX.setDefaultPanX();
|
||||
_camY.setDefaultPanY();
|
||||
}
|
||||
|
||||
void Game::camSetSpeed() {
|
||||
@@ -732,8 +668,8 @@ void Game::camSetSpeed() {
|
||||
}
|
||||
|
||||
void Game::camUpdate() {
|
||||
bool any_pan = camPan(&_camX, &_scene._posAdjust.x, &_player._playerPos.x, 320, _scene._sceneInfo->_width);
|
||||
any_pan |= camPan(&_camY, &_scene._posAdjust.y, &_player._playerPos.y, 156, _scene._sceneInfo->_height);
|
||||
bool any_pan = _camX.camPan(&_scene._posAdjust.x, &_player._playerPos.x, 320, _scene._sceneInfo->_width);
|
||||
any_pan |= _camY.camPan(&_scene._posAdjust.y, &_player._playerPos.y, 156, _scene._sceneInfo->_height);
|
||||
|
||||
if (any_pan) {
|
||||
_scene.setCamera(_scene._posAdjust);
|
||||
@@ -741,110 +677,4 @@ void Game::camUpdate() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Game::camPan(Camera *camera, int16 *picture_view, int16 *player_loc, int display_size, int picture_size) {
|
||||
if (!camera)
|
||||
return false;
|
||||
|
||||
bool panningFl = false;
|
||||
if (camera->_panAllowedFl) {
|
||||
camera->_currentFrameFl = false;
|
||||
|
||||
uint32 timer;
|
||||
if ((abs((int32) (camera->_timer - _player._priorTimer)) < camera->_rate) && (_player._ticksAmount == camera->_rate))
|
||||
timer = _player._priorTimer;
|
||||
else
|
||||
timer = camera->_timer;
|
||||
|
||||
if (camera->_activeFl && (_scene._frameStartTime < timer))
|
||||
return (panningFl);
|
||||
|
||||
camera->_timer = _scene._frameStartTime + camera->_rate;
|
||||
|
||||
if (camera->_manualFl) {
|
||||
if (camera->_activeFl) {
|
||||
int diff = camera->_target - *picture_view;
|
||||
int direction = 0;
|
||||
if (diff < 0)
|
||||
direction = -1;
|
||||
else if (diff > 0)
|
||||
direction = 1;
|
||||
|
||||
int magnitude = MIN(abs(diff), camera->_speed);
|
||||
|
||||
if (magnitude == 0)
|
||||
camera->_activeFl = false;
|
||||
else {
|
||||
int panAmount;
|
||||
if (direction < 0)
|
||||
panAmount = -magnitude;
|
||||
else
|
||||
panAmount = magnitude;
|
||||
|
||||
*picture_view += panAmount;
|
||||
|
||||
panningFl = true;
|
||||
camera->_currentFrameFl = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!camera->_activeFl) {
|
||||
int lowEdge = *picture_view + camera->_startTolerance;
|
||||
int highEdge = *picture_view - camera->_startTolerance + display_size - 1;
|
||||
|
||||
if ((*player_loc < lowEdge) && (picture_view > 0)) {
|
||||
camera->_activeFl = true;
|
||||
camera->_direction = -1;
|
||||
}
|
||||
|
||||
if ((*player_loc > highEdge) && (*picture_view < (picture_size - display_size))) {
|
||||
camera->_activeFl = true;
|
||||
camera->_direction = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int newTarget = *player_loc - (display_size >> 1);
|
||||
|
||||
if (camera->_direction < 0)
|
||||
newTarget -= camera->_distOffCenter;
|
||||
else
|
||||
newTarget += camera->_distOffCenter;
|
||||
|
||||
newTarget = MAX(0, newTarget);
|
||||
newTarget = MIN(newTarget, (picture_size - display_size));
|
||||
|
||||
camera->_target = newTarget;
|
||||
|
||||
int diff = newTarget - *picture_view;
|
||||
int magnitude = abs(diff);
|
||||
|
||||
int direction = 0;
|
||||
if (diff < 0)
|
||||
direction = -1;
|
||||
else if (diff > 0)
|
||||
direction = 1;
|
||||
|
||||
if (camera->_activeFl && (magnitude <= camera->_endTolerance))
|
||||
camera->_activeFl = false;
|
||||
|
||||
if (camera->_activeFl) {
|
||||
magnitude = MIN(magnitude, camera->_speed);
|
||||
|
||||
int panAmount;
|
||||
if (direction < 0)
|
||||
panAmount = -magnitude;
|
||||
else
|
||||
panAmount = magnitude;
|
||||
|
||||
if (panAmount) {
|
||||
*picture_view += panAmount;
|
||||
panningFl = true;
|
||||
camera->_currentFrameFl = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (panningFl);
|
||||
}
|
||||
|
||||
} // End of namespace MADS
|
||||
|
||||
+2
-20
@@ -34,6 +34,7 @@
|
||||
#include "mads/inventory.h"
|
||||
#include "mads/player.h"
|
||||
#include "mads/screen.h"
|
||||
#include "mads/camera.h"
|
||||
|
||||
namespace MADS {
|
||||
|
||||
@@ -148,6 +149,7 @@ public:
|
||||
int _widepipeCtr;
|
||||
int _loadGameSlot;
|
||||
int _panningSpeed;
|
||||
Camera _camX, _camY;
|
||||
|
||||
public:
|
||||
virtual ~Game();
|
||||
@@ -244,29 +246,9 @@ public:
|
||||
|
||||
void syncTimers(SyncType slaveType, int slaveId, SyncType masterType, int masterId);
|
||||
|
||||
typedef struct {
|
||||
bool _panAllowedFl;
|
||||
bool _activeFl;
|
||||
bool _currentFrameFl;
|
||||
bool _manualFl;
|
||||
|
||||
int _speed;
|
||||
int _rate;
|
||||
int _target;
|
||||
int _distOffCenter;
|
||||
int _startTolerance;
|
||||
int _endTolerance;
|
||||
int _direction;
|
||||
uint32 _timer;
|
||||
} Camera;
|
||||
Camera _camX, _camY;
|
||||
|
||||
void camPanTo(Camera *camera, int target);
|
||||
void camInitDefault();
|
||||
void camSetSpeed();
|
||||
void camUpdate();
|
||||
bool camPan(Camera *camera, int16 *picture_view, int16 *player_loc, int display_size, int picture_size);
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace MADS
|
||||
|
||||
@@ -31,6 +31,7 @@ MODULE_OBJS := \
|
||||
animation.o \
|
||||
assets.o \
|
||||
audio.o \
|
||||
camera.o \
|
||||
compression.o \
|
||||
conversations.o \
|
||||
debugger.o \
|
||||
|
||||
@@ -5708,22 +5708,22 @@ void Scene109::enter() {
|
||||
void Scene109::step() {
|
||||
if (_anim0ActvFl) {
|
||||
if (_scene->_animation[_globals._animationIndexes[0]]->getCurrentFrame() == 80)
|
||||
_game.camPanTo(&_game._camY, 156);
|
||||
_game._camY.camPanTo(156);
|
||||
}
|
||||
|
||||
if (_anim1ActvFl) {
|
||||
if (_scene->_animation[_globals._animationIndexes[1]]->getCurrentFrame() == 80)
|
||||
_game.camPanTo(&_game._camY, 0);
|
||||
_game._camY.camPanTo(0);
|
||||
}
|
||||
|
||||
if (_anim2ActvFl) {
|
||||
if (_scene->_animation[_globals._animationIndexes[2]]->getCurrentFrame() == 7)
|
||||
_game.camPanTo(&_game._camY, 312);
|
||||
_game._camY.camPanTo(312);
|
||||
}
|
||||
|
||||
if (_anim3ActvFl) {
|
||||
if (_scene->_animation[_globals._animationIndexes[3]]->getCurrentFrame() == 14)
|
||||
_game.camPanTo(&_game._camY, 156);
|
||||
_game._camY.camPanTo(156);
|
||||
}
|
||||
|
||||
switch (_game._trigger) {
|
||||
|
||||
Reference in New Issue
Block a user