* Expanded docs for the Sprite class
* Added Surface and Screen docs * Small documentation fixes svn-id: r41779
This commit is contained in:
parent
8c3e1b0e8d
commit
f5e39fa61d
6 changed files with 108 additions and 11 deletions
|
@ -42,6 +42,10 @@ Screen::~Screen() {
|
||||||
delete[] _palette;
|
delete[] _palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the first numEntries of palette to zero
|
||||||
|
* @param numEntries The number of entries to set to zero (from start)
|
||||||
|
*/
|
||||||
void Screen::setPaletteEmpty(unsigned int numEntries) {
|
void Screen::setPaletteEmpty(unsigned int numEntries) {
|
||||||
for (unsigned int i = 0; i < 4 * numEntries; ++i) {
|
for (unsigned int i = 0; i < 4 * numEntries; ++i) {
|
||||||
_palette[i] = 0;
|
_palette[i] = 0;
|
||||||
|
@ -51,6 +55,12 @@ void Screen::setPaletteEmpty(unsigned int numEntries) {
|
||||||
copyToScreen();
|
copyToScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets a part of the palette
|
||||||
|
* @param data Pointer to a buffer containing new palette data
|
||||||
|
* start Index of the colour where replacement should start
|
||||||
|
* num Number of colours to replace
|
||||||
|
*/
|
||||||
void Screen::setPalette(byte *data, uint16 start, uint16 num) {
|
void Screen::setPalette(byte *data, uint16 start, uint16 num) {
|
||||||
|
|
||||||
Common::MemoryReadStream pal(data, 3 * kNumColours);
|
Common::MemoryReadStream pal(data, 3 * kNumColours);
|
||||||
|
@ -65,7 +75,7 @@ void Screen::setPalette(byte *data, uint16 start, uint16 num) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Investigate why this is needed
|
// TODO: Investigate why this is needed
|
||||||
// Shift the palette one bit to the left to make it brighter
|
// Shift the palette two bits to the left to make it brighter
|
||||||
for (unsigned int i = 0; i < 4 * kNumColours; ++i) {
|
for (unsigned int i = 0; i < 4 * kNumColours; ++i) {
|
||||||
_palette[i] <<= 2;
|
_palette[i] <<= 2;
|
||||||
}
|
}
|
||||||
|
@ -74,17 +84,26 @@ void Screen::setPalette(byte *data, uint16 start, uint16 num) {
|
||||||
copyToScreen();
|
copyToScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copies the current memory screen buffer to the real screen
|
||||||
|
*/
|
||||||
void Screen::copyToScreen() const {
|
void Screen::copyToScreen() const {
|
||||||
Common::List<Common::Rect> *dirtyRects = _surface->getDirtyRects();
|
Common::List<Common::Rect> *dirtyRects = _surface->getDirtyRects();
|
||||||
Common::List<Common::Rect>::iterator it;
|
Common::List<Common::Rect>::iterator it;
|
||||||
|
|
||||||
|
// If a full update is needed, update the whole screen
|
||||||
if (_surface->needsFullUpdate()) {
|
if (_surface->needsFullUpdate()) {
|
||||||
byte *ptr = (byte *)_surface->getBasePtr(0, 0);
|
byte *ptr = (byte *)_surface->getBasePtr(0, 0);
|
||||||
|
|
||||||
_vm->_system->copyRectToScreen(ptr, kScreenWidth,
|
_vm->_system->copyRectToScreen(ptr, kScreenWidth,
|
||||||
0, 0, kScreenWidth, kScreenHeight);
|
0, 0, kScreenWidth, kScreenHeight);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Otherwise, update only the dirty rectangles
|
||||||
|
|
||||||
for (it = dirtyRects->begin(); it != dirtyRects->end(); ++it) {
|
for (it = dirtyRects->begin(); it != dirtyRects->end(); ++it) {
|
||||||
|
|
||||||
|
// Pointer to the upper left corner of the rectangle
|
||||||
byte *ptr = (byte *)_surface->getBasePtr(it->left, it->top);
|
byte *ptr = (byte *)_surface->getBasePtr(it->left, it->top);
|
||||||
|
|
||||||
_vm->_system->copyRectToScreen(ptr, kScreenWidth,
|
_vm->_system->copyRectToScreen(ptr, kScreenWidth,
|
||||||
|
@ -92,11 +111,16 @@ void Screen::copyToScreen() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call the "real" updateScreen and mark the surface clean
|
||||||
_vm->_system->updateScreen();
|
_vm->_system->updateScreen();
|
||||||
_surface->markClean();
|
_surface->markClean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears the screen
|
||||||
|
*
|
||||||
|
* Clears the screen and marks the whole screen dirty.
|
||||||
|
*/
|
||||||
void Screen::clearScreen() const {
|
void Screen::clearScreen() const {
|
||||||
byte *ptr = (byte *)_surface->getBasePtr(0, 0);
|
byte *ptr = (byte *)_surface->getBasePtr(0, 0);
|
||||||
|
|
||||||
|
@ -105,6 +129,12 @@ void Screen::clearScreen() const {
|
||||||
memset(ptr, 0, kScreenWidth * kScreenHeight);
|
memset(ptr, 0, kScreenWidth * kScreenHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fills the screen with the specified colour
|
||||||
|
* @param colour The colour the screen should be filled with
|
||||||
|
*
|
||||||
|
* Fills the screen with the specified colour and marks the whole screen dirty.
|
||||||
|
*/
|
||||||
void Screen::fillScreen(uint16 colour) const {
|
void Screen::fillScreen(uint16 colour) const {
|
||||||
byte *ptr = (byte *)_surface->getBasePtr(0, 0);
|
byte *ptr = (byte *)_surface->getBasePtr(0, 0);
|
||||||
|
|
||||||
|
@ -113,10 +143,17 @@ void Screen::fillScreen(uint16 colour) const {
|
||||||
memset(ptr, colour, kScreenWidth * kScreenHeight);
|
memset(ptr, colour, kScreenWidth * kScreenHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draws a rectangle on the screen
|
||||||
|
* @param r Which rectangle to draw
|
||||||
|
* colour The colour of the rectangle
|
||||||
|
*/
|
||||||
void Screen::drawRect(Common::Rect &r, uint8 colour) {
|
void Screen::drawRect(Common::Rect &r, uint8 colour) {
|
||||||
|
|
||||||
|
// Clip the rectangle to screen size
|
||||||
r.clip(_surface->w, _surface->h);
|
r.clip(_surface->w, _surface->h);
|
||||||
|
|
||||||
|
// If the whole rectangle is outside the screen, return
|
||||||
if (r.isEmpty())
|
if (r.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -131,10 +168,18 @@ void Screen::drawRect(Common::Rect &r, uint8 colour) {
|
||||||
_surface->markDirtyRect(r);
|
_surface->markDirtyRect(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fetches the current palette
|
||||||
|
* @return A byte pointer to the current palette
|
||||||
|
*/
|
||||||
byte *Screen::getPalette() const {
|
byte *Screen::getPalette() const {
|
||||||
return _palette;
|
return _palette;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fetches the current surface
|
||||||
|
* @return A pointer to the current surface
|
||||||
|
*/
|
||||||
Draci::Surface *Screen::getSurface() {
|
Draci::Surface *Screen::getSurface() {
|
||||||
return _surface;
|
return _surface;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,9 @@ Sprite::Sprite(byte *raw_data, uint16 width, uint16 height, uint16 x, uint16 y,
|
||||||
|
|
||||||
_data = new byte[width * height];
|
_data = new byte[width * height];
|
||||||
|
|
||||||
|
// If the sprite is stored row-wise, just copy it to the internal buffer.
|
||||||
|
// Otherwise, transform it and then copy.
|
||||||
|
|
||||||
if (!columnwise) {
|
if (!columnwise) {
|
||||||
memcpy(_data, raw_data, width * height);
|
memcpy(_data, raw_data, width * height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -63,6 +66,9 @@ Sprite::Sprite(byte *sprite_data, uint16 length, uint16 x, uint16 y,
|
||||||
|
|
||||||
_data = new byte[_width * _height];
|
_data = new byte[_width * _height];
|
||||||
|
|
||||||
|
// If the sprite is stored row-wise, just copy it to the internal buffer.
|
||||||
|
// Otherwise, transform it and then copy.
|
||||||
|
|
||||||
if (!columnwise) {
|
if (!columnwise) {
|
||||||
reader.read(_data, _width * _height);
|
reader.read(_data, _width * _height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,12 +84,21 @@ Sprite::~Sprite() {
|
||||||
delete[] _data;
|
delete[] _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draws the sprite to a Draci::Surface
|
||||||
|
* @param surface Pointer to a Draci::Surface
|
||||||
|
*
|
||||||
|
* Draws the sprite to a Draci::Surface and marks its rectangle on the surface as dirty.
|
||||||
|
*/
|
||||||
void Sprite::draw(Surface *surface) const {
|
void Sprite::draw(Surface *surface) const {
|
||||||
byte *dst = (byte *)surface->getBasePtr(_x, _y);
|
byte *dst = (byte *)surface->getBasePtr(_x, _y);
|
||||||
byte *src = _data;
|
byte *src = _data;
|
||||||
|
|
||||||
|
// Blit the sprite to the surface
|
||||||
for (unsigned int i = 0; i < _height; ++i) {
|
for (unsigned int i = 0; i < _height; ++i) {
|
||||||
for(unsigned int j = 0; j < _width; ++j, ++src) {
|
for(unsigned int j = 0; j < _width; ++j, ++src) {
|
||||||
|
|
||||||
|
// Don't blit if the pixel is transparent on the target surface
|
||||||
if (*src != surface->getTransparentColour())
|
if (*src != surface->getTransparentColour())
|
||||||
dst[j] = *src;
|
dst[j] = *src;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +106,7 @@ void Sprite::draw(Surface *surface) const {
|
||||||
dst += surface->pitch;
|
dst += surface->pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mark the sprite's rectangle dirty
|
||||||
Common::Rect r(_x, _y, _x + _width, _y + _height);
|
Common::Rect r(_x, _y, _x + _width, _y + _height);
|
||||||
surface->markDirtyRect(r);
|
surface->markDirtyRect(r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,10 +56,10 @@ public:
|
||||||
|
|
||||||
void draw(Surface *surface) const;
|
void draw(Surface *surface) const;
|
||||||
|
|
||||||
byte *_data;
|
byte *_data; //!< Pointer to a buffer containing raw sprite data (row-wise)
|
||||||
uint16 _width;
|
uint16 _width; //!< Width of the sprite
|
||||||
uint16 _height;
|
uint16 _height; //!< Height of the sprite
|
||||||
uint16 _x, _y;
|
uint16 _x, _y; //!< Sprite coordinates
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,10 @@ Surface::~Surface() {
|
||||||
this->free();
|
this->free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks a dirty rectangle on the surface
|
||||||
|
* @param r The rectangle to be marked dirty
|
||||||
|
*/
|
||||||
void Surface::markDirtyRect(Common::Rect r) {
|
void Surface::markDirtyRect(Common::Rect r) {
|
||||||
Common::List<Common::Rect>::iterator it;
|
Common::List<Common::Rect>::iterator it;
|
||||||
|
|
||||||
|
@ -61,31 +65,54 @@ void Surface::markDirtyRect(Common::Rect r) {
|
||||||
_dirtyRects.push_back(r);
|
_dirtyRects.push_back(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clears all dirty rectangles
|
||||||
|
*
|
||||||
|
*/
|
||||||
void Surface::clearDirtyRects() {
|
void Surface::clearDirtyRects() {
|
||||||
_dirtyRects.clear();
|
_dirtyRects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the whole surface dirty
|
||||||
|
*/
|
||||||
void Surface::markDirty() {
|
void Surface::markDirty() {
|
||||||
_fullUpdate = true;
|
_fullUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Marks the whole surface clean
|
||||||
|
*/
|
||||||
void Surface::markClean() {
|
void Surface::markClean() {
|
||||||
_fullUpdate = false;
|
_fullUpdate = false;
|
||||||
_dirtyRects.clear();
|
_dirtyRects.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks whether the surface needs a full update
|
||||||
|
*/
|
||||||
bool Surface::needsFullUpdate() {
|
bool Surface::needsFullUpdate() {
|
||||||
return _fullUpdate;
|
return _fullUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fetches the surface's dirty rectangles
|
||||||
|
* @return A pointer a list of dirty rectangles
|
||||||
|
*/
|
||||||
Common::List<Common::Rect> *Surface::getDirtyRects() {
|
Common::List<Common::Rect> *Surface::getDirtyRects() {
|
||||||
return &_dirtyRects;
|
return &_dirtyRects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the current transparent colour of the surface
|
||||||
|
*/
|
||||||
uint8 Surface::getTransparentColour() {
|
uint8 Surface::getTransparentColour() {
|
||||||
return _transparentColour;
|
return _transparentColour;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sets the surface's transparent colour
|
||||||
|
*/
|
||||||
void Surface::setTransparentColour(uint8 colour) {
|
void Surface::setTransparentColour(uint8 colour) {
|
||||||
_transparentColour = colour;
|
_transparentColour = colour;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,18 @@ public:
|
||||||
void setTransparentColour(uint8 colour);
|
void setTransparentColour(uint8 colour);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _fullUpdate;
|
/** The current transparent colour of the surface. See getTransparentColour() and
|
||||||
|
* setTransparentColour().
|
||||||
|
*/
|
||||||
uint8 _transparentColour;
|
uint8 _transparentColour;
|
||||||
Common::List<Common::Rect> _dirtyRects;
|
|
||||||
|
/** Set when the surface is scheduled for a full update.
|
||||||
|
* See markDirty(), markClean(). Accessed via needsFullUpdate().
|
||||||
|
*/
|
||||||
|
bool _fullUpdate;
|
||||||
|
|
||||||
|
Common::List<Common::Rect> _dirtyRects; //!< List of currently dirty rectangles
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Draci
|
} // End of namespace Draci
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue