mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 06:08:35 +00:00
added & renamed some constants; fixed & added some doxygen comments; cleaned up the dirty screen code a bit (this should also fix a bug in V1/V2 games where part of the screen was not redrawn properly)
svn-id: r12118
This commit is contained in:
parent
d49082065a
commit
34db2e793a
@ -29,7 +29,7 @@ namespace Scumm {
|
||||
|
||||
void ScummEngine::setCameraAtEx(int at) {
|
||||
if (!(_features & GF_NEW_CAMERA)) {
|
||||
camera._mode = CM_NORMAL;
|
||||
camera._mode = kNormalCameraMode;
|
||||
camera._cur.x = at;
|
||||
setCameraAt(at, 0);
|
||||
camera._movingToActor = false;
|
||||
@ -37,7 +37,7 @@ void ScummEngine::setCameraAtEx(int at) {
|
||||
}
|
||||
|
||||
void ScummEngine::setCameraAt(int pos_x, int pos_y) {
|
||||
if (camera._mode != CM_FOLLOW_ACTOR || abs(pos_x - camera._cur.x) > (_screenWidth / 2)) {
|
||||
if (camera._mode != kFollowActorCameraMode || abs(pos_x - camera._cur.x) > (_screenWidth / 2)) {
|
||||
camera._cur.x = pos_x;
|
||||
}
|
||||
camera._dest.x = pos_x;
|
||||
@ -89,12 +89,12 @@ void ScummEngine::setCameraFollows(Actor *a) {
|
||||
|
||||
int t, i;
|
||||
|
||||
camera._mode = CM_FOLLOW_ACTOR;
|
||||
camera._mode = kFollowActorCameraMode;
|
||||
camera._follows = a->number;
|
||||
|
||||
if (!a->isInCurrentRoom()) {
|
||||
startScene(a->getRoom(), 0, 0);
|
||||
camera._mode = CM_FOLLOW_ACTOR;
|
||||
camera._mode = kFollowActorCameraMode;
|
||||
camera._cur.x = a->_pos.x;
|
||||
setCameraAt(camera._cur.x, 0);
|
||||
}
|
||||
@ -174,7 +174,7 @@ void ScummEngine::moveCamera() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (camera._mode == CM_FOLLOW_ACTOR) {
|
||||
if (camera._mode == kFollowActorCameraMode) {
|
||||
a = derefActor(camera._follows, "moveCamera");
|
||||
|
||||
actorx = a->_pos.x;
|
||||
@ -353,7 +353,7 @@ void ScummEngine::cameraMoved() {
|
||||
|
||||
void ScummEngine::panCameraTo(int x, int y) {
|
||||
camera._dest.x = x;
|
||||
camera._mode = CM_PANNING;
|
||||
camera._mode = kPanningCameraMode;
|
||||
camera._movingToActor = false;
|
||||
}
|
||||
|
||||
@ -373,7 +373,7 @@ void ScummEngine::actorFollowCamera(int act) {
|
||||
/*
|
||||
// MI1 compatibilty
|
||||
if (act == 0) {
|
||||
camera._mode = CM_NORMAL;
|
||||
camera._mode = kNormalCameraMode;
|
||||
camera._follows = 0;
|
||||
camera._movingToActor = false;
|
||||
return;
|
||||
|
102
scumm/gfx.cpp
102
scumm/gfx.cpp
@ -250,9 +250,9 @@ void ScummEngine::initScreens(int a, int b, int w, int h) {
|
||||
initVirtScreen(3, 0, 80, _screenWidth, 13, false, false);
|
||||
}
|
||||
}
|
||||
initVirtScreen(0, 0, b, _screenWidth, h - b, true, true);
|
||||
initVirtScreen(1, 0, 0, _screenWidth, b, false, false);
|
||||
initVirtScreen(2, 0, h, _screenWidth, _screenHeight - h, false, false);
|
||||
initVirtScreen(kMainVirtScreen, 0, b, _screenWidth, h - b, true, true);
|
||||
initVirtScreen(kTextVirtScreen, 0, 0, _screenWidth, b, false, false);
|
||||
initVirtScreen(kVerbVirtScreen, 0, h, _screenWidth, _screenHeight - h, false, false);
|
||||
|
||||
_screenB = b;
|
||||
_screenH = h;
|
||||
@ -371,32 +371,34 @@ void ScummEngine::updateDirtyRect(int virt, int left, int right, int top, int bo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all dirty screen areas. This method blits all of the internal engine
|
||||
* graphics to the actual display, as needed. In addition, the 'shaking'
|
||||
* code in the backend is controlled from here.
|
||||
*/
|
||||
void ScummEngine::drawDirtyScreenParts() {
|
||||
int i;
|
||||
VirtScreen *vs;
|
||||
byte *src;
|
||||
|
||||
updateDirtyScreen(2);
|
||||
// Update verbs
|
||||
updateDirtyScreen(kVerbVirtScreen);
|
||||
|
||||
// In V1-V3, update the conversation area (at the top of the screen)
|
||||
if (_version <= 3)
|
||||
updateDirtyScreen(1);
|
||||
updateDirtyScreen(kTextVirtScreen);
|
||||
|
||||
if (camera._last.x == camera._cur.x && (camera._last.y == camera._cur.y || !(_features & GF_NEW_CAMERA))) {
|
||||
updateDirtyScreen(0);
|
||||
// Update game area ("stage")
|
||||
if (camera._last.x != camera._cur.x || (_features & GF_NEW_CAMERA && (camera._cur.y != camera._last.y))) {
|
||||
// Camera moved: redraw everything
|
||||
// Small side note: most of our GFX code relies on this identity:
|
||||
// gdi._numStrips * 8 == _screenWidth == vs->width
|
||||
VirtScreen *vs = &virtscr[kMainVirtScreen];
|
||||
gdi.drawStripToScreen(vs, 0, vs->width, 0, vs->height);
|
||||
vs->setDirtyRange(vs->height, 0);
|
||||
} else {
|
||||
vs = &virtscr[0];
|
||||
|
||||
src = vs->screenPtr + vs->xstart + _screenTop * _screenWidth;
|
||||
_system->copy_rect(src, _screenWidth, 0, vs->topline, _screenWidth, vs->height - _screenTop);
|
||||
|
||||
for (i = 0; i < gdi._numStrips; i++) {
|
||||
vs->tdirty[i] = vs->height;
|
||||
vs->bdirty[i] = 0;
|
||||
}
|
||||
updateDirtyScreen(kMainVirtScreen);
|
||||
}
|
||||
|
||||
/* Handle shaking */
|
||||
// Handle shaking
|
||||
if (_shakeEnabled) {
|
||||
_shakeFrame = (_shakeFrame + 1) & (NUM_SHAKE_POSITIONS - 1);
|
||||
_shakeFrame = (_shakeFrame + 1) % NUM_SHAKE_POSITIONS;
|
||||
_system->set_shake_pos(shake_positions[_shakeFrame]);
|
||||
} else if (!_shakeEnabled &&_shakeFrame != 0) {
|
||||
_shakeFrame = 0;
|
||||
@ -409,44 +411,38 @@ void ScummEngine::updateDirtyScreen(int slot) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Blit the data from the given VirtScreen to the display. If the camera moved,
|
||||
* Blit the dirty data from the given VirtScreen to the display. If the camera moved,
|
||||
* a full blit is done, otherwise only the visible dirty areas are updated.
|
||||
*/
|
||||
void Gdi::updateDirtyScreen(VirtScreen *vs) {
|
||||
// Do nothing for unused virtual screens
|
||||
if (vs->height == 0)
|
||||
return;
|
||||
|
||||
if (_vm->_features & GF_NEW_CAMERA && (_vm->camera._cur.y != _vm->camera._last.y)) {
|
||||
drawStripToScreen(vs, 0, _numStrips * 8, 0, vs->height);
|
||||
} else {
|
||||
int i;
|
||||
int start, w, top, bottom;
|
||||
int i;
|
||||
int w = 8;
|
||||
int start = 0;
|
||||
|
||||
w = 8;
|
||||
start = 0;
|
||||
|
||||
for (i = 0; i < _numStrips; i++) {
|
||||
bottom = vs->bdirty[i];
|
||||
|
||||
if (bottom) {
|
||||
top = vs->tdirty[i];
|
||||
vs->tdirty[i] = vs->height;
|
||||
vs->bdirty[i] = 0;
|
||||
if (i != (_numStrips - 1) && vs->bdirty[i + 1] == bottom && vs->tdirty[i + 1] == top) {
|
||||
// Simple optimizations: if two or more neighbouring strips form one bigger rectangle,
|
||||
// blit them all at once.
|
||||
w += 8;
|
||||
continue;
|
||||
}
|
||||
// handle vertically scrolling rooms
|
||||
if (_vm->_features & GF_NEW_CAMERA)
|
||||
drawStripToScreen(vs, start * 8, w, 0, vs->height);
|
||||
else
|
||||
drawStripToScreen(vs, start * 8, w, top, bottom);
|
||||
w = 8;
|
||||
for (i = 0; i < _numStrips; i++) {
|
||||
if (vs->bdirty[i]) {
|
||||
const int bottom = vs->bdirty[i];
|
||||
const int top = vs->tdirty[i];
|
||||
vs->tdirty[i] = vs->height;
|
||||
vs->bdirty[i] = 0;
|
||||
if (i != (_numStrips - 1) && vs->bdirty[i + 1] == bottom && vs->tdirty[i + 1] == top) {
|
||||
// Simple optimizations: if two or more neighbouring strips form one bigger rectangle,
|
||||
// blit them all at once.
|
||||
w += 8;
|
||||
continue;
|
||||
}
|
||||
start = i + 1;
|
||||
// handle vertically scrolling rooms
|
||||
if (_vm->_features & GF_NEW_CAMERA)
|
||||
drawStripToScreen(vs, start * 8, w, 0, vs->height);
|
||||
else
|
||||
drawStripToScreen(vs, start * 8, w, top, bottom);
|
||||
w = 8;
|
||||
}
|
||||
start = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2257,7 +2253,7 @@ void ScummEngine::fadeOut(int effect) {
|
||||
case 129:
|
||||
// Just blit screen 0 to the display (i.e. display will be black)
|
||||
vs->setDirtyRange(0, vs->height);
|
||||
updateDirtyScreen(0);
|
||||
updateDirtyScreen(kMainVirtScreen);
|
||||
break;
|
||||
case 134:
|
||||
dissolveEffect(1, 1);
|
||||
@ -2341,7 +2337,7 @@ void ScummEngine::transitionEffect(int a) {
|
||||
else
|
||||
virtscr[0].bdirty[l] = (b + 1) * 8;
|
||||
}
|
||||
updateDirtyScreen(0);
|
||||
updateDirtyScreen(kMainVirtScreen);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
|
44
scumm/gfx.h
44
scumm/gfx.h
@ -29,13 +29,15 @@ namespace Scumm {
|
||||
|
||||
class ScummEngine;
|
||||
|
||||
enum { /** Camera modes */
|
||||
CM_NORMAL = 1,
|
||||
CM_FOLLOW_ACTOR = 2,
|
||||
CM_PANNING = 3
|
||||
/** Camera modes */
|
||||
enum {
|
||||
kNormalCameraMode = 1,
|
||||
kFollowActorCameraMode = 2,
|
||||
kPanningCameraMode = 3
|
||||
};
|
||||
|
||||
struct CameraData { /** Camera state data */
|
||||
/** Camera state data */
|
||||
struct CameraData {
|
||||
Common::Point _cur;
|
||||
Common::Point _dest;
|
||||
Common::Point _accel;
|
||||
@ -45,7 +47,15 @@ struct CameraData { /** Camera state data */
|
||||
bool _movingToActor;
|
||||
};
|
||||
|
||||
struct VirtScreen { /** Virtual screen areas */
|
||||
/** Virtual screen identifiers */
|
||||
enum {
|
||||
kMainVirtScreen = 0, // The 'stage'
|
||||
kTextVirtScreen = 1, // In V1-V3 games: the area where text is printed
|
||||
kVerbVirtScreen = 2 // The verb area
|
||||
};
|
||||
|
||||
/** Virtual screen areas */
|
||||
struct VirtScreen {
|
||||
int number;
|
||||
uint16 topline;
|
||||
uint16 width, height;
|
||||
@ -66,7 +76,8 @@ struct VirtScreen { /** Virtual screen areas */
|
||||
}
|
||||
};
|
||||
|
||||
struct ColorCycle { /** Palette cycles */
|
||||
/** Palette cycles */
|
||||
struct ColorCycle {
|
||||
uint16 delay;
|
||||
uint16 counter;
|
||||
uint16 flags;
|
||||
@ -74,7 +85,8 @@ struct ColorCycle { /** Palette cycles */
|
||||
byte end;
|
||||
};
|
||||
|
||||
struct BlastObject { /** BlastObjects to draw */
|
||||
/** BlastObjects to draw */
|
||||
struct BlastObject {
|
||||
uint16 number;
|
||||
int16 posX, posY;
|
||||
uint16 width, height;
|
||||
@ -190,14 +202,14 @@ public:
|
||||
// to get it fixed and so that really interested parties can experiment it.
|
||||
// It is NOT FIT FOR GENERAL USAGE! You have been warned.
|
||||
//
|
||||
// Doing this correctly will be quite some more complicated. Basically, with smooth
|
||||
// scrolling, the virtual screen strips don't match the display screen strips.
|
||||
// Hence we either have to draw partial strips - but that'd be rather cumbersome.
|
||||
// Or the much simple (and IMHO more elegant) solution is to simply use a screen pitch
|
||||
// that is 8 pixel wider than the real screen width, and always draw one strip more than
|
||||
// needed to the backbuf. This will still require quite some code to be changed but
|
||||
// should otherwise be relatively easy to understand, and using VirtScreen::pitch
|
||||
// will actually clean up the code.
|
||||
// Doing this correctly will be complicated. Basically, with smooth scrolling,
|
||||
// the virtual screen strips don't match the display screen strips. Hence we
|
||||
// either have to draw partial strips (but that'd be rather cumbersome). Or the
|
||||
// alternative (and IMHO more elegant) solution is to simply use a screen pitch
|
||||
// that is 8 pixel wider than the real screen width, and always draw one strip
|
||||
// more than needed to the backbuf. This will still require quite some code to
|
||||
// be changed but should otherwise be relatively easy to understand, and using
|
||||
// VirtScreen::pitch will actually clean up the code.
|
||||
//
|
||||
// #define V7_SMOOTH_SCROLLING_HACK
|
||||
|
||||
|
@ -1411,7 +1411,7 @@ void ScummEngine_v2::o2_endCutscene() {
|
||||
|
||||
if (_gameId == GID_MANIAC) {
|
||||
camera._mode = (byte) vm.cutSceneData[3];
|
||||
if (camera._mode == CM_FOLLOW_ACTOR) {
|
||||
if (camera._mode == kFollowActorCameraMode) {
|
||||
actorFollowCamera(VAR(VAR_EGO));
|
||||
} else if (vm.cutSceneData[2] != _currentRoom) {
|
||||
startScene(vm.cutSceneData[2], 0, 0);
|
||||
|
@ -2083,7 +2083,7 @@ void ScummEngine::startScene(int room, Actor *a, int objectNr) {
|
||||
VAR(VAR_CAMERA_MAX_Y) = _roomHeight - (_screenHeight / 2);
|
||||
setCameraAt(_screenWidth / 2, _screenHeight / 2);
|
||||
} else {
|
||||
camera._mode = CM_NORMAL;
|
||||
camera._mode = kNormalCameraMode;
|
||||
if (_version > 2)
|
||||
camera._cur.x = camera._dest.x = _screenWidth / 2;
|
||||
camera._cur.y = camera._dest.y = _screenHeight / 2;
|
||||
|
Loading…
Reference in New Issue
Block a user