[Scummvm-git-logs] scummvm master -> 56206fef9f57567248c2c926659cbc4ec1535095
waltervn
walter at vanniftrik-it.nl
Sun Mar 5 21:50:21 CET 2017
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e97973a930 ADL: Skip deleted files when reading VTOC
6bd7ca75f9 ADL: Move shape drawing into base gfx class
c88d30d8d3 ADL: Allow smaller delays
19b07a7c12 ADL: Move multi-disk handling into v2
33c8073bc2 ADL: Make framebuffer loader static
494682de90 ADL: Add byte-access functions to Display class
3beb48f5ce ADL: Fix error() when opening GMM during intro
56206fef9f ADL: Implement hires4 intro (1986 re-release)
Commit: e97973a9307941b7accee46ba420e74d3b28c7f6
https://github.com/scummvm/scummvm/commit/e97973a9307941b7accee46ba420e74d3b28c7f6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:57+01:00
Commit Message:
ADL: Skip deleted files when reading VTOC
Changed paths:
engines/adl/disk.cpp
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 133c655..2c1fe8e 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -406,7 +406,8 @@ void Files_DOS33::readVTOC() {
entry.totalSectors = stream->readUint16BE();
- if (sectorList.track != 0) {
+ // 0 is empty slot, 255 is deleted file
+ if (sectorList.track != 0 && sectorList.track != 255) {
readSectorList(sectorList, entry.sectors);
_toc[name] = entry;
}
Commit: 6bd7ca75f9ed6510b1a6efa82157e02364c65e50
https://github.com/scummvm/scummvm/commit/6bd7ca75f9ed6510b1a6efa82157e02364c65e50
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:57+01:00
Commit Message:
ADL: Move shape drawing into base gfx class
Changed paths:
engines/adl/adl.h
engines/adl/graphics.cpp
engines/adl/graphics.h
engines/adl/hires0.cpp
engines/adl/hires1.cpp
engines/adl/hires2.cpp
engines/adl/hires4.cpp
engines/adl/hires5.cpp
engines/adl/hires6.cpp
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 75c6485..7076ab2 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -148,14 +148,14 @@ struct Item {
byte region;
byte room;
byte picture;
- bool isLineArt;
+ bool isShape;
Common::Point position;
int state;
byte description;
Common::Array<byte> roomPictures;
bool isOnScreen;
- Item() : id(0), noun(0), region(0), room(0), picture(0), isLineArt(false), state(0), description(0), isOnScreen(false) { }
+ Item() : id(0), noun(0), region(0), room(0), picture(0), isShape(false), state(0), description(0), isOnScreen(false) { }
};
struct Time {
diff --git a/engines/adl/graphics.cpp b/engines/adl/graphics.cpp
index cf90665..0f80bac 100644
--- a/engines/adl/graphics.cpp
+++ b/engines/adl/graphics.cpp
@@ -77,44 +77,7 @@ void GraphicsMan::putPixel(const Common::Point &p, byte color) const {
_display.putPixel(p, color);
}
-void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
- byte x, y;
- bool bNewLine = false;
- byte oldX = 0, oldY = 0;
- while (1) {
- x = pic.readByte();
- y = pic.readByte();
-
- if (pic.err() || pic.eos())
- error("Error reading picture");
-
- if (x == 0xff && y == 0xff)
- return;
-
- if (x == 0 && y == 0) {
- bNewLine = true;
- continue;
- }
-
- x += pos.x;
- y += pos.y;
-
- if (y > 160)
- y = 160;
-
- if (bNewLine) {
- putPixel(Common::Point(x, y), 0x7f);
- bNewLine = false;
- } else {
- drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
- }
-
- oldX = x;
- oldY = y;
- }
-}
-
-void Graphics_v1::drawCornerPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
+void GraphicsMan::drawShapePixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
if (bits & 4)
putPixel(p, color);
@@ -126,7 +89,7 @@ void Graphics_v1::drawCornerPixel(Common::Point &p, byte color, byte bits, byte
p.y += (bits & 2 ? 1 : -1);
}
-void Graphics_v1::drawCorners(Common::ReadStream &corners, const Common::Point &pos, byte rotation, byte scaling, byte color) const {
+void GraphicsMan::drawShape(Common::ReadStream &corners, Common::Point &pos, byte rotation, byte scaling, byte color) const {
const byte stepping[] = {
0xff, 0xfe, 0xfa, 0xf4, 0xec, 0xe1, 0xd4, 0xc5,
0xb4, 0xa1, 0x8d, 0x78, 0x61, 0x49, 0x31, 0x18,
@@ -138,8 +101,6 @@ void Graphics_v1::drawCorners(Common::ReadStream &corners, const Common::Point &
byte xStep = stepping[rotation];
byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
- Common::Point p(pos);
-
while (true) {
byte b = corners.readByte();
@@ -154,10 +115,10 @@ void Graphics_v1::drawCorners(Common::ReadStream &corners, const Common::Point &
byte yFrac = 0x80;
for (uint j = 0; j < scaling; ++j) {
if (xFrac + xStep + 1 > 255)
- drawCornerPixel(p, color, b, quadrant);
+ drawShapePixel(pos, color, b, quadrant);
xFrac += xStep + 1;
if (yFrac + yStep > 255)
- drawCornerPixel(p, color, b, quadrant + 1);
+ drawShapePixel(pos, color, b, quadrant + 1);
yFrac += yStep;
}
b >>= 3;
@@ -165,6 +126,43 @@ void Graphics_v1::drawCorners(Common::ReadStream &corners, const Common::Point &
}
}
+void GraphicsMan::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
+ byte x, y;
+ bool bNewLine = false;
+ byte oldX = 0, oldY = 0;
+ while (1) {
+ x = pic.readByte();
+ y = pic.readByte();
+
+ if (pic.err() || pic.eos())
+ error("Error reading picture");
+
+ if (x == 0xff && y == 0xff)
+ return;
+
+ if (x == 0 && y == 0) {
+ bNewLine = true;
+ continue;
+ }
+
+ x += pos.x;
+ y += pos.y;
+
+ if (y > 160)
+ y = 160;
+
+ if (bNewLine) {
+ putPixel(Common::Point(x, y), 0x7f);
+ bNewLine = false;
+ } else {
+ drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
+ }
+
+ oldX = x;
+ oldY = y;
+ }
+}
+
#define NUM_PATTERNS 22
#define PATTERN_LEN 4
static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
@@ -219,7 +217,7 @@ static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
p.y += _offset.y; \
} while (0)
-void Graphics_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+void GraphicsMan_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
Common::Point p;
READ_POINT(p);
@@ -253,7 +251,7 @@ doYStep:
}
}
-void Graphics_v2::drawRelativeLines(Common::SeekableReadStream &pic) {
+void GraphicsMan_v2::drawRelativeLines(Common::SeekableReadStream &pic) {
Common::Point p1;
READ_POINT(p1);
@@ -283,7 +281,7 @@ void Graphics_v2::drawRelativeLines(Common::SeekableReadStream &pic) {
}
}
-void Graphics_v2::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+void GraphicsMan_v2::drawAbsoluteLines(Common::SeekableReadStream &pic) {
Common::Point p1;
READ_POINT(p1);
@@ -308,11 +306,11 @@ static byte getPatternColor(const Common::Point &p, byte pattern) {
return fillPatterns[pattern][offset % PATTERN_LEN];
}
-bool Graphics_v2::canFillAt(const Common::Point &p, const bool stopBit) {
+bool GraphicsMan_v2::canFillAt(const Common::Point &p, const bool stopBit) {
return _display.getPixelBit(p) != stopBit && _display.getPixelBit(Common::Point(p.x + 1, p.y)) != stopBit;
}
-void Graphics_v2::fillRowLeft(Common::Point p, const byte pattern, const bool stopBit) {
+void GraphicsMan_v2::fillRowLeft(Common::Point p, const byte pattern, const bool stopBit) {
byte color = getPatternColor(p, pattern);
while (--p.x >= _bounds.left) {
@@ -326,7 +324,7 @@ void Graphics_v2::fillRowLeft(Common::Point p, const byte pattern, const bool st
}
}
-void Graphics_v2::fillRow(Common::Point p, const byte pattern, const bool stopBit) {
+void GraphicsMan_v2::fillRow(Common::Point p, const byte pattern, const bool stopBit) {
// Set pixel at p and palette
byte color = getPatternColor(p, pattern);
_display.setPixelPalette(p, color);
@@ -348,7 +346,7 @@ void Graphics_v2::fillRow(Common::Point p, const byte pattern, const bool stopBi
}
}
-void Graphics_v2::fillAt(Common::Point p, const byte pattern) {
+void GraphicsMan_v2::fillAt(Common::Point p, const byte pattern) {
const bool stopBit = !_display.getPixelBit(p);
// Move up into the open space above p
@@ -359,7 +357,7 @@ void Graphics_v2::fillAt(Common::Point p, const byte pattern) {
fillRow(p, pattern, stopBit);
}
-void Graphics_v2::fill(Common::SeekableReadStream &pic) {
+void GraphicsMan_v2::fill(Common::SeekableReadStream &pic) {
byte pattern;
READ_BYTE(pattern);
@@ -372,7 +370,7 @@ void Graphics_v2::fill(Common::SeekableReadStream &pic) {
}
}
-void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
+void GraphicsMan_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
// NOTE: The original engine only resets the color for overlays. As a result, room
// pictures that draw without setting a color or clearing the screen, will use the
// last color set by the previous picture. We assume this is unintentional and do
@@ -441,7 +439,7 @@ void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &
}
}
-void Graphics_v3::fillRowLeft(Common::Point p, const byte pattern, const bool stopBit) {
+void GraphicsMan_v3::fillRowLeft(Common::Point p, const byte pattern, const bool stopBit) {
byte color = getPatternColor(p, pattern);
while (--p.x >= _bounds.left) {
@@ -456,7 +454,7 @@ void Graphics_v3::fillRowLeft(Common::Point p, const byte pattern, const bool st
}
}
-void Graphics_v3::fillAt(Common::Point p, const byte pattern) {
+void GraphicsMan_v3::fillAt(Common::Point p, const byte pattern) {
// If the row at p cannot be filled, we do nothing
if (!canFillAt(p))
return;
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index c0d1780..38dc2b2 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef ADL_PICTURE_H
-#define ADL_PICTURE_H
+#ifndef ADL_GRAPHICS_H
+#define ADL_GRAPHICS_H
#include "common/rect.h"
@@ -33,40 +33,35 @@ namespace Adl {
class Display;
+// Used in hires1
class GraphicsMan {
public:
+ GraphicsMan(Display &display) : _bounds(280, 160), _display(display) { }
virtual ~GraphicsMan() { }
- virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) = 0;
+
+ // Applesoft BASIC HLINE
+ void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
+ // Applesoft BASIC DRAW
+ void drawShape(Common::ReadStream &shape, Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
+
+ virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos);
void clearScreen() const;
void putPixel(const Common::Point &p, byte color) const;
+ void setBounds(const Common::Rect &r) { _bounds = r; }
protected:
- GraphicsMan(Display &display) : _bounds(280, 160), _display(display) { }
- void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
-
Display &_display;
Common::Rect _bounds;
private:
- virtual byte getClearColor() const = 0;
-};
-
-// Used in hires1
-class Graphics_v1 : public GraphicsMan {
-public:
- Graphics_v1(Display &display) : GraphicsMan(display) { }
- void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos);
- void drawCorners(Common::ReadStream &corners, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
-
-private:
- void drawCornerPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
- byte getClearColor() const { return 0x00; }
+ void drawShapePixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
+ virtual byte getClearColor() const { return 0x00; }
};
// Used in hires0 and hires2-hires4
-class Graphics_v2 : public GraphicsMan {
+class GraphicsMan_v2 : public GraphicsMan {
public:
- Graphics_v2(Display &display) : GraphicsMan(display), _color(0) { }
+ GraphicsMan_v2(Display &display) : GraphicsMan(display), _color(0) { }
void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos);
protected:
@@ -87,9 +82,9 @@ private:
};
// Used in hires5, hires6 and gelfling (possibly others as well)
-class Graphics_v3 : public Graphics_v2 {
+class GraphicsMan_v3 : public GraphicsMan_v2 {
public:
- Graphics_v3(Display &display) : Graphics_v2(display) { }
+ GraphicsMan_v3(Display &display) : GraphicsMan_v2(display) { }
private:
void fillRowLeft(Common::Point p, const byte pattern, const bool stopBit);
diff --git a/engines/adl/hires0.cpp b/engines/adl/hires0.cpp
index 9a0af05..0165170 100644
--- a/engines/adl/hires0.cpp
+++ b/engines/adl/hires0.cpp
@@ -56,7 +56,7 @@ private:
};
void HiRes0Engine::init() {
- _graphics = new Graphics_v2(*_display);
+ _graphics = new GraphicsMan_v2(*_display);
_disk = new DiskImage();
if (!_disk->open(IDS_HR0_DISK_IMAGE))
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 239792d..41436ac 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -83,7 +83,7 @@ namespace Adl {
#define IDI_HR1_OFS_MSGS 0x4d00
#define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
-#define IDI_HR1_OFS_CORNERS 0x4f00
+#define IDI_HR1_OFS_SHAPES 0x4f00
#define IDI_HR1_OFS_VERBS 0x3800
#define IDI_HR1_OFS_NOUNS 0x0f00
@@ -229,7 +229,7 @@ void HiRes1Engine::init() {
} else
_files = new Files_Plain();
- _graphics = new Graphics_v1(*_display);
+ _graphics = new GraphicsMan(*_display);
StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
@@ -279,11 +279,11 @@ void HiRes1Engine::init() {
stream->seek(IDI_HR1_OFS_ITEM_OFFSETS);
loadDroppedItemOffsets(*stream, IDI_HR1_NUM_ITEM_OFFSETS);
- // Load right-angle line art
- stream->seek(IDI_HR1_OFS_CORNERS);
+ // Load shapes
+ stream->seek(IDI_HR1_OFS_SHAPES);
uint16 cornersCount = stream->readUint16LE();
for (uint i = 0; i < cornersCount; ++i)
- _corners.push_back(_files->getDataBlock(IDS_HR1_EXE_1, IDI_HR1_OFS_CORNERS + stream->readUint16LE()));
+ _corners.push_back(_files->getDataBlock(IDS_HR1_EXE_1, IDI_HR1_OFS_SHAPES + stream->readUint16LE()));
if (stream->eos() || stream->err())
error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
@@ -324,7 +324,7 @@ void HiRes1Engine::initGameState() {
item.noun = stream->readByte();
item.room = stream->readByte();
item.picture = stream->readByte();
- item.isLineArt = stream->readByte();
+ item.isShape = stream->readByte();
item.position.x = stream->readByte();
item.position.y = stream->readByte();
item.state = stream->readByte();
@@ -416,9 +416,10 @@ void HiRes1Engine::drawItems() {
}
void HiRes1Engine::drawItem(Item &item, const Common::Point &pos) {
- if (item.isLineArt) {
+ if (item.isShape) {
StreamPtr stream(_corners[item.picture - 1]->createReadStream());
- static_cast<Graphics_v1 *>(_graphics)->drawCorners(*stream, pos);
+ Common::Point p(pos);
+ _graphics->drawShape(*stream, p);
} else
drawPic(item.picture, pos);
}
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 9562095..ac1ee57 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -80,7 +80,7 @@ void HiRes2Engine::runIntro() {
}
void HiRes2Engine::init() {
- _graphics = new Graphics_v2(*_display);
+ _graphics = new GraphicsMan_v2(*_display);
_disk = new DiskImage();
if (!_disk->open(IDS_HR2_DISK_IMAGE))
diff --git a/engines/adl/hires4.cpp b/engines/adl/hires4.cpp
index 3775a2d..9b085e3 100644
--- a/engines/adl/hires4.cpp
+++ b/engines/adl/hires4.cpp
@@ -83,7 +83,7 @@ HiRes4Engine_Atari::~HiRes4Engine_Atari() {
}
void HiRes4Engine_Atari::init() {
- _graphics = new Graphics_v2(*_display);
+ _graphics = new GraphicsMan_v2(*_display);
_boot = new DiskImage();
if (!_boot->open(atariDisks[0]))
diff --git a/engines/adl/hires5.cpp b/engines/adl/hires5.cpp
index e0f61ba..efe69a7 100644
--- a/engines/adl/hires5.cpp
+++ b/engines/adl/hires5.cpp
@@ -325,7 +325,7 @@ void HiRes5Engine::runIntro() {
}
void HiRes5Engine::init() {
- _graphics = new Graphics_v3(*_display);
+ _graphics = new GraphicsMan_v3(*_display);
insertDisk(2);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 0eb47de..02ef0f0 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -289,7 +289,7 @@ void HiRes6Engine::runIntro() {
}
void HiRes6Engine::init() {
- _graphics = new Graphics_v3(*_display);
+ _graphics = new GraphicsMan_v3(*_display);
insertDisk(0);
Commit: c88d30d8d3bbe02eca5b09ae9061ade3184d96ef
https://github.com/scummvm/scummvm/commit/c88d30d8d3bbe02eca5b09ae9061ade3184d96ef
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:58+01:00
Commit Message:
ADL: Allow smaller delays
Changed paths:
engines/adl/adl.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 3887fa9..2d2bee5 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -139,12 +139,14 @@ Common::String AdlEngine::getItemDescription(const Item &item) const {
}
void AdlEngine::delay(uint32 ms) const {
- uint32 start = g_system->getMillis();
+ uint32 now = g_system->getMillis();
+ const uint32 end = now + ms;
- while (!shouldQuit() && g_system->getMillis() - start < ms) {
+ while (!shouldQuit() && now < end) {
Common::Event event;
pollEvent(event);
- g_system->delayMillis(16);
+ g_system->delayMillis(end - now < 16 ? end - now : 16);
+ now = g_system->getMillis();
}
}
Commit: 19b07a7c125b40d42996e1c943131504649b97eb
https://github.com/scummvm/scummvm/commit/19b07a7c125b40d42996e1c943131504649b97eb
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:58+01:00
Commit Message:
ADL: Move multi-disk handling into v2
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/adl_v4.cpp
engines/adl/adl_v4.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 2329439..dfc2df6 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -26,6 +26,7 @@
#include "adl/adl_v2.h"
#include "adl/display.h"
#include "adl/graphics.h"
+#include "adl/detection.h"
namespace Adl {
@@ -38,6 +39,7 @@ AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
AdlEngine(syst, gd),
_maxLines(4),
_disk(nullptr),
+ _currentVolume(0),
_itemRemoved(false),
_roomOnScreen(0),
_picOnScreen(0),
@@ -45,6 +47,26 @@ AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
_random = new Common::RandomSource("adl");
}
+Common::String AdlEngine_v2::getDiskImageName(byte volume) const {
+ const ADGameFileDescription *ag;
+
+ for (ag = _gameDescription->desc.filesDescriptions; ag->fileName; ag++)
+ if (ag->fileType == volume)
+ return ag->fileName;
+
+ error("Disk volume %d not found", volume);
+}
+
+void AdlEngine_v2::insertDisk(byte volume) {
+ delete _disk;
+ _disk = new DiskImage();
+
+ if (!_disk->open(getDiskImageName(volume)))
+ error("Failed to open disk volume %d", volume);
+
+ _currentVolume = volume;
+}
+
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v2> OpcodeV2;
#define SetOpcodeTable(x) table = &x;
#define Opcode(x) table->push_back(new OpcodeV2(this, &AdlEngine_v2::x))
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 9d4d5fa..889b03c 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -54,6 +54,8 @@ protected:
// Engine
bool canSaveGameStateCurrently();
+ Common::String getDiskImageName(byte volume) const;
+ void insertDisk(byte volume);
virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
virtual void adjustDataBlockPtr(byte &track, byte §or, byte &offset, byte &size) const { }
void loadItems(Common::ReadStream &stream);
@@ -91,6 +93,7 @@ protected:
uint _maxLines;
DiskImage *_disk;
+ byte _currentVolume;
Common::Array<DataBlockPtr> _itemPics;
bool _itemRemoved;
byte _roomOnScreen, _picOnScreen, _itemsOnScreen;
diff --git a/engines/adl/adl_v4.cpp b/engines/adl/adl_v4.cpp
index e8ee798..c06099b 100644
--- a/engines/adl/adl_v4.cpp
+++ b/engines/adl/adl_v4.cpp
@@ -20,15 +20,15 @@
*
*/
+#include "common/error.h"
+
#include "adl/adl_v4.h"
#include "adl/display.h"
-#include "adl/detection.h"
namespace Adl {
AdlEngine_v4::AdlEngine_v4(OSystem *syst, const AdlGameDescription *gd) :
AdlEngine_v3(syst, gd),
- _currentVolume(0),
_itemPicIndex(nullptr) {
}
@@ -190,26 +190,6 @@ Common::String AdlEngine_v4::getItemDescription(const Item &item) const {
return _itemDesc[item.id - 1];
}
-Common::String AdlEngine_v4::getDiskImageName(byte volume) const {
- const ADGameFileDescription *ag;
-
- for (ag = _gameDescription->desc.filesDescriptions; ag->fileName; ag++)
- if (ag->fileType == volume)
- return ag->fileName;
-
- error("Disk volume %d not found", volume);
-}
-
-void AdlEngine_v4::insertDisk(byte volume) {
- delete _disk;
- _disk = new DiskImage();
-
- if (!_disk->open(getDiskImageName(volume)))
- error("Failed to open disk volume %d", volume);
-
- _currentVolume = volume;
-}
-
void AdlEngine_v4::loadRegionLocations(Common::ReadStream &stream, uint regions) {
for (uint r = 0; r < regions; ++r) {
RegionLocation loc;
diff --git a/engines/adl/adl_v4.h b/engines/adl/adl_v4.h
index ca9aeff..efb58b2 100644
--- a/engines/adl/adl_v4.h
+++ b/engines/adl/adl_v4.h
@@ -71,8 +71,6 @@ protected:
kRegionChunkGlobalCmds
};
- Common::String getDiskImageName(byte volume) const;
- void insertDisk(byte volume);
void loadRegionLocations(Common::ReadStream &stream, uint regions);
void loadRegionInitDataOffsets(Common::ReadStream &stream, uint regions);
void initRegions(const byte *roomsPerRegion, uint regions);
@@ -98,7 +96,6 @@ protected:
int o4_setRegionRoom(ScriptEnv &e);
int o4_setRoomPic(ScriptEnv &e);
- byte _currentVolume;
Common::Array<RegionLocation> _regionLocations;
Common::Array<RegionInitDataOffset> _regionInitDataOffsets;
Common::SeekableReadStream *_itemPicIndex;
Commit: 33c8073bc278f2fe7323bd0bfecc3f7209f2dd1d
https://github.com/scummvm/scummvm/commit/33c8073bc278f2fe7323bd0bfecc3f7209f2dd1d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:58+01:00
Commit Message:
ADL: Make framebuffer loader static
Changed paths:
engines/adl/display.cpp
engines/adl/display.h
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 7283777..fc20082 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -39,9 +39,6 @@ namespace Adl {
// This implements the Apple II "Hi-Res" display mode
-#define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
-#define DISPLAY_SIZE (DISPLAY_PITCH * DISPLAY_HEIGHT)
-
#define TEXT_BUF_SIZE (TEXT_WIDTH * TEXT_HEIGHT)
#define COLOR_PALETTE_ENTRIES 8
@@ -201,8 +198,7 @@ bool Display::saveThumbnail(Common::WriteStream &out) {
return retval;
}
-void Display::loadFrameBuffer(Common::ReadStream &stream) {
- byte *dst = _frameBuf;
+void Display::loadFrameBuffer(Common::ReadStream &stream, byte *dst) {
for (uint j = 0; j < 8; ++j) {
for (uint i = 0; i < 8; ++i) {
stream.read(dst, DISPLAY_PITCH);
@@ -221,6 +217,10 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
error("Failed to read frame buffer");
}
+void Display::loadFrameBuffer(Common::ReadStream &stream) {
+ loadFrameBuffer(stream, _frameBuf);
+}
+
void Display::putPixel(const Common::Point &p, byte color) {
byte offset = p.x / 7;
byte mask = 0x80 | (1 << (p.x % 7));
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 311a058..da083e8 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -40,6 +40,8 @@ namespace Adl {
#define DISPLAY_WIDTH 280
#define DISPLAY_HEIGHT 192
+#define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
+#define DISPLAY_SIZE (DISPLAY_PITCH * DISPLAY_HEIGHT)
#define TEXT_WIDTH 40
#define TEXT_HEIGHT 24
@@ -62,6 +64,7 @@ public:
bool saveThumbnail(Common::WriteStream &out);
// Graphics
+ static void loadFrameBuffer(Common::ReadStream &stream, byte *dst);
void loadFrameBuffer(Common::ReadStream &stream);
void putPixel(const Common::Point &p, byte color);
void setPixelBit(const Common::Point &p, byte color);
Commit: 494682de90e7fb0d01cdd32c473e58b564f25eaf
https://github.com/scummvm/scummvm/commit/494682de90e7fb0d01cdd32c473e58b564f25eaf
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:58+01:00
Commit Message:
ADL: Add byte-access functions to Display class
Changed paths:
engines/adl/display.cpp
engines/adl/display.h
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index fc20082..52fb1b4 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -241,6 +241,12 @@ void Display::putPixel(const Common::Point &p, byte color) {
writeFrameBuffer(p, color, mask);
}
+void Display::setPixelByte(const Common::Point &p, byte color) {
+ assert(p.x >= 0 && p.x < DISPLAY_WIDTH && p.y >= 0 && p.y < DISPLAY_HEIGHT);
+
+ _frameBuf[p.y * DISPLAY_PITCH + p.x / 7] = color;
+}
+
void Display::setPixelBit(const Common::Point &p, byte color) {
writeFrameBuffer(p, color, 1 << (p.x % 7));
}
@@ -249,6 +255,12 @@ void Display::setPixelPalette(const Common::Point &p, byte color) {
writeFrameBuffer(p, color, 0x80);
}
+byte Display::getPixelByte(const Common::Point &p) const {
+ assert(p.x >= 0 && p.x < DISPLAY_WIDTH && p.y >= 0 && p.y < DISPLAY_HEIGHT);
+
+ return _frameBuf[p.y * DISPLAY_PITCH + p.x / 7];
+}
+
bool Display::getPixelBit(const Common::Point &p) const {
assert(p.x >= 0 && p.x < DISPLAY_WIDTH && p.y >= 0 && p.y < DISPLAY_HEIGHT);
diff --git a/engines/adl/display.h b/engines/adl/display.h
index da083e8..c1c0f41 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -67,8 +67,10 @@ public:
static void loadFrameBuffer(Common::ReadStream &stream, byte *dst);
void loadFrameBuffer(Common::ReadStream &stream);
void putPixel(const Common::Point &p, byte color);
+ void setPixelByte(const Common::Point &p, byte color);
void setPixelBit(const Common::Point &p, byte color);
void setPixelPalette(const Common::Point &p, byte color);
+ byte getPixelByte(const Common::Point &p) const;
bool getPixelBit(const Common::Point &p) const;
void clear(byte color);
Commit: 3beb48f5ced89ba5521d5f6729534332db6b76d9
https://github.com/scummvm/scummvm/commit/3beb48f5ced89ba5521d5f6729534332db6b76d9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:58+01:00
Commit Message:
ADL: Fix error() when opening GMM during intro
This is a regression from 516815d
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/hires6.cpp
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index dfc2df6..6eb26c5 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -634,6 +634,9 @@ int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
}
bool AdlEngine_v2::canSaveGameStateCurrently() {
+ if (!_canSaveNow)
+ return false;
+
// Back up first visit flag as it may be changed by this test
const bool isFirstTime = getCurRoom().isFirstTime;
const bool retval = AdlEngine::canSaveGameStateCurrently();
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 02ef0f0..a8d2f3f 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -206,6 +206,9 @@ int HiRes6Engine::o_fluteSound(ScriptEnv &e) {
}
bool HiRes6Engine::canSaveGameStateCurrently() {
+ if (!_canSaveNow)
+ return false;
+
// Back up variables that may be changed by this test
const byte var2 = getVar(2);
const byte var24 = getVar(24);
Commit: 56206fef9f57567248c2c926659cbc4ec1535095
https://github.com/scummvm/scummvm/commit/56206fef9f57567248c2c926659cbc4ec1535095
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2017-03-05T21:16:58+01:00
Commit Message:
ADL: Implement hires4 intro (1986 re-release)
Changed paths:
engines/adl/hires4.cpp
diff --git a/engines/adl/hires4.cpp b/engines/adl/hires4.cpp
index 9b085e3..5f9b279 100644
--- a/engines/adl/hires4.cpp
+++ b/engines/adl/hires4.cpp
@@ -25,6 +25,7 @@
#include "common/error.h"
#include "common/file.h"
#include "common/stream.h"
+#include "common/events.h"
#include "adl/adl_v3.h"
#include "adl/detection.h"
@@ -48,6 +49,367 @@ namespace Adl {
#define IDI_HR4_MSG_ITEM_NOT_HERE 115
#define IDI_HR4_MSG_THANKS_FOR_PLAYING 113
+class HiRes4Engine : public AdlEngine_v3 {
+public:
+ HiRes4Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v3(syst, gd) { }
+
+private:
+ // AdlEngine
+ void runIntro();
+ void init();
+ void initGameState();
+
+ void putSpace(uint x, uint y) const;
+ void drawChar(byte c, Common::SeekableReadStream &shapeTable, Common::Point &pos) const;
+ void drawText(const Common::String &str, Common::SeekableReadStream &shapeTable, const float ht, const float vt) const;
+
+ void runIntroAdvise(Common::SeekableReadStream &menu);
+ void runIntroLogo(Common::SeekableReadStream &ms2);
+ void runIntroTitle(Common::SeekableReadStream &menu, Common::SeekableReadStream &ms2);
+ void runIntroInstructions(Common::SeekableReadStream &instructions);
+ void runIntroLoading(Common::SeekableReadStream &adventure);
+
+ static const uint kClock = 1022727; // Apple II CPU clock rate
+};
+
+void HiRes4Engine::putSpace(uint x, uint y) const {
+ if (shouldQuit())
+ return;
+
+ _display->moveCursorTo(Common::Point(x, y));
+ _display->printChar(' ');
+ _display->updateTextScreen();
+ delay(2);
+}
+
+void HiRes4Engine::drawChar(byte c, Common::SeekableReadStream &shapeTable, Common::Point &pos) const {
+ shapeTable.seek(0);
+ byte entries = shapeTable.readByte();
+
+ if (c >= entries)
+ error("Character %d is not in the shape table", c);
+
+ shapeTable.seek(c * 2 + 2);
+ uint16 offset = shapeTable.readUint16LE();
+
+ shapeTable.seek(offset);
+
+ _graphics->drawShape(shapeTable, pos);
+}
+
+void HiRes4Engine::drawText(const Common::String &str, Common::SeekableReadStream &shapeTable, const float ht, const float vt) const {
+ if (shouldQuit())
+ return;
+
+ Common::Point pos(ht * 7, vt * 7.7);
+
+ drawChar(99, shapeTable, pos);
+
+ for (uint i = 0; i < str.size(); ++i) {
+ const byte c = str[i] - 32;
+
+ drawChar(c, shapeTable, pos);
+ drawChar(98, shapeTable, pos);
+
+ _display->updateHiResScreen();
+ delay(15);
+ }
+}
+
+void HiRes4Engine::runIntroAdvise(Common::SeekableReadStream &menu) {
+ Common::StringArray backupText;
+ backupText.push_back(readStringAt(menu, 0x659, '"'));
+ backupText.push_back(readStringAt(menu, 0x682, '"'));
+ backupText.push_back(readStringAt(menu, 0x6a9, '"'));
+ backupText.push_back(readStringAt(menu, 0x6c6, '"'));
+
+ _display->setMode(DISPLAY_MODE_TEXT);
+
+ for (uint x = 2; x <= 36; ++x)
+ putSpace(x, 2);
+
+ for (uint y = 3; y <= 20; ++y) {
+ putSpace(2, y);
+ putSpace(36, y);
+ }
+
+ for (uint x = 2; x <= 36; ++x)
+ putSpace(x, 20);
+
+ for (uint x = 0; x <= 38; ++x)
+ putSpace(x, 0);
+
+ for (uint y = 1; y <= 21; ++y) {
+ putSpace(0, y);
+ putSpace(38, y);
+ }
+
+ for (uint x = 0; x <= 38; ++x)
+ putSpace(x, 22);
+
+ int y = 7;
+
+ for (uint i = 0; i < backupText.size(); ++i) {
+ uint x = 0;
+
+ do {
+ if (shouldQuit())
+ return;
+
+ ++x;
+
+ Common::String left = backupText[i];
+ left.erase(x, Common::String::npos);
+ Common::String right = backupText[i];
+ right.erase(0, right.size() - x);
+
+ _display->moveCursorTo(Common::Point(19 - x, y));
+ _display->printAsciiString(left);
+ _display->moveCursorTo(Common::Point(19, y));
+ _display->printAsciiString(right);
+ _display->updateTextScreen();
+ delay(35);
+ } while (x != backupText[i].size() / 2);
+
+ if (i == 2)
+ y = 18;
+ else
+ y += 2;
+ }
+
+ Common::String cursor = readStringAt(menu, 0x781, '"');
+
+ uint cursorIdx = 0;
+ while (!shouldQuit()) {
+ Common::Event event;
+ if (pollEvent(event)) {
+ if (event.type == Common::EVENT_KEYDOWN)
+ break;
+ }
+
+ _display->moveCursorTo(Common::Point(32, 18));
+ _display->printChar(APPLECHAR(cursor[cursorIdx]));
+ _display->updateTextScreen();
+ g_system->delayMillis(25);
+ cursorIdx = (cursorIdx + 1) % cursor.size();
+ }
+}
+
+void HiRes4Engine::runIntroLogo(Common::SeekableReadStream &ms2) {
+ _display->clear(0x00);
+ _display->setMode(DISPLAY_MODE_HIRES);
+ byte *logo = new byte[DISPLAY_SIZE];
+ Display::loadFrameBuffer(ms2, logo);
+
+ for (uint x = 0; x < DISPLAY_WIDTH; ++x) {
+ for (uint y = 0; y < DISPLAY_HEIGHT; ++y) {
+ const byte p = logo[y * DISPLAY_PITCH + x / 7];
+ _display->setPixelBit(Common::Point(x, y), p);
+ if (x % 7 == 6)
+ _display->setPixelPalette(Common::Point(x, y), p);
+ }
+ _display->updateHiResScreen();
+
+ if (shouldQuit()) {
+ delete logo;
+ return;
+ }
+
+ delay(7);
+ }
+
+ delete logo;
+
+ for (uint i = 38; i != 0; --i) {
+ Common::Point p;
+
+ for (p.y = 1; p.y < DISPLAY_HEIGHT; ++p.y)
+ for (p.x = 0; p.x < DISPLAY_WIDTH; p.x += 7)
+ _display->setPixelByte(Common::Point(p.x, p.y - 1), _display->getPixelByte(p));
+
+ _display->updateHiResScreen();
+
+ Tones tone;
+ tone.push_back(Tone(kClock / 2.0 / ((i * 4 + 1) * 10.0 + 10.0), 12.5));
+ playTones(tone, false, false);
+
+ if (shouldQuit())
+ return;
+ }
+}
+
+void HiRes4Engine::runIntroTitle(Common::SeekableReadStream &menu, Common::SeekableReadStream &ms2) {
+ ms2.seek(0x2290);
+ StreamPtr shapeTable(ms2.readStream(0x450));
+ if (ms2.err() || ms2.eos())
+ error("Failed to read shape table");
+
+ Common::String titleString(readStringAt(menu, 0x1f5, '"'));
+ drawText(titleString, *shapeTable, 4.0f, 22.5f);
+
+ titleString = readStringAt(menu, 0x22b, '"');
+ drawText(titleString, *shapeTable, 5.0f, 24.0f);
+
+ // Draw "TM" with lines
+ _graphics->drawLine(Common::Point(200, 170), Common::Point(200, 174), 0x7f);
+ _graphics->drawLine(Common::Point(198, 170), Common::Point(202, 170), 0x7f);
+ _display->updateHiResScreen();
+ delay(7);
+ _graphics->drawLine(Common::Point(204, 170), Common::Point(204, 174), 0x7f);
+ _graphics->drawLine(Common::Point(204, 170), Common::Point(207, 173), 0x7f);
+ _graphics->drawLine(Common::Point(207, 173), Common::Point(209, 170), 0x7f);
+ _graphics->drawLine(Common::Point(209, 170), Common::Point(209, 174), 0x7f);
+ _display->updateHiResScreen();
+ delay(7);
+
+ titleString = readStringAt(menu, 0x46c);
+ drawText(titleString, *shapeTable, 20.0f - titleString.size() / 2.0f, 10.6f);
+
+ titleString = readStringAt(menu, 0x490);
+ drawText(titleString, *shapeTable, 20.0f - titleString.size() / 2.0f, 11.8f);
+
+ Common::StringArray menuStrings;
+ menuStrings.push_back(readStringAt(menu, 0x515));
+ menuStrings.push_back(readStringAt(menu, 0x52b));
+
+ for (uint i = 0; i < menuStrings.size(); ++i)
+ drawText(Common::String::format("%d) ", i + 1) + menuStrings[i], *shapeTable, 12.5f, 14.0f + i * 1.2f);
+
+ titleString = readStringAt(menu, 0x355, '"');
+ drawText(titleString, *shapeTable, 12.5f, 14.0f + menuStrings.size() * 1.2f + 2.0f);
+}
+
+void HiRes4Engine::runIntroInstructions(Common::SeekableReadStream &instructions) {
+ Common::String line;
+ Common::String pressKey(readStringAt(instructions, 0xad6, '"'));
+ instructions.seek(0);
+
+ _display->home();
+ _display->setMode(DISPLAY_MODE_TEXT);
+
+ // Search for PRINT commands in tokenized BASIC
+ while (1) {
+ char c;
+
+ do {
+ c = instructions.readByte();
+
+ if (instructions.err() || instructions.eos())
+ error("Error reading instructions file");
+
+ // GOSUB (calls "press any key" routine)
+ if (c == (char)0xb0) {
+ _display->moveCursorTo(Common::Point(6, 23));
+ _display->printAsciiString(pressKey);
+ inputKey();
+
+ if (shouldQuit())
+ return;
+
+ _display->home();
+ }
+ } while (c != (char)0xba); // PRINT
+
+ uint quotes = 0;
+ while (1) {
+ c = instructions.readByte();
+
+ if (instructions.err() || instructions.eos())
+ error("Error reading instructions file");
+
+ if (c == '"') {
+ ++quotes;
+ continue;
+ }
+
+ if (c == 0)
+ break;
+
+ if (quotes == 1)
+ line += c;
+ else if (c == ':') // Separator
+ break;
+ else if (c == '4') // CTRL-D before "RUN MENU"
+ return;
+ };
+
+ line += '\r';
+ _display->printAsciiString(line);
+ line.clear();
+ }
+}
+
+void HiRes4Engine::runIntroLoading(Common::SeekableReadStream &adventure) {
+ _display->home();
+ _display->setMode(DISPLAY_MODE_TEXT);
+
+ const uint kStrings = 4;
+ const uint kStringLen = 39;
+ char text[kStrings][kStringLen];
+
+ adventure.seek(0x2eb);
+
+ if (adventure.read(text, sizeof(text)) < sizeof(text))
+ error("Failed to read loading screen text");
+
+ const uint yPos[kStrings] = { 2, 19, 8, 22 };
+
+ for (uint i = 0; i < kStrings; ++i) {
+ _display->moveCursorTo(Common::Point(0, yPos[i]));
+ _display->printString(Common::String(text[i], kStringLen));
+ }
+
+ delay(4000);
+}
+
+void HiRes4Engine::runIntro() {
+ Common::ScopedPtr<Files_DOS33> files(new Files_DOS33());
+ files->open(getDiskImageName(0));
+
+ while (!shouldQuit()) {
+ StreamPtr menu(files->createReadStream("MENU"));
+ runIntroAdvise(*menu);
+
+ if (shouldQuit())
+ return;
+
+ StreamPtr ms2(files->createReadStream("MS2"));
+ runIntroLogo(*ms2);
+
+ if (shouldQuit())
+ return;
+
+ _graphics->setBounds(Common::Rect(280, 192));
+ runIntroTitle(*menu, *ms2);
+ _graphics->setBounds(Common::Rect(280, 160));
+
+ while (1) {
+ char key = inputKey();
+
+ if (shouldQuit())
+ return;
+
+ if (key == APPLECHAR('1')) {
+ StreamPtr instructions(files->createReadStream("INSTRUCTIONS"));
+ runIntroInstructions(*instructions);
+ break;
+ } else if (key == APPLECHAR('2')) {
+ StreamPtr adventure(files->createReadStream("THE ADVENTURE"));
+ runIntroLoading(*adventure);
+ return;
+ }
+ };
+ }
+}
+
+void HiRes4Engine::init() {
+ _graphics = new GraphicsMan_v2(*_display);
+}
+
+void HiRes4Engine::initGameState() {
+}
+
class HiRes4Engine_Atari : public AdlEngine_v3 {
public:
HiRes4Engine_Atari(OSystem *syst, const AdlGameDescription *gd) :
@@ -261,6 +623,8 @@ void HiRes4Engine_Atari::adjustDataBlockPtr(byte &track, byte §or, byte &off
Engine *HiRes4Engine_create(OSystem *syst, const AdlGameDescription *gd) {
switch (gd->desc.platform) {
+ case Common::kPlatformApple2:
+ return new HiRes4Engine(syst, gd);
case Common::kPlatformAtari8Bit:
return new HiRes4Engine_Atari(syst, gd);
default:
More information about the Scummvm-git-logs
mailing list