aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwhiterandrek2018-06-09 15:54:21 +0300
committerEugene Sandulenko2018-06-28 23:51:32 +0200
commitbfd1b62063040c970894fbf81d9dca9c3d4088d0 (patch)
tree8fc1641df6073f649c7bd47dd9bdfe076ff52e2e
parent4dd40b0f7b8fdf27b59fc7e330b624cd844348da (diff)
downloadscummvm-rg350-bfd1b62063040c970894fbf81d9dca9c3d4088d0.tar.gz
scummvm-rg350-bfd1b62063040c970894fbf81d9dca9c3d4088d0.tar.bz2
scummvm-rg350-bfd1b62063040c970894fbf81d9dca9c3d4088d0.zip
PINK: change drawing method
-rw-r--r--engines/pink/director.cpp179
-rw-r--r--engines/pink/director.h30
-rw-r--r--engines/pink/objects/actions/action_cel.cpp3
-rw-r--r--engines/pink/pink.cpp8
4 files changed, 132 insertions, 88 deletions
diff --git a/engines/pink/director.cpp b/engines/pink/director.cpp
index 0f208c66e5..dd8e870b8d 100644
--- a/engines/pink/director.cpp
+++ b/engines/pink/director.cpp
@@ -29,53 +29,34 @@
#include "pink/objects/actions/action_cel.h"
namespace Pink {
-Director::Director(OSystem *system)
- : _system(system), showBounds(1) {}
+Director::Director()
+ : _surface(640, 480) {
+ _wndManager.setScreen(&_surface);
+}
-void Director::draw() {
- _system->fillScreen(0);
+void Director::update() {
+ static uint32 time = g_system->getMillis();
+ static uint32 times = 0;
+
+ for (uint i = 0; i < _sounds.size(); ++i) {
+ _sounds[i]->update();
+ }
for (uint i = 0; i < _sprites.size(); ++i) {
- drawSprite(_sprites[i]);
+ _sprites[i]->update();
}
- _system->updateScreen();
-}
-void Director::drawSprite(ActionCEL *sprite) {
- CelDecoder *decoder = sprite->getDecoder();
- const Graphics::Surface *surface;
- if (decoder->needsUpdate())
- surface = decoder->decodeNextFrame();
- else
- surface = decoder->getCurrentFrame();
-
- int h = surface->h;
- if (surface->h + decoder->getY() > 480)
- h = 480 - decoder->getY();
- int w = surface->w;
- if (surface->w + decoder->getX() > 640)
- w = 640 - decoder->getX();
-
- if (!showBounds) {
- Graphics::Surface *screen = _system->lockScreen();
-
- for (int y = 0; y < h; ++y) {
- for (int x = 0; x < w; ++x) {
- uint16 spritePixelColourIndex = *(byte*)surface->getBasePtr(x, y);
- if (spritePixelColourIndex != decoder->getTransparentColourIndex()) {
- *(byte *) screen->getBasePtr(decoder->getX() + x, decoder->getY() + y) = spritePixelColourIndex;
- }
- }
- }
- _system->unlockScreen();
- }
- else
- _system->copyRectToScreen(surface->getPixels(), surface->pitch,
- decoder->getX(), decoder->getY(),
- w, h);
+ draw();
+ times++;
+ if (g_system->getMillis() - time >= 1000) {
+ debug("FPS: %u ", times);
+ sum += times;
+ count++;
+ time = g_system->getMillis();
+ times = 0;
+ }
}
-
void Director::addSprite(ActionCEL *sprite) {
_sprites.push_back(sprite);
int i;
@@ -86,6 +67,7 @@ void Director::addSprite(ActionCEL *sprite) {
break;
}
_sprites[i] = sprite;
+ _dirtyRects.push_back(sprite->getDecoder()->getRectangle());
}
void Director::removeSprite(ActionCEL *sprite) {
@@ -95,65 +77,120 @@ void Director::removeSprite(ActionCEL *sprite) {
break;
}
}
+ _dirtyRects.push_back(sprite->getDecoder()->getRectangle());
}
-void Director::setPallette(const byte *pallete) {
- _system->getPaletteManager()->setPalette(pallete, 0, 256);
-}
-
-void Director::update() {
+void Director::removeSound(ActionSound *sound) {
for (uint i = 0; i < _sounds.size(); ++i) {
- _sounds[i]->update();
- }
- for (uint i = 0; i < _sprites.size(); ++i) {
- _sprites[i]->update();
+ if (_sounds[i] == sound)
+ _sounds.remove_at(i);
}
}
-void Director::addSound(ActionSound *sound) {
- _sounds.push_back(sound);
+void Director::clear() {
+ _dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
+ _sprites.resize(0);
}
-void Director::removeSound(ActionSound *sound) {
- for (uint i = 0; i < _sounds.size(); ++i) {
- if (_sounds[i] == sound)
- _sounds.remove_at(i);
+void Director::pause(bool pause) {
+ for (uint i = 0; i < _sprites.size() ; ++i) {
+ _sprites[i]->pause(pause);
}
}
-void Director::clear() {
+void Director::saveStage() {
+ _savedSprites = _sprites;
_sprites.clear();
}
-Actor *Director::getActorByPoint(Common::Point point) {
+void Director::loadStage() {
+ assert(_sprites.empty());
+ _sprites = _savedSprites;
+ _savedSprites.clear();
+}
+
+Actor *Director::getActorByPoint(const Common::Point point) {
for (int i = _sprites.size() - 1; i >= 0; --i) {
CelDecoder *decoder = _sprites[i]->getDecoder();
const Graphics::Surface *frame = decoder->getCurrentFrame();
- Common::Rect &rect = decoder->getRectangle();
- if (rect.contains(point) &&
- *(byte*)frame->getBasePtr(point.x - rect.left, point.y - rect.top)
- != decoder->getTransparentColourIndex())
+ const Common::Rect &rect = decoder->getRectangle();
+ byte spritePixel = *(const byte*) frame->getBasePtr(point.x - rect.left, point.y - rect.top);
+ if (rect.contains(point) && spritePixel != decoder->getTransparentColourIndex()) {
return _sprites[i]->getActor();
+ }
}
return nullptr;
}
-void Director::pause(bool pause) {
- for (uint i = 0; i < _sprites.size() ; ++i) {
- _sprites[i]->getDecoder()->pauseVideo(pause);
+void Director::draw() {
+ for (uint i = 0; i < _sprites.size(); ++i) {
+ if (_sprites[i]->getDecoder()->needsUpdate()) {
+ _sprites[i]->getDecoder()->decodeNextFrame();
+ addDirtyRects(_sprites[i]);
+ }
+ }
+
+ if (!_dirtyRects.empty()) {
+ mergeDirtyRects();
+
+ for (uint i = 0; i < _dirtyRects.size(); ++i) {
+ drawRect(_dirtyRects[i]);
+ }
+
+ _dirtyRects.resize(0);
+ _surface.update();
+ }
+ else
+ g_system->updateScreen();
+}
+
+void Director::mergeDirtyRects() {
+ Common::Array<Common::Rect>::iterator rOuter, rInner;
+ for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
+ rInner = rOuter;
+ while (++rInner != _dirtyRects.end()) {
+ if ((*rOuter).intersects(*rInner)) {
+ // These two rectangles overlap, so merge them
+ rOuter->extend(*rInner);
+
+ // remove the inner rect from the list
+ _dirtyRects.erase(rInner);
+
+ // move back to beginning of list
+ rInner = rOuter;
+ }
+ }
}
}
-void Director::saveStage() {
- _savedSprites = _sprites;
- _sprites.clear();
+void Director::addDirtyRects(ActionCEL *sprite) {
+ const Common::Rect spriteRect = sprite->getDecoder()->getRectangle();
+ const Common::List<Common::Rect> *dirtyRects = sprite->getDecoder()->getDirtyRects();
+ if (dirtyRects->size() > 100) {
+ _dirtyRects.push_back(spriteRect);
+ } else {
+ for (Common::List<Common::Rect>::const_iterator it = dirtyRects->begin(); it != dirtyRects->end(); ++it) {
+ Common::Rect dirtyRect = *it;
+ dirtyRect.translate(spriteRect.left, spriteRect.top);
+ _dirtyRects.push_back(dirtyRect);
+ }
+ }
+ sprite->getDecoder()->clearDirtyRects();
}
-void Director::loadStage() {
- assert(_sprites.empty());
- _sprites = _savedSprites;
- _savedSprites.clear();
+void Director::drawRect(const Common::Rect &rect) {
+ _surface.fillRect(rect, 0);
+ for (uint i = 0; i < _sprites.size(); ++i) {
+ const Common::Rect &spriteRect = _sprites[i]->getDecoder()->getRectangle();
+ Common::Rect interRect = rect.findIntersectingRect(spriteRect);
+ if (interRect.isEmpty())
+ continue;
+
+ Common::Rect srcRect(interRect);
+ srcRect.translate(-spriteRect.left, -spriteRect.top);
+ _surface.transBlitFrom(*_sprites[i]->getDecoder()->getCurrentFrame(), srcRect, interRect, _sprites[i]->getDecoder()->getTransparentColourIndex());
+ }
}
}
diff --git a/engines/pink/director.h b/engines/pink/director.h
index 4574305098..4902c54328 100644
--- a/engines/pink/director.h
+++ b/engines/pink/director.h
@@ -27,26 +27,27 @@
#include "common/rect.h"
#include "common/system.h"
+#include "graphics/macgui/macwindowmanager.h"
+#include "graphics/screen.h"
+
namespace Pink {
class Actor;
class ActionCEL;
class ActionSound;
-class CelDecoder;
class Director {
public:
- Director(OSystem *system);
- Actor *getActorByPoint(Common::Point point);
+ Director();
- void draw();
void update();
+ void setPallette(const byte *pallete) { g_system->getPaletteManager()->setPalette(pallete, 0, 256); }
+
void addSprite(ActionCEL *sprite);
void removeSprite(ActionCEL *sprite);
- void setPallette(const byte *pallete);
- void addSound(ActionSound* sound);
+ void addSound(ActionSound* sound) { _sounds.push_back(sound); };
void removeSound(ActionSound* sound);
void clear();
@@ -56,11 +57,22 @@ public:
void saveStage();
void loadStage();
- bool showBounds;
+ Actor *getActorByPoint(const Common::Point point);
+
+ Graphics::MacWindowManager &getWndManager() { return _wndManager; };
+
+ uint32 count = 0;
+ uint32 sum = 0;
private:
- void drawSprite(ActionCEL *sprite);
- OSystem *_system;
+ void draw();
+ void addDirtyRects(ActionCEL *sprite);
+ void mergeDirtyRects();
+ void drawRect(const Common::Rect &rect);
+
+ Graphics::Screen _surface;
+ Graphics::MacWindowManager _wndManager;
+ Common::Array<Common::Rect> _dirtyRects;
Common::Array<ActionCEL *> _sprites;
Common::Array<ActionCEL *> _savedSprites;
Common::Array<ActionSound *> _sounds;
diff --git a/engines/pink/objects/actions/action_cel.cpp b/engines/pink/objects/actions/action_cel.cpp
index e6f262f390..a5f0e1f610 100644
--- a/engines/pink/objects/actions/action_cel.cpp
+++ b/engines/pink/objects/actions/action_cel.cpp
@@ -59,9 +59,8 @@ bool ActionCEL::initPalette(Director *director) {
void ActionCEL::start() {
if (!_decoder)
_decoder = _actor->getPage()->loadCel(_fileName);
- _actor->getPage()->getGame()->getDirector()->addSprite(this);
-
this->onStart();
+ _actor->getPage()->getGame()->getDirector()->addSprite(this);
}
void ActionCEL::end() {
diff --git a/engines/pink/pink.cpp b/engines/pink/pink.cpp
index 53407e6f66..eaeadbcd2e 100644
--- a/engines/pink/pink.cpp
+++ b/engines/pink/pink.cpp
@@ -41,7 +41,7 @@ namespace Pink {
Pink::PinkEngine::PinkEngine(OSystem *system, const ADGameDescription *desc)
: Engine(system), _console(nullptr), _rnd("pink"),
_desc(*desc), _bro(nullptr), _module(nullptr),
- _director(_system), _pdaMgr(this) {
+ _director(), _pdaMgr(this) {
debug("PinkEngine constructed");
DebugMan.addDebugChannel(kPinkDebugGeneral, "general", "General issues");
@@ -117,9 +117,6 @@ Common::Error Pink::PinkEngine::run() {
_actor->onLeftButtonClick(event.mouse);
break;
case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode == Common::KEYCODE_d)
- _director.showBounds = !_director.showBounds;
- else
_actor->onKeyboardButtonClick(event.kbd.keycode);
break;
// don't know why it is used in original
@@ -132,8 +129,7 @@ Common::Error Pink::PinkEngine::run() {
_actor->update();
_director.update();
- _director.draw();
- _system->delayMillis(5);
+ _system->delayMillis(10);
}
return Common::kNoError;