[Scummvm-git-logs] scummvm master -> 4a7e8c4fd239abf1aada31eaabf769ade950bc41
mduggan
noreply at scummvm.org
Sun Nov 10 00:00:07 UTC 2024
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
689adf855e DGDS: Add some safeguards on reading compressed data
4a7e8c4fd2 DGDS: Add draw circle TTM opcodes
Commit: 689adf855ec15d2d54aa9daaa76a936e4cbae031
https://github.com/scummvm/scummvm/commit/689adf855ec15d2d54aa9daaa76a936e4cbae031
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-10T10:54:11+11:00
Commit Message:
DGDS: Add some safeguards on reading compressed data
We assumed that SCR data was always the same size as the screen resolution.
Probably true, but corrupted or unexpected data could easily overrun the
buffer.
Also check the return value from decompression and print a warning if the read
size was not as expected.
Changed paths:
engines/dgds/decompress.cpp
engines/dgds/image.cpp
engines/dgds/image.h
engines/dgds/includes.h
diff --git a/engines/dgds/decompress.cpp b/engines/dgds/decompress.cpp
index e7aec5d5ccf..a9aea69f017 100644
--- a/engines/dgds/decompress.cpp
+++ b/engines/dgds/decompress.cpp
@@ -22,6 +22,7 @@
#include "common/debug.h"
#include "common/stream.h"
#include "common/util.h"
+#include "common/textconsole.h"
#include "dgds/decompress.h"
@@ -204,22 +205,32 @@ byte *Decompressor::decompress(Common::SeekableReadStream *input, int size, uint
uncompressedSize = input->readUint32LE();
byte *data = new byte[uncompressedSize];
+ uint32 result = 0;
+ uint32 expectedSize = size;
switch (compression) {
case 0x00:
- input->read(data, size);
+ result = input->read(data, size);
break;
case 0x01:
- _rleDecompressor.decompress(data, uncompressedSize, *input);
+ result = _rleDecompressor.decompress(data, uncompressedSize, *input);
+ expectedSize = uncompressedSize;
break;
case 0x02:
- _lzwDecompressor.decompress(data, uncompressedSize, *input);
+ result = _lzwDecompressor.decompress(data, uncompressedSize, *input);
+ expectedSize = uncompressedSize;
break;
default:
input->skip(size);
- debug("Unknown chunk compression: 0x%x", compression);
+ result = size;
+ warning("Unknown chunk compression: 0x%x", compression);
break;
}
+ if (result != expectedSize) {
+ warning("Loading resource with compression type %d - expected %d bytes, got %d",
+ compression, expectedSize, result);
+ }
+
return data;
}
diff --git a/engines/dgds/image.cpp b/engines/dgds/image.cpp
index 4fcad07af39..535224dea59 100644
--- a/engines/dgds/image.cpp
+++ b/engines/dgds/image.cpp
@@ -73,18 +73,34 @@ void Image::drawScreen(const Common::String &filename, Graphics::ManagedSurface
_filename = filename;
- surface.fillRect(Common::Rect(SCREEN_WIDTH, SCREEN_HEIGHT), 0);
+ surface.fillRect(Common::Rect(surface.w, surface.h), 0);
+
+ uint16 xsize = surface.w;
+ uint16 ysize = surface.h;
DgdsChunkReader chunk(fileStream);
while (chunk.readNextHeader(ex, filename)) {
+ if (chunk.isContainer()) {
+ continue;
+ }
+
chunk.readContent(_decompressor);
Common::SeekableReadStream *stream = chunk.getContent();
if (chunk.isSection(ID_BIN)) {
- loadBitmap4(&surface, 0, stream, false);
+ loadBitmap4(&surface, 0, stream, false, xsize, ysize);
+ } else if (chunk.isSection(ID_DIM)) {
+ xsize = stream->readUint16LE();
+ ysize = stream->readUint16LE();
+ if (xsize > surface.w || ysize > surface.h) {
+ error("Trying to load SCR size %d x %d which is larger than screen %d x %d",
+ xsize, ysize, surface.w, surface.h);
+ }
+ debug("screen file %s dims %d x %d into surface %d x %d",
+ filename.c_str(), xsize, ysize, surface.w, surface.h);
} else if (chunk.isSection(ID_VGA)) {
- loadBitmap4(&surface, 0, stream, true);
+ loadBitmap4(&surface, 0, stream, true, xsize, ysize);
} else if (chunk.isSection(ID_MA8)) {
- loadBitmap8(&surface, 0, stream);
+ loadBitmap8(&surface, 0, stream, xsize, ysize);
} else if (chunk.isSection(ID_VQT)) {
loadVQT(&surface, 0, stream);
}
@@ -101,6 +117,10 @@ int Image::frameCount(const Common::String &filename) {
int tileCount = -1;
DgdsChunkReader chunk(fileStream);
while (chunk.readNextHeader(EX_BMP, filename)) {
+ if (chunk.isContainer()) {
+ continue;
+ }
+
chunk.readContent(_decompressor);
Common::SeekableReadStream *stream = chunk.getContent();
if (chunk.isSection(ID_INF)) {
@@ -138,6 +158,10 @@ void Image::loadBitmap(const Common::String &filename) {
DgdsChunkReader chunk(fileStream);
while (chunk.readNextHeader(ex, filename)) {
+ if (chunk.isContainer()) {
+ continue;
+ }
+
chunk.readContent(_decompressor);
Common::SeekableReadStream *stream = chunk.getContent();
if (chunk.isSection(ID_INF)) {
@@ -172,11 +196,11 @@ void Image::loadBitmap(const Common::String &filename) {
}
} else if (chunk.isSection(ID_BIN)) {
for (auto & frame : _frames) {
- loadBitmap4(frame.get(), 0, stream, false);
+ loadBitmap4(frame.get(), 0, stream, false, frame->w, frame->h);
}
} else if (chunk.isSection(ID_VGA)) {
for (auto & frame : _frames) {
- loadBitmap4(frame.get(), 0, stream, true);
+ loadBitmap4(frame.get(), 0, stream, true, frame->w, frame->h);
}
} else if (chunk.isSection(ID_VQT)) {
// Postpone parsing this until we have the offsets, which come after.
@@ -321,33 +345,28 @@ void Image::drawScrollBitmap(int16 x, int16 y, int16 width, int16 height, int16
}
-void Image::loadBitmap4(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream, bool highByte) {
- uint32 tw = surf->w;
- uint32 th = surf->h;
+void Image::loadBitmap4(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream, bool highByte, uint16 tw, uint16 th) {
assert(th != 0);
byte *data = (byte *)surf->getPixels();
- byte buf;
stream->skip(toffset >> 1);
if (highByte) {
for (uint i = 0; i < tw * th; i += 2) {
- buf = stream->readByte();
- data[i + 0] |= buf & 0xF0;
- data[i + 1] |= (buf & 0x0F) << 4;
+ byte val = stream->readByte();
+ data[i + 0] |= val & 0xF0;
+ data[i + 1] |= (val & 0x0F) << 4;
}
} else {
for (uint i = 0; i < tw * th; i += 2) {
- buf = stream->readByte();
- data[i + 0] |= (buf & 0xF0) >> 4;
- data[i + 1] |= buf & 0x0F;
+ byte val = stream->readByte();
+ data[i + 0] |= (val & 0xF0) >> 4;
+ data[i + 1] |= val & 0x0F;
}
}
}
-void Image::loadBitmap8(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream) {
- uint32 tw = surf->w;
- uint32 th = surf->h;
+void Image::loadBitmap8(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream, uint16 tw, uint16 th) {
assert(th != 0);
byte *data = (byte *)surf->getPixels();
diff --git a/engines/dgds/image.h b/engines/dgds/image.h
index ea33653e106..3cab5979d7a 100644
--- a/engines/dgds/image.h
+++ b/engines/dgds/image.h
@@ -73,8 +73,8 @@ public:
const Common::String &getFilename() const { return _filename; }
private:
- void loadBitmap4(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream, bool highByte);
- void loadBitmap8(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream);
+ void loadBitmap4(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream, bool highByte, uint16 width, uint16 height);
+ void loadBitmap8(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream, uint16 width, uint16 height);
uint32 loadVQT(Graphics::ManagedSurface *surf, uint32 toffset, Common::SeekableReadStream *stream);
bool loadSCN(Graphics::ManagedSurface *surf, Common::SeekableReadStream *stream);
diff --git a/engines/dgds/includes.h b/engines/dgds/includes.h
index 607cc6676d3..9a45f67dcf4 100644
--- a/engines/dgds/includes.h
+++ b/engines/dgds/includes.h
@@ -29,6 +29,7 @@ namespace Dgds {
#define ID_BIN MKTAG24('B', 'I', 'N')
#define ID_CGA MKTAG24('C', 'G', 'A')
#define ID_DAT MKTAG24('D', 'A', 'T')
+#define ID_DIM MKTAG24('D', 'I', 'M')
#define ID_EGA MKTAG24('E', 'G', 'A')
#define ID_FNM MKTAG24('F', 'N', 'M')
#define ID_FNT MKTAG24('F', 'N', 'T')
Commit: 4a7e8c4fd239abf1aada31eaabf769ade950bc41
https://github.com/scummvm/scummvm/commit/4a7e8c4fd239abf1aada31eaabf769ade950bc41
Author: Matthew Duggan (mgithub at guarana.org)
Date: 2024-11-10T10:54:11+11:00
Commit Message:
DGDS: Add draw circle TTM opcodes
Maybe not used anywhere but Johnny Castaway, but implementation is simple as we
already have the code.
Changed paths:
engines/dgds/ttm.cpp
diff --git a/engines/dgds/ttm.cpp b/engines/dgds/ttm.cpp
index b51e47f163a..9c11632b643 100644
--- a/engines/dgds/ttm.cpp
+++ b/engines/dgds/ttm.cpp
@@ -34,7 +34,7 @@
#include "dgds/sound.h"
#include "dgds/font.h"
#include "dgds/sound_raw.h"
-
+#include "dgds/drawing.h"
namespace Dgds {
@@ -908,6 +908,19 @@ void TTMInterpreter::handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byt
case 0xa300:
doDrawDialogForStrings(env, seq, ivals[0], ivals[1], ivals[2], ivals[3]);
break;
+
+ case 0xa400: { // DRAW FILLED CIRCLE
+ int16 xr = ivals[2] / 2;
+ int16 yr = ivals[3] / 2;
+ Drawing::filledCircle(ivals[0] + xr, ivals[1] + yr, xr, yr, &_vm->_compositionBuffer, seq._drawColFG, seq._drawColBG);
+ break;
+ }
+ case 0xa420: { // DRAW EMPTY CIRCLE
+ int16 xr = ivals[2] / 2;
+ int16 yr = ivals[3] / 2;
+ Drawing::emptyCircle(ivals[0] + xr, ivals[1] + yr, xr, yr, &_vm->_compositionBuffer, seq._drawColFG);
+ break;
+ }
case 0xa500: // DRAW SPRITE: x,y,tile-id,bmp-id:int [-n,+n]
case 0xa510: // DRAW SPRITE FLIP V x,y:int
case 0xa520: // DRAW SPRITE FLIP H: x,y:int
More information about the Scummvm-git-logs
mailing list