aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kurushin2005-07-08 16:56:03 +0000
committerAndrew Kurushin2005-07-08 16:56:03 +0000
commitd944bd7793d1e366bf3555cea3c11a488b9eecaf (patch)
treed60c38c67d9341749021e838fd698378ca6b71a1
parent7e0033983fef78e6d1597fc601a700aa2aafe27e (diff)
downloadscummvm-rg350-d944bd7793d1e366bf3555cea3c11a488b9eecaf.tar.gz
scummvm-rg350-d944bd7793d1e366bf3555cea3c11a488b9eecaf.tar.bz2
scummvm-rg350-d944bd7793d1e366bf3555cea3c11a488b9eecaf.zip
implemented per scene actors clipping
so last sequence should look much better (not perfect) svn-id: r18516
-rw-r--r--saga/actor.cpp26
-rw-r--r--saga/actor.h2
-rw-r--r--saga/events.cpp38
-rw-r--r--saga/game.cpp2
-rw-r--r--saga/gfx.cpp49
-rw-r--r--saga/gfx.h46
-rw-r--r--saga/interface.cpp14
-rw-r--r--saga/isomap.cpp4
-rw-r--r--saga/puzzle.cpp11
-rw-r--r--saga/saga.cpp5
-rw-r--r--saga/saga.h4
-rw-r--r--saga/scene.cpp37
-rw-r--r--saga/scene.h20
-rw-r--r--saga/sfuncs.cpp18
-rw-r--r--saga/sprite.cpp160
-rw-r--r--saga/sprite.h20
-rw-r--r--saga/transitions.cpp2
17 files changed, 196 insertions, 262 deletions
diff --git a/saga/actor.cpp b/saga/actor.cpp
index 12cad6eb41..16d6cffe77 100644
--- a/saga/actor.cpp
+++ b/saga/actor.cpp
@@ -1225,8 +1225,9 @@ void Actor::direct(int msec) {
}
-void Actor::calcScreenPosition(CommonObjectData *commonObjectData) {
+bool Actor::calcScreenPosition(CommonObjectData *commonObjectData) {
int beginSlope, endSlope, middle;
+ bool result;
if (_vm->_scene->getFlags() & kSceneFlagISO) {
_vm->_isoMap->tileCoordsToScreenPoint(commonObjectData->location, commonObjectData->screenPosition);
commonObjectData->screenScale = 256;
@@ -1252,6 +1253,12 @@ void Actor::calcScreenPosition(CommonObjectData *commonObjectData) {
commonObjectData->location.toScreenPointXYZ(commonObjectData->screenPosition);
}
+ result = commonObjectData->screenPosition.x > -64 &&
+ commonObjectData->screenPosition.x < _vm->getDisplayWidth() + 64 &&
+ commonObjectData->screenPosition.y > -64 &&
+ commonObjectData->screenPosition.y < _vm->getSceneHeight() + 64;
+
+ return result;
}
uint16 Actor::hitTest(const Point &testPoint, bool skipProtagonist) {
@@ -1262,17 +1269,8 @@ uint16 Actor::hitTest(const Point &testPoint, bool skipProtagonist) {
// fine to interact with. For example, the door entrance at the glass
// makers's house in ITE's ferret village.
- SCENE_BGINFO bg_info;
- Common::Rect sceneRect;
-
- _vm->_scene->getBGInfo(&bg_info);
- sceneRect.left = bg_info.bg_x;
- sceneRect.top = bg_info.bg_y;
- sceneRect.right = bg_info.bg_x + bg_info.bg_w;
- sceneRect.bottom = bg_info.bg_y + bg_info.bg_h;
-
- if (!sceneRect.contains(testPoint))
+ if (!_vm->_scene->getSceneClip().contains(testPoint))
return ID_NOTHING;
CommonObjectOrderList::iterator drawOrderIterator;
@@ -1328,7 +1326,9 @@ void Actor::createDrawOrderList() {
continue;
_drawOrderList.pushBack(obj, compareFunction);
- calcScreenPosition(obj);
+ if (!calcScreenPosition(obj)) {
+ warning("calcScreenPosition return false actorIdx=%i", i);
+ }
}
}
@@ -1393,7 +1393,7 @@ void Actor::drawActors() {
if (_vm->_scene->getFlags() & kSceneFlagISO) {
_vm->_isoMap->drawSprite(back_buf, *spriteList, frameNumber, drawObject->location, drawObject->screenPosition, drawObject->screenScale);
} else {
- _vm->_sprite->drawOccluded(back_buf, *spriteList, frameNumber, drawObject->screenPosition, drawObject->screenScale, drawObject->screenDepth);
+ _vm->_sprite->drawOccluded(back_buf, _vm->_scene->getSceneClip(),*spriteList, frameNumber, drawObject->screenPosition, drawObject->screenScale, drawObject->screenDepth);
}
}
diff --git a/saga/actor.h b/saga/actor.h
index 39b14ff10d..0f2b4255db 100644
--- a/saga/actor.h
+++ b/saga/actor.h
@@ -568,7 +568,7 @@ private:
void stepZoneAction(ActorData *actor, const HitZone *hitZone, bool exit, bool stopped);
void createDrawOrderList();
- void calcScreenPosition(CommonObjectData *commonObjectData);
+ bool calcScreenPosition(CommonObjectData *commonObjectData);
bool getSpriteParams(CommonObjectData *commonObjectData, int &frameNumber, SpriteList *&spriteList);
bool followProtagonist(ActorData *actor);
diff --git a/saga/events.cpp b/saga/events.cpp
index 378ff9a772..ec23f8f12e 100644
--- a/saga/events.cpp
+++ b/saga/events.cpp
@@ -125,7 +125,7 @@ int Events::handleContinuous(EVENT *event) {
int event_done = 0;
BUFFER_INFO buf_info;
- SCENE_BGINFO bg_info;
+ BGInfo bgInfo;
event_pc = ((double)event->duration - event->time) / event->duration;
@@ -162,10 +162,10 @@ int Events::handleContinuous(EVENT *event) {
switch (event->op) {
case EVENT_DISSOLVE:
_vm->_render->getBufferInfo(&buf_info);
- _vm->_scene->getBGInfo(&bg_info);
+ _vm->_scene->getBGInfo(bgInfo);
_vm->transitionDissolve(buf_info.bg_buf, buf_info.bg_buf_w,
- buf_info.bg_buf_h, buf_info.bg_buf_w, bg_info.bg_buf, bg_info.bg_w,
- bg_info.bg_h, bg_info.bg_p, 0, 0, 0, event_pc);
+ buf_info.bg_buf_h, buf_info.bg_buf_w, bgInfo.buffer, bgInfo.bounds.width(),
+ bgInfo.bounds.height(), 0, 0, 0, event_pc);
break;
case EVENT_DISSOLVE_BGMASK:
// we dissolve it centered.
@@ -177,7 +177,7 @@ int Events::handleContinuous(EVENT *event) {
_vm->_render->getBufferInfo(&buf_info);
_vm->_scene->getBGMaskInfo(w, h, mask_buf, len);
_vm->transitionDissolve(buf_info.bg_buf, buf_info.bg_buf_w,
- buf_info.bg_buf_h, buf_info.bg_buf_w, mask_buf, w, h, 0, 1,
+ buf_info.bg_buf_h, buf_info.bg_buf_w, mask_buf, w, h, 1,
(320 - w) / 2, (200 - h) / 2, event_pc);
break;
default:
@@ -254,7 +254,7 @@ int Events::handleOneShot(EVENT *event) {
ScriptThread *sthread;
Rect rect;
- static SCENE_BGINFO bginfo;
+ static BGInfo bgInfo;
if (event->time > 0) {
return EVENT_CONTINUE;
@@ -301,29 +301,29 @@ int Events::handleOneShot(EVENT *event) {
back_buf = _vm->_gfx->getBackBuffer();
_vm->_render->getBufferInfo(&rbuf_info);
- _vm->_scene->getBGInfo(&bginfo);
+ _vm->_scene->getBGInfo(bgInfo);
- bg_pt.x = bginfo.bg_x;
- bg_pt.y = bginfo.bg_y;
+ bg_pt.x = bgInfo.bounds.left;
+ bg_pt.y = bgInfo.bounds.top;
bufToBuffer(rbuf_info.bg_buf, rbuf_info.bg_buf_w, rbuf_info.bg_buf_h,
- bginfo.bg_buf, bginfo.bg_w, bginfo.bg_h, NULL, &bg_pt);
+ bgInfo.buffer, bgInfo.bounds.width(), bgInfo.bounds.height(), NULL, &bg_pt);
// If it is inset scene then draw black border
- if (bginfo.bg_w < _vm->getDisplayWidth() || bginfo.bg_h < _vm->getSceneHeight()) {
+ if (bgInfo.bounds.width() < _vm->getDisplayWidth() || bgInfo.bounds.height() < _vm->getSceneHeight()) {
SURFACE s;
s.pixels = rbuf_info.bg_buf;
s.w = s.pitch = rbuf_info.bg_buf_w;
s.h = rbuf_info.bg_buf_h;
s.bytesPerPixel = 1;
- Common::Rect rect1(2, bginfo.bg_h + 4);
- Common::Rect rect2(bginfo.bg_w + 4, 2);
- Common::Rect rect3(2, bginfo.bg_h + 4);
- Common::Rect rect4(bginfo.bg_w + 4, 2);
- rect1.moveTo(bginfo.bg_x - 2, bginfo.bg_y - 2);
- rect2.moveTo(bginfo.bg_x - 2, bginfo.bg_y - 2);
- rect3.moveTo(bginfo.bg_x + bginfo.bg_w, bginfo.bg_y - 2);
- rect4.moveTo(bginfo.bg_x - 2, bginfo.bg_y + bginfo.bg_h);
+ Common::Rect rect1(2, bgInfo.bounds.height() + 4);
+ Common::Rect rect2(bgInfo.bounds.width() + 4, 2);
+ Common::Rect rect3(2, bgInfo.bounds.height() + 4);
+ Common::Rect rect4(bgInfo.bounds.width() + 4, 2);
+ rect1.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2);
+ rect2.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.top - 2);
+ rect3.moveTo(bgInfo.bounds.right, bgInfo.bounds.top - 2);
+ rect4.moveTo(bgInfo.bounds.left - 2, bgInfo.bounds.bottom);
drawRect(&s, rect1, kITEColorBlack);
drawRect(&s, rect2, kITEColorBlack);
diff --git a/saga/game.cpp b/saga/game.cpp
index 44e2b7cb53..3287c667ef 100644
--- a/saga/game.cpp
+++ b/saga/game.cpp
@@ -1060,6 +1060,8 @@ int SagaEngine::loadGame(int gameNumber) {
_gameNumber = gameNumber;
_gameDescription = &gameDescriptions[gameNumber];
_gameDisplayInfo = *_gameDescription->gameDisplayInfo;
+ _displayClip.right = _gameDisplayInfo.logicalWidth;
+ _displayClip.bottom = _gameDisplayInfo.logicalHeight;
gameFileCount = _gameDescription->filesCount;
diff --git a/saga/gfx.cpp b/saga/gfx.cpp
index cd26e03e0e..2c2439608c 100644
--- a/saga/gfx.cpp
+++ b/saga/gfx.cpp
@@ -396,55 +396,6 @@ int drawPolyLine(SURFACE *ds, const Point *pts, int pt_ct, int draw_color) {
return SUCCESS;
}
-int getClipInfo(CLIPINFO *clipinfo) {
- Common::Rect s;
- int d_x, d_y;
-
- Common::Rect clip;
-
- if (clipinfo == NULL) {
- return FAILURE;
- }
-
- if (clipinfo->dst_pt != NULL) {
- d_x = clipinfo->dst_pt->x;
- d_y = clipinfo->dst_pt->y;
- } else {
- d_x = 0;
- d_y = 0;
- }
-
- // Get the clip rect.
-
- clip.left = clipinfo->dst_rect->left;
- clip.right = clipinfo->dst_rect->right;
- clip.top = clipinfo->dst_rect->top;
- clip.bottom = clipinfo->dst_rect->bottom;
-
- // Adjust the rect to draw to its screen coordinates
-
- s.left = d_x + clipinfo->src_rect->left;
- s.right = d_x + clipinfo->src_rect->right;
- s.top = d_y + clipinfo->src_rect->top;
- s.bottom = d_y + clipinfo->src_rect->bottom;
-
- s.clip(clip);
-
- if (s.width() <= 0 || s.height() <= 0) {
- clipinfo->nodraw = 1;
- return SUCCESS;
- }
-
- clipinfo->nodraw = 0;
- clipinfo->src_draw_x = s.left - clipinfo->src_rect->left - d_x;
- clipinfo->src_draw_y = s.top - clipinfo->src_rect->top - d_y;
- clipinfo->dst_draw_x = s.left;
- clipinfo->dst_draw_y = s.top;
- clipinfo->draw_w = s.width();
- clipinfo->draw_h = s.height();
-
- return SUCCESS;
-}
SURFACE *Gfx::getBackBuffer() {
return &_back_buf;
diff --git a/saga/gfx.h b/saga/gfx.h
index 1cd0ba25f1..4dc671814e 100644
--- a/saga/gfx.h
+++ b/saga/gfx.h
@@ -33,20 +33,43 @@ namespace Saga {
using Common::Point;
using Common::Rect;
-struct CLIPINFO {
+struct ClipData {
// input members
- const Rect *src_rect;
- const Rect *dst_rect;
- const Point *dst_pt;
+ Rect sourceRect;
+ Rect destRect;
+ Point destPoint;
// output members
- int nodraw;
- int src_draw_x;
- int src_draw_y;
- int dst_draw_x;
- int dst_draw_y;
- int draw_w;
- int draw_h;
+ Point sourceDraw;
+ Point destDraw;
+ int width;
+ int height;
+
+ bool calcClip() {
+ Common::Rect s;
+
+ // Adjust the rect to draw to its screen coordinates
+ s = sourceRect;
+ s.left += destPoint.x;
+ s.right += destPoint.x;
+ s.top += destPoint.y;
+ s.bottom += destPoint.y;
+
+ s.clip(destRect);
+
+ if ((s.width() <= 0) || (s.height() <= 0)) {
+ return false;
+ }
+
+ sourceDraw.x = s.left - sourceRect.left - destPoint.x;
+ sourceDraw.y = s.top - sourceRect.top - destPoint.y;
+ destDraw.x = s.left;
+ destDraw.y = s.top;
+ width = s.width();
+ height = s.height();
+
+ return true;
+ }
};
struct PALENTRY {
@@ -78,7 +101,6 @@ int drawPalette(SURFACE *dst_s);
int bufToSurface(SURFACE *ds, const byte *src, int src_w, int src_h, Rect *src_rect, Point *dst_pt);
int bufToBuffer(byte * dst_buf, int dst_w, int dst_h, const byte *src,
int src_w, int src_h, Rect *src_rect, Point *dst_pt);
-int getClipInfo(CLIPINFO *clipinfo);
int drawRect(SURFACE *ds, Rect &dst_rect, int color);
int drawFrame(SURFACE *ds, const Point *p1, const Point *p2, int color);
int drawPolyLine(SURFACE *ds, const Point *pts, int pt_ct, int draw_color);
diff --git a/saga/interface.cpp b/saga/interface.cpp
index 9e27cde2e1..3f8e6db460 100644
--- a/saga/interface.cpp
+++ b/saga/interface.cpp
@@ -528,7 +528,7 @@ void Interface::drawVerbPanel(SURFACE *backBuffer, PanelButton* panelButton) {
point.x = _mainPanel.x + panelButton->xOffset;
point.y = _mainPanel.y + panelButton->yOffset;
- _vm->_sprite->draw(backBuffer, _mainPanel.sprites, spriteNumber, point, 256);
+ _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _mainPanel.sprites, spriteNumber, point, 256);
drawVerbPanelText(backBuffer, panelButton, textColor, _vm->getDisplayInfo().verbTextShadowColor);
}
@@ -577,7 +577,7 @@ void Interface::draw() {
_lockedMode == kPanelMain || _lockedMode == kPanelConverse) {
leftPortraitPoint.x = _mainPanel.x + _vm->getDisplayInfo().leftPortraitXOffset;
leftPortraitPoint.y = _mainPanel.y + _vm->getDisplayInfo().leftPortraitYOffset;
- _vm->_sprite->draw(backBuffer, _defPortraits, _leftPortrait, leftPortraitPoint, 256);
+ _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _defPortraits, _leftPortrait, leftPortraitPoint, 256);
}
if (!_inMainMode && _vm->getDisplayInfo().rightPortraitXOffset >= 0) { //FIXME: should we change !_inMainMode to _panelMode == kPanelConverse ?
@@ -592,7 +592,7 @@ void Interface::draw() {
if (_rightPortrait >= _scenePortraits.spriteCount)
_rightPortrait = 0;
- _vm->_sprite->draw(backBuffer, _scenePortraits, _rightPortrait, rightPortraitPoint, 256);
+ _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _scenePortraits, _rightPortrait, rightPortraitPoint, 256);
}
drawInventory(backBuffer);
@@ -1345,7 +1345,7 @@ void Interface::drawStatusBar() {
rect.right = rect.left + _vm->getDisplayInfo().saveReminderWidth;
rect.bottom = rect.top + _vm->getDisplayInfo().saveReminderHeight;
- _vm->_sprite->draw(backBuffer, _vm->_sprite->_mainSprites,
+ _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _vm->_sprite->_mainSprites,
_saveReminderState == 1 ? _vm->getDisplayInfo().saveReminderFirstSpriteNumber : _vm->getDisplayInfo().saveReminderSecondSpriteNumber,
rect, 256);
@@ -1561,7 +1561,7 @@ void Interface::drawInventory(SURFACE *backBuffer) {
point.x = rect.left;
point.y = rect.top;
obj = _vm->_actor->getObj(_inventory[ci]);
- _vm->_sprite->draw(backBuffer, _vm->_sprite->_mainSprites, obj->spriteListResourceId, rect, 256);
+ _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _vm->_sprite->_mainSprites, obj->spriteListResourceId, rect, 256);
ci++;
}
@@ -1729,7 +1729,7 @@ void Interface::drawPanelButtonArrow(SURFACE *ds, InterfacePanel *panel, PanelBu
point.x = panel->x + panelButton->xOffset;
point.y = panel->y + panelButton->yOffset;
- _vm->_sprite->draw(ds, _vm->_sprite->_mainSprites, spriteNumber, point, 256);
+ _vm->_sprite->draw(ds, _vm->getDisplayClip(), _vm->_sprite->_mainSprites, spriteNumber, point, 256);
}
void Interface::drawVerbPanelText(SURFACE *ds, PanelButton *panelButton, int textColor, int textShadowColor) {
@@ -2113,7 +2113,7 @@ void Interface::mapPanelDrawCrossHair() {
Rect screen(_vm->getDisplayWidth(), _vm->getSceneHeight());
if (screen.contains(mapPosition)) {
- _vm->_sprite->draw(backBuffer, _vm->_sprite->_mainSprites,
+ _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _vm->_sprite->_mainSprites,
_mapPanelCrossHairState? RID_ITE_SPR_XHAIR1 : RID_ITE_SPR_XHAIR2,
mapPosition, 256);
}
diff --git a/saga/isomap.cpp b/saga/isomap.cpp
index 36153d690d..18f524f905 100644
--- a/saga/isomap.cpp
+++ b/saga/isomap.cpp
@@ -379,7 +379,7 @@ int16 IsoMap::findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH) {
int IsoMap::draw(SURFACE *ds) {
- Rect isoRect(_vm->getDisplayWidth(), _vm->getClippedSceneHeight());
+ Rect isoRect(_vm->_scene->getSceneClip());
drawRect(ds, isoRect, 0);
_tileClip = isoRect;
drawTiles(ds, NULL);
@@ -399,7 +399,7 @@ void IsoMap::drawSprite(SURFACE *ds, SpriteList &spriteList, int spriteNumber, c
int yAlign;
const byte *spriteBuffer;
Point spritePointer;
- Rect clip(_vm->getDisplayWidth(), _vm->getClippedSceneHeight());
+ Rect clip(_vm->_scene->getSceneClip());
_vm->_sprite->getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
diff --git a/saga/puzzle.cpp b/saga/puzzle.cpp
index addfdd65f8..76a97df194 100644
--- a/saga/puzzle.cpp
+++ b/saga/puzzle.cpp
@@ -267,7 +267,7 @@ void Puzzle::showPieces(void) {
int num = _piecePriority[j];
if (_puzzlePiece != num) {
- _vm->_sprite->draw(backBuffer, puzzle->spriteList, num, Point(_pieceInfo[num].curX, _pieceInfo[num].curY), 256);
+ _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), puzzle->spriteList, num, Point(_pieceInfo[num].curX, _pieceInfo[num].curY), 256);
}
}
}
@@ -275,14 +275,9 @@ void Puzzle::showPieces(void) {
void Puzzle::drawCurrentPiece() {
ActorData *puzzle = _vm->_actor->getActor(_vm->_actor->actorIndexToId(ITE_ACTOR_PUZZLE));
SURFACE *backBuffer = _vm->_gfx->getBackBuffer();
- SCENE_BGINFO bg_info;
- _vm->_scene->getBGInfo(&bg_info);
-
- Rect clip(bg_info.bg_x, bg_info.bg_y, bg_info.bg_x + bg_info.bg_w, bg_info.bg_y + bg_info.bg_h);
-
- _vm->_sprite->draw(backBuffer, puzzle->spriteList, _puzzlePiece,
- Point(_pieceInfo[_puzzlePiece].curX, _pieceInfo[_puzzlePiece].curY), 256, &clip);
+ _vm->_sprite->draw(backBuffer, _vm->_scene->getSceneClip(), puzzle->spriteList, _puzzlePiece,
+ Point(_pieceInfo[_puzzlePiece].curX, _pieceInfo[_puzzlePiece].curY), 256);
}
void Puzzle::movePiece(Point mousePt) {
diff --git a/saga/saga.cpp b/saga/saga.cpp
index 37dbdafc48..c03dee77e3 100644
--- a/saga/saga.cpp
+++ b/saga/saga.cpp
@@ -165,6 +165,7 @@ SagaEngine::SagaEngine(GameDetector *detector, OSystem *syst)
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
+ _displayClip.left = _displayClip.top = 0;
_vm = this;
}
@@ -302,6 +303,10 @@ int SagaEngine::go() {
_previousTicks = _system->getMillis();
+ if (ConfMan.hasKey("start_scene")) {
+ _scene->changeScene(ConfMan.getInt("start_scene"), 0, kTransitionNoFade);
+ }
+ else
if (ConfMan.hasKey("save_slot")) {
// First scene sets up palette
_scene->changeScene(getStartSceneNumber(), 0, kTransitionNoFade);
diff --git a/saga/saga.h b/saga/saga.h
index 95ef5217d7..dd696326fd 100644
--- a/saga/saga.h
+++ b/saga/saga.h
@@ -587,7 +587,7 @@ public:
int textProcessList(TEXTLIST *textlist, long ms);
int transitionDissolve(byte *dst_img, int dst_w, int dst_h, int dst_p,
- const byte *src_img, int src_w, int src_h, int src_p, int flags, int x, int y,
+ const byte *src_img, int src_w, int src_h, int flags, int x, int y,
double percent);
int processInput(void);
@@ -627,6 +627,7 @@ public:
int _gameNumber;
GameDescription *_gameDescription;
GameDisplayInfo _gameDisplayInfo;
+ Common::Rect _displayClip;
public:
int initGame(void);
@@ -649,6 +650,7 @@ public:
int getStartSceneNumber() const { return _gameDescription->startSceneNumber; }
+ const Common::Rect &getDisplayClip() const { return _displayClip;}
int getDisplayWidth() const { return _gameDisplayInfo.logicalWidth; }
int getDisplayHeight() const { return _gameDisplayInfo.logicalHeight;}
int getSceneHeight() const { return _gameDisplayInfo.sceneHeight; }
diff --git a/saga/scene.cpp b/saga/scene.cpp
index a050d76d87..3cf3bf5db6 100644
--- a/saga/scene.cpp
+++ b/saga/scene.cpp
@@ -267,32 +267,22 @@ void Scene::getSlopes(int &beginSlope, int &endSlope) {
endSlope = _vm->getSceneHeight() - _sceneDescription.endSlope;
}
-int Scene::getBGInfo(SCENE_BGINFO *bginfo) {
- int x, y;
-
- assert(_initialized);
-
- bginfo->bg_buf = _bg.buf;
- bginfo->bg_buflen = _bg.buf_len;
- bginfo->bg_w = _bg.w;
- bginfo->bg_h = _bg.h;
- bginfo->bg_p = _bg.p;
-
- x = 0;
- y = 0;
+void Scene::getBGInfo(BGInfo &bgInfo) {
+ bgInfo.buffer = _bg.buf;
+ bgInfo.bufferLength = _bg.buf_len;
+ bgInfo.bounds.left = 0;
+ bgInfo.bounds.top = 0;
if (_bg.w < _vm->getDisplayWidth()) {
- x = (_vm->getDisplayWidth() - _bg.w) / 2;
+ bgInfo.bounds.left = (_vm->getDisplayWidth() - _bg.w) / 2;
}
if (_bg.h < _vm->getSceneHeight()) {
- y = (_vm->getSceneHeight() - _bg.h) / 2;
+ bgInfo.bounds.top = (_vm->getClippedSceneHeight() - _bg.h) / 2;
}
- bginfo->bg_x = x;
- bginfo->bg_y = y;
-
- return SUCCESS;
+ bgInfo.bounds.setWidth(_bg.w);
+ bgInfo.bounds.setHeight(_bg.h);
}
int Scene::getBGPal(PALENTRY **pal) {
@@ -456,7 +446,16 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) {
if (_sceneDescription.flags & kSceneFlagISO) {
_outsetSceneNumber = _sceneNumber;
+
+ _sceneClip.left = 0;
+ _sceneClip.top = 0;
+ _sceneClip.right = _vm->getDisplayWidth();
+ _sceneClip.bottom = _vm->getClippedSceneHeight();
} else {
+ BGInfo backGroundInfo;
+ getBGInfo(backGroundInfo);
+ _sceneClip = backGroundInfo.bounds;
+
if (!(_bg.w < _vm->getDisplayWidth() || _bg.h < _vm->getSceneHeight()))
_outsetSceneNumber = _sceneNumber;
}
diff --git a/saga/scene.h b/saga/scene.h
index a67acb4fd9..7b6767f062 100644
--- a/saga/scene.h
+++ b/saga/scene.h
@@ -43,14 +43,10 @@ enum SceneFlags {
kSceneFlagShowCursor = 2
};
-struct SCENE_BGINFO {
- int bg_x;
- int bg_y;
- int bg_w;
- int bg_h;
- int bg_p;
- byte *bg_buf;
- size_t bg_buflen;
+struct BGInfo {
+ Rect bounds;
+ byte *buffer;
+ size_t bufferLength;
};
typedef int (SceneProc) (int, void *);
@@ -232,7 +228,8 @@ class Scene {
int getFlags() const { return _sceneDescription.flags; }
int getScriptModuleNumber() const { return _sceneDescription.scriptModuleNumber; }
bool isInDemo() { return !_inGame; }
-
+ const Rect& getSceneClip() const { return _sceneClip; }
+
void getBGMaskInfo(int &width, int &height, byte *&buffer, size_t &bufferLength);
int isBGMaskPresent() { return _bgMask.loaded; }
int getBGMaskType(const Point &testPoint);
@@ -244,7 +241,7 @@ class Scene {
int getDoorState(int doorNumber);
void initDoorsState();
- int getBGInfo(SCENE_BGINFO *bginfo);
+ void getBGInfo(BGInfo &bgInfo);
int getBGPal(PALENTRY **pal);
void getSlopes(int &beginSlope, int &endSlope);
@@ -296,7 +293,8 @@ class Scene {
SceneProc *_sceneProc;
SCENE_IMAGE _bg;
SCENE_IMAGE _bgMask;
-
+ Common::Rect _sceneClip;
+
int _sceneDoors[SCENE_DOORS_MAX];
diff --git a/saga/sfuncs.cpp b/saga/sfuncs.cpp
index cfba54aaad..95f38cb098 100644
--- a/saga/sfuncs.cpp
+++ b/saga/sfuncs.cpp
@@ -1050,7 +1050,7 @@ void Script::sfPlaceActor(SCRIPTFUNC_PARAMS) {
frameType = thread->pop();
frameOffset = thread->pop();
- debug(1, "sfPlaceActor(%d, %d, %d, %d, %d, %d)", actorId, actorLocation.x,
+ debug(1, "sfPlaceActor(id = %d, x=%d, y=%d, dir=%d, frameType=%d, frameOffset=%d)", actorId, actorLocation.x,
actorLocation.y, actorDirection, frameType, frameOffset);
if (_vm->getGameType() == GType_IHNM) {
@@ -1241,7 +1241,7 @@ void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
event.data = back_buf;
event.param = 138;
event.param2 = 0;
- event.param3 = _vm->getSceneHeight();
+ event.param3 = _vm->getClippedSceneHeight();
event.param4 = 0;
event.param5 = _vm->getDisplayWidth();
@@ -1258,7 +1258,7 @@ void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
text_entry.color = kITEColorBrightWhite;
text_entry.effect_color = kITEColorBlack;
text_entry.text_x = _vm->getDisplayWidth() / 2;
- text_entry.text_y = (_vm->getSceneHeight() - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2;
+ text_entry.text_y = (_vm->getClippedSceneHeight() - _vm->_font->getHeight(MEDIUM_FONT_ID)) / 2;
text_entry.font_id = MEDIUM_FONT_ID;
text_entry.flags = FONT_OUTLINE | FONT_CENTERED;
text_entry.string = thread->_strings->getString(stringId);
@@ -1556,19 +1556,17 @@ void Script::sfGetActorY(SCRIPTFUNC_PARAMS) {
// Script function #62 (0x3E)
void Script::sfEraseDelta(SCRIPTFUNC_PARAMS) {
BUFFER_INFO bufferInfo;
- SCENE_BGINFO backGroundInfo;
+ BGInfo backGroundInfo;
Point backGroundPoint;
_vm->_render->getBufferInfo(&bufferInfo);
- _vm->_scene->getBGInfo(&backGroundInfo);
- backGroundPoint.x = backGroundInfo.bg_x;
- backGroundPoint.y = backGroundInfo.bg_y;
+ _vm->_scene->getBGInfo(backGroundInfo);
+ backGroundPoint.x = backGroundInfo.bounds.left;
+ backGroundPoint.y = backGroundInfo.bounds.top;
bufToBuffer(bufferInfo.bg_buf, bufferInfo.bg_buf_w, bufferInfo.bg_buf_h,
- backGroundInfo.bg_buf, backGroundInfo.bg_w, backGroundInfo.bg_h,
+ backGroundInfo.buffer, backGroundInfo.bounds.width(), backGroundInfo.bounds.height(),
NULL, &backGroundPoint);
-
-
}
// Script function #63 (0x3F)
diff --git a/saga/sprite.cpp b/saga/sprite.cpp
index 0392c699de..a95f91630a 100644
--- a/saga/sprite.cpp
+++ b/saga/sprite.cpp
@@ -170,7 +170,7 @@ void Sprite::getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int
}
-void Sprite::drawClip(SURFACE *ds, Rect clip, const Point &spritePointer, int width, int height, const byte *spriteBuffer) {
+void Sprite::drawClip(SURFACE *ds, const Rect &clipRect, const Point &spritePointer, int width, int height, const byte *spriteBuffer) {
int clipWidth;
int clipHeight;
@@ -182,22 +182,22 @@ void Sprite::drawClip(SURFACE *ds, Rect clip, const Point &spritePointer, int wi
srcRowPointer = spriteBuffer;
clipWidth = width;
- if (width > (clip.right - spritePointer.x)) {
- clipWidth = (clip.right - spritePointer.x);
+ if (width > (clipRect.right - spritePointer.x)) {
+ clipWidth = (clipRect.right - spritePointer.x);
}
clipHeight = height;
- if (height > (clip.bottom - spritePointer.y)) {
- clipHeight = (clip.bottom - spritePointer.y);
+ if (height > (clipRect.bottom - spritePointer.y)) {
+ clipHeight = (clipRect.bottom - spritePointer.y);
}
jo = 0;
io = 0;
- if (spritePointer.x < clip.left) {
- jo = clip.left - spritePointer.x;
+ if (spritePointer.x < clipRect.left) {
+ jo = clipRect.left - spritePointer.x;
}
- if (spritePointer.y < clip.top) {
- io = clip.top - spritePointer.y;
+ if (spritePointer.y < clipRect.top) {
+ io = clipRect.top - spritePointer.y;
bufRowPointer += ds->pitch * io;
srcRowPointer += width * io;
}
@@ -217,60 +217,29 @@ void Sprite::drawClip(SURFACE *ds, Rect clip, const Point &spritePointer, int wi
}
}
-int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int32 spriteNumber, const Point &screenCoord, int scale, Rect *clipOverride) {
+void Sprite::draw(SURFACE *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Point &screenCoord, int scale) {
const byte *spriteBuffer;
int width;
int height;
int xAlign;
int yAlign;
Point spritePointer;
- Rect clip;
-
- assert(_initialized);
-
- if (clipOverride) {
- clip.left = clipOverride->left;
- clip.right = clipOverride->right;
- clip.top = clipOverride->top;
- clip.bottom = clipOverride->bottom;
- } else {
- clip.left = 0;
- clip.right = _vm->getDisplayWidth();
- clip.top = 0;
- clip.bottom = _vm->getDisplayHeight();
- }
getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
spritePointer.x = screenCoord.x + xAlign;
spritePointer.y = screenCoord.y + yAlign;
- drawClip(ds, clip, spritePointer, width, height, spriteBuffer);
-
- return SUCCESS;
+ drawClip(ds, clipRect, spritePointer, width, height, spriteBuffer);
}
-int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int32 spriteNumber, const Rect &screenRect, int scale, Rect *clipOverride) {
+void Sprite::draw(SURFACE *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Rect &screenRect, int scale) {
const byte *spriteBuffer;
int width;
int height;
int xAlign, spw;
int yAlign, sph;
Point spritePointer;
- Rect clip;
-
- assert(_initialized);
-
- if (clipOverride) {
- clip.left = clipOverride->left;
- clip.right = clipOverride->right;
- clip.top = clipOverride->top;
- clip.bottom = clipOverride->bottom;
- } else {
- clip.left = 0;
- clip.right = _vm->getDisplayWidth();
- clip.top = 0;
- clip.bottom = _vm->getDisplayHeight();
- }
+
getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
spw = (screenRect.width() - width) / 2;
@@ -283,9 +252,7 @@ int Sprite::draw(SURFACE *ds, SpriteList &spriteList, int32 spriteNumber, const
}
spritePointer.x = screenRect.left + xAlign + spw;
spritePointer.y = screenRect.top + yAlign + sph;
- drawClip(ds, clip, spritePointer, width, height, spriteBuffer);
-
- return SUCCESS;
+ drawClip(ds, clipRect, spritePointer, width, height, spriteBuffer);
}
bool Sprite::hitTest(SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, const Point &testPoint) {
@@ -316,97 +283,80 @@ bool Sprite::hitTest(SpriteList &spriteList, int spriteNumber, const Point &scre
return *srcRowPointer != 0;
}
-int Sprite::drawOccluded(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth) {
+void Sprite::drawOccluded(SURFACE *ds, const Rect &clipRect, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth) {
const byte *spriteBuffer;
int x, y;
- byte *dst_row_p;
- const byte *src_row_p;
- const byte *src_p;
- byte *dst_p;
- byte *mask_p;
+ byte *destRowPointer;
+ const byte *sourceRowPointer;
+ const byte *sourcePointer;
+ byte *destPointer;
+ byte *maskPointer;
int width;
int height;
int xAlign;
int yAlign;
- Point spritePointer;
- // Clipinfo variables
- Rect spriteSourceRect;
- Rect spriteDestRect;
- CLIPINFO ci;
+ ClipData clipData;
// BG mask variables
int maskWidth;
int maskHeight;
byte *maskBuffer;
size_t maskBufferLength;
- byte *mask_row_p;
- int mask_z;
+ byte *maskRowPointer;
+ int maskZ;
+
assert(_initialized);
if (!_vm->_scene->isBGMaskPresent()) {
- return draw(ds, spriteList, spriteNumber, screenCoord, scale);
+ draw(ds, clipRect, spriteList, spriteNumber, screenCoord, scale);
+ return;
}
_vm->_scene->getBGMaskInfo(maskWidth, maskHeight, maskBuffer, maskBufferLength);
getScaledSpriteBuffer(spriteList, spriteNumber, scale, width, height, xAlign, yAlign, spriteBuffer);
- spritePointer.x = screenCoord.x + xAlign;
- spritePointer.y = screenCoord.y + yAlign;
-
- spriteSourceRect.left = 0;
- spriteSourceRect.top = 0;
- spriteSourceRect.right = width;
- spriteSourceRect.bottom = height;
-
- SCENE_BGINFO bg_info;
-
- _vm->_scene->getBGInfo(&bg_info);
-
- spriteDestRect.left = bg_info.bg_x;
- spriteDestRect.top = bg_info.bg_y;
- spriteDestRect.right = bg_info.bg_x + bg_info.bg_w;
- spriteDestRect.bottom = bg_info.bg_y + bg_info.bg_h;
+ clipData.destPoint.x = screenCoord.x + xAlign;
+ clipData.destPoint.y = screenCoord.y + yAlign;
- ci.dst_rect = &spriteDestRect;
- ci.src_rect = &spriteSourceRect;
- ci.dst_pt = &spritePointer;
+ clipData.sourceRect.left = 0;
+ clipData.sourceRect.top = 0;
+ clipData.sourceRect.right = width;
+ clipData.sourceRect.bottom = height;
- getClipInfo(&ci);
+ clipData.destRect = clipRect;
- if (ci.nodraw) {
- return SUCCESS;
+ if (!clipData.calcClip()) {
+ return;
}
// Finally, draw the occluded sprite
- src_row_p = spriteBuffer + ci.src_draw_x + (ci.src_draw_y * width);
-
- dst_row_p = (byte *)ds->pixels + ci.dst_draw_x + (ci.dst_draw_y * ds->pitch);
- mask_row_p = maskBuffer + ci.dst_draw_x + (ci.dst_draw_y * maskWidth);
-
- for (y = 0; y < ci.draw_h; y++) {
- src_p = src_row_p;
- dst_p = dst_row_p;
- mask_p = mask_row_p;
- for (x = 0; x < ci.draw_w; x++) {
- if (*src_p != 0) {
- mask_z = *mask_p & SPRITE_ZMASK;
- if (mask_z > depth) {
- *dst_p = *src_p;
+ sourceRowPointer = spriteBuffer + clipData.sourceDraw.x + (clipData.sourceDraw.y * width);
+
+ destRowPointer = (byte *)ds->pixels + clipData.destDraw.x + (clipData.destDraw.y * ds->pitch);
+ maskRowPointer = maskBuffer + clipData.destDraw.x + (clipData.destDraw.y * maskWidth);
+
+ for (y = 0; y < clipData.height; y++) {
+ sourcePointer = sourceRowPointer;
+ destPointer = destRowPointer;
+ maskPointer = maskRowPointer;
+ for (x = 0; x < clipData.width; x++) {
+ if (*sourcePointer != 0) {
+ maskZ = *maskPointer & SPRITE_ZMASK;
+ if (maskZ > depth) {
+ *destPointer = *sourcePointer;
}
}
- src_p++;
- dst_p++;
- mask_p++;
+ sourcePointer++;
+ destPointer++;
+ maskPointer++;
}
- dst_row_p += ds->pitch;
- mask_row_p += maskWidth;
- src_row_p += width;
+ destRowPointer += ds->pitch;
+ maskRowPointer += maskWidth;
+ sourceRowPointer += width;
}
-
- return SUCCESS;
}
void Sprite::decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength) {
diff --git a/saga/sprite.h b/saga/sprite.h
index 0a1ba6bf44..a12b35943c 100644
--- a/saga/sprite.h
+++ b/saga/sprite.h
@@ -60,19 +60,31 @@ struct SpriteList {
}
};
+
class Sprite {
public:
SpriteList _mainSprites;
+
+
Sprite(SagaEngine *vm);
~Sprite(void);
+
+ // draw scaled sprite using background scene mask
+ void drawOccluded(SURFACE *ds, const Rect &clipRect, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth);
+
+ // draw scaled sprite using background scene mask
+ void draw(SURFACE *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Point &screenCoord, int scale);
+
+ // main function
+ void drawClip(SURFACE *ds, const Rect &clipRect, const Point &spritePointer, int width, int height, const byte *spriteBuffer);
+
+ void draw(SURFACE *ds, const Rect &clipRect, SpriteList &spriteList, int32 spriteNumber, const Rect &screenRect, int scale);
+
int loadList(int resourceId, SpriteList &spriteList); // load or append spriteList
- int draw(SURFACE *ds, SpriteList &spriteList, int32 spriteNumber, const Point &screenCoord, int scale, Rect *clipOverride = NULL);
- int draw(SURFACE *ds, SpriteList &spriteList, int32 spriteNumber, const Rect &screenRect, int scale, Rect *clipOverride = NULL);
- int drawOccluded(SURFACE *ds, SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, int depth);
bool hitTest(SpriteList &spriteList, int spriteNumber, const Point &screenCoord, int scale, const Point &testPoint);
void getScaledSpriteBuffer(SpriteList &spriteList, int spriteNumber, int scale, int &width, int &height, int &xAlign, int &yAlign, const byte *&buffer);
- void drawClip(SURFACE *ds, Rect clip, const Point &spritePointer, int width, int height, const byte *spriteBuffer);
+
private:
void decodeRLEBuffer(const byte *inputBuffer, size_t inLength, size_t outLength);
void scaleBuffer(const byte *src, int width, int height, int scale);
diff --git a/saga/transitions.cpp b/saga/transitions.cpp
index bb252cf416..6df47be404 100644
--- a/saga/transitions.cpp
+++ b/saga/transitions.cpp
@@ -31,7 +31,7 @@ namespace Saga {
* If flags if set to 1, do zero masking.
*/
int SagaEngine::transitionDissolve(byte *dst_img, int dst_w, int dst_h, int dst_p, const byte *src_img,
- int src_w, int src_h, int src_p, int flags, int x, int y,
+ int src_w, int src_h, int flags, int x, int y,
double percent) {
#define XOR_MASK 0xB400;
int pixelcount = dst_w * dst_h;