mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 13:50:13 +00:00
PINK: change drawing method
This commit is contained in:
parent
4dd40b0f7b
commit
bfd1b62063
@ -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();
|
||||
draw();
|
||||
|
||||
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();
|
||||
times++;
|
||||
if (g_system->getMillis() - time >= 1000) {
|
||||
debug("FPS: %u ", times);
|
||||
sum += times;
|
||||
count++;
|
||||
time = g_system->getMillis();
|
||||
times = 0;
|
||||
}
|
||||
else
|
||||
_system->copyRectToScreen(surface->getPixels(), surface->pitch,
|
||||
decoder->getX(), decoder->getY(),
|
||||
w, h);
|
||||
|
||||
}
|
||||
|
||||
|
||||
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,23 +77,7 @@ void Director::removeSprite(ActionCEL *sprite) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Director::setPallette(const byte *pallete) {
|
||||
_system->getPaletteManager()->setPalette(pallete, 0, 256);
|
||||
}
|
||||
|
||||
void Director::update() {
|
||||
for (uint i = 0; i < _sounds.size(); ++i) {
|
||||
_sounds[i]->update();
|
||||
}
|
||||
for (uint i = 0; i < _sprites.size(); ++i) {
|
||||
_sprites[i]->update();
|
||||
}
|
||||
}
|
||||
|
||||
void Director::addSound(ActionSound *sound) {
|
||||
_sounds.push_back(sound);
|
||||
_dirtyRects.push_back(sprite->getDecoder()->getRectangle());
|
||||
}
|
||||
|
||||
void Director::removeSound(ActionSound *sound) {
|
||||
@ -122,26 +88,13 @@ void Director::removeSound(ActionSound *sound) {
|
||||
}
|
||||
|
||||
void Director::clear() {
|
||||
_sprites.clear();
|
||||
}
|
||||
|
||||
Actor *Director::getActorByPoint(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())
|
||||
return _sprites[i]->getActor();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
|
||||
_sprites.resize(0);
|
||||
}
|
||||
|
||||
void Director::pause(bool pause) {
|
||||
for (uint i = 0; i < _sprites.size() ; ++i) {
|
||||
_sprites[i]->getDecoder()->pauseVideo(pause);
|
||||
_sprites[i]->pause(pause);
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,4 +109,88 @@ void Director::loadStage() {
|
||||
_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();
|
||||
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::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::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::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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user