diff options
author | Andrew Kurushin | 2005-07-08 16:56:03 +0000 |
---|---|---|
committer | Andrew Kurushin | 2005-07-08 16:56:03 +0000 |
commit | d944bd7793d1e366bf3555cea3c11a488b9eecaf (patch) | |
tree | d60c38c67d9341749021e838fd698378ca6b71a1 | |
parent | 7e0033983fef78e6d1597fc601a700aa2aafe27e (diff) | |
download | scummvm-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.cpp | 26 | ||||
-rw-r--r-- | saga/actor.h | 2 | ||||
-rw-r--r-- | saga/events.cpp | 38 | ||||
-rw-r--r-- | saga/game.cpp | 2 | ||||
-rw-r--r-- | saga/gfx.cpp | 49 | ||||
-rw-r--r-- | saga/gfx.h | 46 | ||||
-rw-r--r-- | saga/interface.cpp | 14 | ||||
-rw-r--r-- | saga/isomap.cpp | 4 | ||||
-rw-r--r-- | saga/puzzle.cpp | 11 | ||||
-rw-r--r-- | saga/saga.cpp | 5 | ||||
-rw-r--r-- | saga/saga.h | 4 | ||||
-rw-r--r-- | saga/scene.cpp | 37 | ||||
-rw-r--r-- | saga/scene.h | 20 | ||||
-rw-r--r-- | saga/sfuncs.cpp | 18 | ||||
-rw-r--r-- | saga/sprite.cpp | 160 | ||||
-rw-r--r-- | saga/sprite.h | 20 | ||||
-rw-r--r-- | saga/transitions.cpp | 2 |
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; |