SAGA2: Made sprite unpacking more robust

This commit is contained in:
Eugene Sandulenko 2021-06-20 14:24:44 +02:00
parent 9fa23205d6
commit 9b76670b45
No known key found for this signature in database
GPG Key ID: 014D387312D34F08
4 changed files with 40 additions and 35 deletions

View File

@ -25,6 +25,7 @@
*/
#include "common/debug.h"
#include "common/memstream.h"
#include "graphics/surface.h"
#include "saga2/std.h"
@ -104,12 +105,25 @@ void unpackImage(gPixelMap *map, int32 width, int32 rowCount, int8 *srcData) {
unpackImage(*map, (int16)width, (int16)rowCount, srcData);
}
void unpackSprite(gPixelMap *map, uint8 *sprData) {
void unpackSprite(gPixelMap *map, uint8 *sprData, uint32 dataSize) {
byte *dst = map->data;
int bytes = map->size.x * map->size.y;
if (!sprData) {
warning("unpackSprite(): empty sprData");
return;
}
Common::MemoryReadStream stream(sprData, dataSize);
while (true) {
byte trans = *sprData++;
byte trans = stream.readByte();
if (stream.eos()) {
warning("unpackSprite: premature end of data");
return;
}
if (bytes < trans) {
warning("unpackSprite: too many trans %d < %d", bytes, trans);
trans = bytes;
@ -122,15 +136,25 @@ void unpackSprite(gPixelMap *map, uint8 *sprData) {
if (bytes < 0)
break;
byte fill = *sprData++;
byte fill = stream.readByte();
if (stream.eos()) {
warning("unpackSprite: premature end of data");
return;
}
if (bytes < fill) {
warning("unpackSprite: too many bytes %d < %d", bytes, fill);
fill = bytes;
}
memcpy(dst, sprData, fill);
if (stream.read(dst, fill) != fill) {
warning("unpackSprite: premature end of data");
return;
}
dst += fill;
bytes -= fill;
sprData += fill;
if (bytes <= 0)
break;
}
}

View File

@ -42,7 +42,7 @@ void _HLine(uint8 *dstPtr, uint32 width, uint32 color);
void unpackImage(gPixelMap *map, int32 width, int32 rowCount, int8 *srcData);
void unpackImage(gPixelMap &map, int16 width, int16 rowCount, int8 *srcData);
void unpackSprite(gPixelMap *map, uint8 *sprData);
void unpackSprite(gPixelMap *map, uint8 *sprData, uint32 dataSize);
void compositePixels(gPixelMap *compMap, gPixelMap *sprMap, int32 xpos, int32 ypos, uint8 *lookup);
void compositePixelsRvs(gPixelMap *compMap, gPixelMap *sprMap, int32 xpos, int32 ypos, uint8 *lookup);

View File

@ -44,26 +44,6 @@ const uint32 spriteGroupID = MKTAG('S', 'P', 'R', 'I'),
weaponSpriteBaseID = MKTAG('W', 'P', 'N', 0),
missileSpriteID = MKTAG('M', 'I', 'S', 'S');
/* ===================================================================== *
Prototypes
* ===================================================================== */
#ifndef FTAASM_H
extern void unpackSprite(gPixelMap *map, uint8 *sprData);
extern void compositePixels(
gPixelMap *compMap,
gPixelMap *sprMap,
int32 xpos,
int32 ypos,
uint8 *lookup);
extern void compositePixelsRvs(
gPixelMap *compMap,
gPixelMap *sprMap,
int32 xpos,
int32 ypos,
uint8 *lookup);
#endif
extern uint16 rippedRoofID;
extern void drawTileMask(
const Point16 &sPos,
@ -250,7 +230,7 @@ void DrawCompositeMaskedSprite(
// Unpack the sprite into the temp map
unpackSprite(&sprMap, sp->_data);
unpackSprite(&sprMap, sp->_data, sp->_dataSize);
// Blit the temp map onto the composite map
@ -361,7 +341,7 @@ void DrawSprite(
sprMap.data = (uint8 *)getQuickMem(sprMap.bytes());
// Unpack the sprite into the temp map
unpackSprite(&sprMap, sp->_data);
unpackSprite(&sprMap, sp->_data, sp->_dataSize);
// Blit to the port
port.setMode(drawModeMatte);
@ -391,7 +371,7 @@ void DrawColorMappedSprite(
sprReMap.data = (uint8 *)getQuickMem(sprReMap.bytes());
// Unpack the sprite into the temp map
unpackSprite(&sprMap, sp->_data);
unpackSprite(&sprMap, sp->_data, sp->_dataSize);
memset(sprReMap.data, 0, sprReMap.bytes());
@ -429,7 +409,7 @@ void ExpandColorMappedSprite(
sprMap.data = (uint8 *)getQuickMem(sprMap.bytes());
// Unpack the sprite into the temp map
unpackSprite(&sprMap, sp->_data);
unpackSprite(&sprMap, sp->_data, sp->_dataSize);
// remap the sprite to the color table given
compositePixels(
@ -458,7 +438,7 @@ uint8 GetSpritePixel(
sprMap.data = (uint8 *)getQuickMem(sprMap.bytes());
// Unpack the sprite into the temp map
unpackSprite(&sprMap, sp->_data);
unpackSprite(&sprMap, sp->_data, sp->_dataSize);
// Map the coords to the bitmap and return the pixel
if (flipped) {
@ -513,7 +493,7 @@ uint16 visiblePixelsInSprite(
sprMap.size = sp->size;
sprMap.data = (uint8 *)getQuickMem(sprMap.bytes());
unpackSprite(&sprMap, sp->_data);
unpackSprite(&sprMap, sp->_data, sp->_dataSize);
org.x = drawPos.x - xMin;
org.y = drawPos.y - yMin;
@ -795,9 +775,9 @@ Sprite::Sprite(Common::SeekableReadStream *stream) {
size.load(stream);
offset.load(stream);
int data_size = size.x * size.y;
_data = (byte *)malloc(data_size * sizeof(byte));
stream->read(_data, data_size);
_dataSize = size.x * size.y;
_data = (byte *)malloc(_dataSize);
stream->read(_data, _dataSize);
}
Sprite::~Sprite() {

View File

@ -50,6 +50,7 @@ struct Sprite {
Extent16 size; // size of sprite
Point16 offset; // sprite origin point
byte *_data;
uint32 _dataSize;
Sprite(Common::SeekableReadStream *stream);
~Sprite();