ACCESS: Implement routine for scaled drawing of player

This commit is contained in:
Paul Gilbert 2014-08-16 15:47:25 -04:00
parent 5ff004b2d8
commit fa099b8480
3 changed files with 68 additions and 4 deletions

View File

@ -244,6 +244,10 @@ void AccessEngine::plotList1() {
bounds.setHeight(_screen->_scaleTable1[frame->h]);
}
// Make a copy - some of the drawing methods I've adapted need the full
// scaled dimensions on-screen, and handle clipping themselves
Common::Rect destBounds = bounds;
if (_buffer2.clip(bounds)) {
ie._flags |= 1;
} else {
@ -261,7 +265,7 @@ void AccessEngine::plotList1() {
if (ie._flags & 2) {
_buffer2.sPlotB(frame, Common::Point(bounds.left, bounds.top));
} else {
_buffer2.sPlotF(frame, Common::Point(bounds.left, bounds.top));
_buffer2.sPlotF(frame, destBounds);
}
} else {
if (ie._flags & 2) {

View File

@ -82,6 +82,15 @@ SpriteFrame::~SpriteFrame() {
/*------------------------------------------------------------------------*/
ImageEntry::ImageEntry() {
_frameNumber = 0;
_spritesPtr = nullptr;
_priority = 0;
_flags = 0;
}
/*------------------------------------------------------------------------*/
static bool sortImagesY(const ImageEntry &ie1, const ImageEntry &ie2) {
return ie1._priority < ie2._priority;
}
@ -237,12 +246,59 @@ void ASurface::copyTo(ASurface *dest, const Common::Point &destPos) {
}
}
void ASurface::copyTo(ASurface *dest, const Common::Rect &bounds) {
const int SCALE_LIMIT = 0x100;
int scaleX = SCALE_LIMIT * bounds.width() / this->w;
int scaleY = SCALE_LIMIT * bounds.height() / this->h;
int scaleXCtr = 0, scaleYCtr = 0;
int y = bounds.top;
for (int yCtr = 0, y = bounds.top; yCtr < this->h; ++yCtr) {
// Handle skipping lines if Y scaling
scaleYCtr += scaleY;
if (scaleYCtr < SCALE_LIMIT)
continue;
scaleYCtr -= SCALE_LIMIT;
// Handle off-screen lines
if (y < 0)
continue;
else if (y >= dest->h)
break;
// Handle drawing the line
byte *pSrc = (byte *)getBasePtr(0, yCtr);
byte *pDest = (byte *)dest->getBasePtr(bounds.left, y);
scaleXCtr = 0;
int x = bounds.left;
for (int xCtr = 0; xCtr < this->w; ++xCtr, ++pSrc) {
// Handle horizontal scaling
scaleXCtr += scaleX;
if (scaleXCtr < SCALE_LIMIT)
continue;
scaleXCtr -= SCALE_LIMIT;
// Only handle on-scren pixels
if (x >= dest->w)
break;
if (x >= 0 && *pSrc != 0)
*pDest = *pSrc;
++pDest;
++x;
}
++y;
}
}
void ASurface::sPlotB(SpriteFrame *frame, const Common::Point &pt) {
frame->copyTo(this, pt);
}
void ASurface::sPlotF(SpriteFrame *frame, const Common::Point &pt) {
frame->copyTo(this, pt);
void ASurface::sPlotF(SpriteFrame *frame, const Common::Rect &bounds) {
frame->copyTo(this, bounds);
}
void ASurface::plotB(SpriteFrame *frame, const Common::Point &pt) {

View File

@ -60,13 +60,15 @@ public:
void sPlotB(SpriteFrame *frame, const Common::Point &pt);
void sPlotF(SpriteFrame *frame, const Common::Point &pt);
void sPlotF(SpriteFrame *frame, const Common::Rect &bounds);
void plotB(SpriteFrame *frame, const Common::Point &pt);
void copyBlock(ASurface *src, const Common::Rect &bounds);
void copyTo(ASurface *dest, const Common::Point &destPos);
void copyTo(ASurface *dest, const Common::Rect &bounds);
};
class SpriteFrame : public ASurface {
@ -95,6 +97,8 @@ public:
int _priority;
Common::Point _position;
int _flags;
public:
ImageEntry();
};
class ImageEntryList : public Common::Array<ImageEntry> {