[Scummvm-cvs-logs] scummvm master -> 9acf6c3838d0aaaf5cff8ea120ec4672cf6fe6c8
waltervn
walter at vanniftrik-it.nl
Mon Jun 6 20:43:39 CEST 2016
This automated email contains information about 117 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
ee0c5e4452 ADL: Add skeleton for Hi-Res #2
e49085b49d ADL: Implement hires2 title screen
ebb6ceb294 ADL: Load verbs and nouns for hires2
fe384e0ae0 ADL: Make room description hires1-only
c44f18a818 ADL: Load hires2 room data
641d87f752 ADL: Load (some) hires2 strings
930bdcfa91 ADL: Implement hires2 PIC drawing
60892c91a5 ADL: Rename PictureD to Graphics
148814b2a6 ADL: Move hires1 drawing functions into class
0686ba9de8 ADL: Clean up file error handling
b4aea80723 ADL: Implement hires2 word wrapping
0664b51d2f ADL: Add bell function
7cef93739c ADL: Hook up bell in hires2
1e5fff86c8 ADL: Fix hires2 message printing
0a6b7fb6a6 ADL: Add loading of room picture index for hires2
7ff7e0def4 ADL: Add hires2 command loading
46528f2c04 ADL: Fix flood fill palette setting
df4daf954f ADL: Load hires2 items
0593460b1b ADL: Enable global commands in hires2
a653fa2f45 ADL: Add partial hires2 item drawing
6fd580fb66 ADL: Add pic offsetting
c0b33afc4a ADL: Load hires2 dropped item offsets
64cf93198f ADL: Use functors to implement opcodes
eaacfe1eed ADL: Use template for direction opcode
37656db0d4 ADL: Clean up opcodes
a9afe17169 ADL: Replace opcode arg macro with function
f93ae5479e ADL: Make opcodes return arg count
0cb889b55e ADL: Remove unused opcode #defines
60a9a592f5 ADL: Clean up script handling
ddf1151a53 ADL: Add new class for second generation ADL
fab489c530 ADL: Rename IDI_ITEM_MOVED to IDI_ITEM_DROPPED
8d1901c39b ADL: Implement hires2 cond opcodes 0x01 and 0x04
ee8c63183d ADL: Implement hires2 random cond opcode
d09247baca ADL: Fix move counter
d8035140e2 ADL: Clean up opcodes
8a05a9cbca ADL: Implement final hires2 conditional opcode
3f7d5608a9 ADL: Implement a few hires2 opcodes
4ce697e2c3 ADL: Rename IDI_NONE to IDI_ANY
3102ff4a19 ADL: Clean up handling of room value 0xfc
e7c93489e4 ADL: Clean up drawItems()
a7a371c63d ADL: Implement time opcode
905e2cd63f ADL: Add hires2 opcode 0x20
3afcf67643 ADL: Stub init disk opcode
a82ac8973d ADL: Implement hires2 save/restore opcodes
ffbc4da0b0 ADL: Use display class to print init disk message
4af9f32d3f ADL: Add disk format abstraction
bfbacf9397 ADL: Use DiskImage class in hires2
f2de96512a ADL: Add file-based disk access class
5451df3afe ADL: Use new disk class in hires1
3b67b07364 ADL: Set ADGF_UNSTABLE
71ca8de7e6 ADL: Add support for Apple DOS 3.3 disk images
02563df422 ADL: Add support for hires1 disk image
7ee183ca48 ADL: Refactor disk classes
865bd06845 ADL: Move room-local commands into base class
c9824921b4 ADL: Move message delay code into hires1 class
41e8227637 ADL: Set room description in hires1
aa661fae5c ADL: Fix room loading in hires2
bd588d9615 ADL: Use HashMaps for room/global pics
42c41b4495 ADL: Load hires2 global pics
53e7ecb79c ADL: Remove unused DrawPic color parameter
d0f33851bc ADL: Fix regression in message loading
760d5ac733 ADL: Move drawPic() into base class
367cb511d1 ADL: Add Console
73dfe71b1b ADL: Add verbs and nouns debug commands
b24f30527b ADL: Add script dump and trace for hires1
2c8e0cefb1 ADL: Store items in a List instead of an Array
cf6bc0e438 ADL: Add script dump and trace for hires2
3b72a30c0f ADL: Clean up script dump debug command
dd5ce7ebbb ADL: Add valid_cmds debug command
3b7813d971 ADL: Fix debug print for MOVE_ALL_ITEMS
26b8e8d66a ADL: Use columns when printing verb/noun lists
9eb7af0f67 ADL: Add 'room' debugger command
fde2db9d4c ADL: Add items and give_item debug commands
23d4e61260 ADL: Fix hires2 item description debug printing
1d314b2084 ADL: Allow synonyms in give_item debug command
ff4b9fcd9c ADL: Add 'vars' debug command
1b9d712a8b ADL: Add 'var' debug command
d6f34eda99 ADL: Remove DataBlockPtr::isValid()
f275add1e5 ADL: Use pointer for hires2 disk image
4ee8cf4f9e ADL: Move some hires2 functionality into ADL_v2
97168fa200 ADL: Load line feeds string
09146fba6e ADL: Move restartGame() into opcode
b4a82370cd ADL: Partially fix hires2 restarting
adecc10674 ADL: Reset "lines printed" counter on restart
83d75c2f4c ADL: Clean-up
ed0653e393 ADL: Update save game format for hires2
bc0fc246f0 ADL: Implement hires2 screen update routine
d361f2e4b0 ADL: Add (experimental) support for NIB files
5db8f401a8 ADL: Add detection entry for hires0
e89f34857f ADL: Fix NIB track swapping hack
266e63453f ADL: Add support for newer NIB files
ae405707cc ADL: Add skeleton for hires6
7dc5f636f8 ADL: Map DOS 3.3 NIB to logical sectors
a320b319eb ADL: Load more hires6 data
1842d0c45f ADL: Add loadMessage function
4f932afd60 ADL: Load messages on demand
ca47d3bb22 ADL: Decrypt hires6 messages
6044022c8e ADL: Add '%' string code processing for hires6
8cc5100afd ADL: Fix OB1 bug in ADL v2 word wrapping
5fe95d51ea ADL: Separate game-specific state init
bf520ca321 ADL: Fix restarting from AllCommands list
7e9a8c0072 ADL: Partially implement hires6 var handling
b8c40f9a8b ADL: Implement hires6 cond opcode 0xa
bb6cd4612d ADL: Fix bug in hires6 printString
04604ed602 ADL: Implement hires6 showRoom() var handling
d2175a70ce ADL: Implement remaining hires6 conditionals
e79f26c9bc ADL: Implement hires6 item descriptions
e755f8fcba ADL: Implement hires6 "move item" opcode
92b1b287b1 ADL: Preliminary support for hires6 disk changing
2cdb1d49a5 ADL: Add stubs for hires6 opcodes
12fe7dabab ADL: Fix debug output in 'move all items' opcode
d435f5b4eb ADL: Fix item rendering in hires6
f8d75bbc86 ADL: Implement hires6 verb/noun error messages
0c2d2b2c92 ADL: Fix GCC 4.9 shadow warnings
9967ae8c52 ADL: Fix more GCC 4.9 shadow warnings
c71740bc5d ADL: Fix GCC 4.9 missing initializer warnings
9acf6c3838 ADL: Fix formatting
Commit: ee0c5e4452722fcee3304af26d209114b4c80f75
https://github.com/scummvm/scummvm/commit/ee0c5e4452722fcee3304af26d209114b4c80f75
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add skeleton for Hi-Res #2
Changed paths:
A engines/adl/hires2.cpp
A engines/adl/hires2.h
engines/adl/detection.cpp
engines/adl/detection.h
engines/adl/module.mk
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 1a8c502..3069f21 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -60,8 +60,9 @@ static const ADExtraGuiOptionsMap optionsList[] = {
};
static const PlainGameDescriptor adlGames[] = {
- {"hires1", "Hi-Res Adventure #1: Mystery House"},
- {0, 0}
+ { "hires1", "Hi-Res Adventure #1: Mystery House" },
+ { "hires2", "Hi-Res Adventure #2: Wizard and the Princess" },
+ { 0, 0 }
};
static const AdlGameDescription gameDescriptions[] = {
@@ -69,9 +70,9 @@ static const AdlGameDescription gameDescriptions[] = {
{
"hires1", 0,
{
- {"ADVENTURE", 0, "22d9e63a11d69fa033ba1738715ad09a", 29952},
- {"AUTO LOAD OBJ", 0, "23bfccfe9fcff9b22cf6c41bde9078ac", 12291},
- {"MYSTERY.HELLO", 0, "2289b7fea300b506e902a4c597968369", 836},
+ { "ADVENTURE", 0, "22d9e63a11d69fa033ba1738715ad09a", 29952 },
+ { "AUTO LOAD OBJ", 0, "23bfccfe9fcff9b22cf6c41bde9078ac", 12291 },
+ { "MYSTERY.HELLO", 0, "2289b7fea300b506e902a4c597968369", 836 },
AD_LISTEND
},
Common::EN_ANY,
@@ -81,6 +82,20 @@ static const AdlGameDescription gameDescriptions[] = {
},
GAME_TYPE_HIRES1
},
+ { // Hi-Res Adventure #2: Wizard and the Princess - Apple II - 1986 SierraVenture release
+ {
+ "hires2", 0,
+ {
+ { "WIZARD.DSK", 0, "816fdfc35e25496213c8db40ecf26569", 143360 },
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformApple2GS, // FIXME
+ ADGF_NO_FLAGS,
+ GUIO1(GAMEOPTION_SCANLINES)
+ },
+ GAME_TYPE_HIRES2
+ },
{ AD_TABLE_END_MARKER, GAME_TYPE_NONE }
};
@@ -220,6 +235,7 @@ void AdlMetaEngine::removeSaveState(const char *target, int slot) const {
}
Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd);
+Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd);
bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
if (!gd)
@@ -231,6 +247,9 @@ bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
case GAME_TYPE_HIRES1:
*engine = HiRes1Engine_create(syst, adlGd);
break;
+ case GAME_TYPE_HIRES2:
+ *engine = HiRes2Engine_create(syst, adlGd);
+ break;
default:
error("Unknown GameType");
}
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index c646aeb..4275286 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -32,7 +32,8 @@ namespace Adl {
enum GameType {
GAME_TYPE_NONE,
- GAME_TYPE_HIRES1
+ GAME_TYPE_HIRES1,
+ GAME_TYPE_HIRES2
};
struct AdlGameDescription {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
new file mode 100644
index 0000000..25e0e6f
--- /dev/null
+++ b/engines/adl/hires2.cpp
@@ -0,0 +1,54 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "common/debug.h"
+#include "common/error.h"
+#include "common/file.h"
+#include "common/stream.h"
+
+#include "adl/hires2.h"
+#include "adl/display.h"
+
+namespace Adl {
+
+void HiRes2Engine::runIntro() const {
+}
+
+void HiRes2Engine::loadData() {
+}
+
+void HiRes2Engine::initState() {
+}
+
+void HiRes2Engine::restartGame() {
+ initState();
+}
+
+void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
+}
+
+Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+ return new HiRes2Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
new file mode 100644
index 0000000..005948a
--- /dev/null
+++ b/engines/adl/hires2.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_HIRES1_H
+#define ADL_HIRES1_H
+
+#include "common/str.h"
+
+#include "adl/adl.h"
+
+namespace Common {
+class ReadStream;
+class Point;
+}
+
+namespace Adl {
+
+class HiRes2Engine : public AdlEngine {
+public:
+ HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
+
+private:
+ // AdlEngine
+ void runIntro() const;
+ void loadData();
+ void initState();
+ void restartGame();
+ void drawPic(byte pic, Common::Point pos) const;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 6acd06f..de69b52 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,7 +4,8 @@ MODULE_OBJS := \
adl.o \
detection.o \
display.o \
- hires1.o
+ hires1.o \
+ hires2.o
MODULE_DIRS += \
engines/adl
Commit: e49085b49d0ff0b2962923682db6770ef3c908dd
https://github.com/scummvm/scummvm/commit/e49085b49d0ff0b2962923682db6770ef3c908dd
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires2 title screen
Changed paths:
engines/adl/detection.cpp
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 3069f21..81050d7 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -32,8 +32,9 @@
namespace Adl {
-#define GAMEOPTION_COLOR GUIO_GAMEOPTIONS1
-#define GAMEOPTION_SCANLINES GUIO_GAMEOPTIONS2
+#define GAMEOPTION_COLOR GUIO_GAMEOPTIONS1
+#define GAMEOPTION_SCANLINES GUIO_GAMEOPTIONS2
+#define GAMEOPTION_MONO GUIO_GAMEOPTIONS3
static const ADExtraGuiOptionsMap optionsList[] = {
{
@@ -47,6 +48,16 @@ static const ADExtraGuiOptionsMap optionsList[] = {
},
{
+ GAMEOPTION_MONO,
+ {
+ _s("Color mode"),
+ _s("Use color graphics"),
+ "color",
+ true
+ }
+ },
+
+ {
GAMEOPTION_SCANLINES,
{
_s("Scanlines"),
@@ -92,7 +103,7 @@ static const AdlGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformApple2GS, // FIXME
ADGF_NO_FLAGS,
- GUIO1(GAMEOPTION_SCANLINES)
+ GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES2
},
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 25e0e6f..f318ad3 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -32,6 +32,22 @@
namespace Adl {
void HiRes2Engine::runIntro() const {
+ Common::File f;
+
+ if (!f.open(IDS_HR2_DISK_IMAGE))
+ error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+ f.seek(IDI_HR2_OFS_INTRO_TEXT);
+
+ _display->setMode(DISPLAY_MODE_TEXT);
+
+ Common::String str = readStringAt(f, IDI_HR2_OFS_INTRO_TEXT);
+
+ if (f.eos() || f.err())
+ error("Error reading disk image");
+
+ _display->printString(str);
+ delay(2000);
}
void HiRes2Engine::loadData() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 005948a..9bb7b98 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -34,6 +34,13 @@ class Point;
namespace Adl {
+#define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
+
+// Track, sector, offset
+#define TSO(T, S, O) (((T) * 16 + (S)) * 256 + (O))
+
+#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
+
class HiRes2Engine : public AdlEngine {
public:
HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
Commit: ebb6ceb2945084e73d1511a02d2ad8fe72d568e0
https://github.com/scummvm/scummvm/commit/ebb6ceb2945084e73d1511a02d2ad8fe72d568e0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load verbs and nouns for hires2
Changed paths:
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index f318ad3..1831266 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -51,6 +51,16 @@ void HiRes2Engine::runIntro() const {
}
void HiRes2Engine::loadData() {
+ Common::File f;
+
+ if (!f.open(IDS_HR2_DISK_IMAGE))
+ error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+ f.seek(IDI_HR2_OFS_VERBS);
+ loadWords(f, _verbs);
+
+ f.seek(IDI_HR2_OFS_NOUNS);
+ loadWords(f, _nouns);
}
void HiRes2Engine::initState() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 9bb7b98..60c6ca1 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -37,9 +37,13 @@ namespace Adl {
#define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
// Track, sector, offset
-#define TSO(T, S, O) (((T) * 16 + (S)) * 256 + (O))
+#define TSO(TRACK, SECTOR, OFFSET) (((TRACK) * 16 + (SECTOR)) * 256 + (OFFSET))
+#define TS(TRACK, SECTOR) TSO(TRACK, SECTOR, 0)
+#define T(TRACK) TS(TRACK, 0)
#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
+#define IDI_HR2_OFS_VERBS T(0x19)
+#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
class HiRes2Engine : public AdlEngine {
public:
Commit: fe384e0ae09ec3e72d653cd9fd34ab047231e249
https://github.com/scummvm/scummvm/commit/fe384e0ae09ec3e72d653cd9fd34ab047231e249
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Make room description hires1-only
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1ab74c3..47623d4 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -264,6 +264,186 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
}
}
+void AdlEngine::clearScreen() const {
+ _display->setMode(DISPLAY_MODE_MIXED);
+ _display->clear(0x00);
+}
+
+void AdlEngine::drawItems() const {
+ Common::Array<Item>::const_iterator item;
+
+ uint dropped = 0;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ if (item->room != _state.room)
+ continue;
+
+ if (item->state == IDI_ITEM_MOVED) {
+ if (getCurRoom().picture == getCurRoom().curPicture) {
+ const Common::Point &p = _itemOffsets[dropped];
+ if (item->isLineArt)
+ drawLineArt(_lineArt[item->picture - 1], p);
+ else
+ drawPic(item->picture, p);
+ ++dropped;
+ }
+ continue;
+ }
+
+ Common::Array<byte>::const_iterator pic;
+
+ for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+ if (*pic == getCurRoom().curPicture) {
+ if (item->isLineArt)
+ drawLineArt(_lineArt[item->picture - 1], item->position);
+ else
+ drawPic(item->picture, item->position);
+ continue;
+ }
+ }
+ }
+}
+
+void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
+ if (bits & 4)
+ _display->putPixel(p, color);
+
+ bits += quadrant;
+
+ if (bits & 1)
+ p.x += (bits & 2 ? -1 : 1);
+ else
+ p.y += (bits & 2 ? 1 : -1);
+}
+
+void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const 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,
+ 0xff
+ };
+
+ byte quadrant = rotation >> 4;
+ rotation &= 0xf;
+ byte xStep = stepping[rotation];
+ byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
+
+ Common::Point p(pos);
+
+ for (uint i = 0; i < lineArt.size(); ++i) {
+ byte b = lineArt[i];
+
+ do {
+ byte xFrac = 0x80;
+ byte yFrac = 0x80;
+ for (uint j = 0; j < scaling; ++j) {
+ if (xFrac + xStep + 1 > 255)
+ drawNextPixel(p, color, b, quadrant);
+ xFrac += xStep + 1;
+ if (yFrac + yStep > 255)
+ drawNextPixel(p, color, b, quadrant + 1);
+ yFrac += yStep;
+ }
+ b >>= 3;
+ } while (b != 0);
+ }
+}
+
+const Room &AdlEngine::getRoom(uint i) const {
+ if (i < 1 || i > _state.rooms.size())
+ error("Room %i out of range [1, %i]", i, _state.rooms.size());
+
+ return _state.rooms[i - 1];
+}
+
+Room &AdlEngine::getRoom(uint i) {
+ if (i < 1 || i > _state.rooms.size())
+ error("Room %i out of range [1, %i]", i, _state.rooms.size());
+
+ return _state.rooms[i - 1];
+}
+
+const Room &AdlEngine::getCurRoom() const {
+ return getRoom(_state.room);
+}
+
+Room &AdlEngine::getCurRoom() {
+ return getRoom(_state.room);
+}
+
+const Item &AdlEngine::getItem(uint i) const {
+ if (i < 1 || i > _state.items.size())
+ error("Item %i out of range [1, %i]", i, _state.items.size());
+
+ return _state.items[i - 1];
+}
+
+Item &AdlEngine::getItem(uint i) {
+ if (i < 1 || i > _state.items.size())
+ error("Item %i out of range [1, %i]", i, _state.items.size());
+
+ return _state.items[i - 1];
+}
+
+byte AdlEngine::getVar(uint i) const {
+ if (i >= _state.vars.size())
+ error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
+
+ return _state.vars[i];
+}
+
+void AdlEngine::setVar(uint i, byte value) {
+ if (i >= _state.vars.size())
+ error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
+
+ _state.vars[i] = value;
+}
+
+void AdlEngine::takeItem(byte noun) {
+ Common::Array<Item>::iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ if (item->noun != noun || item->room != _state.room)
+ continue;
+
+ if (item->state == IDI_ITEM_DOESNT_MOVE) {
+ printMessage(_messageIds.itemDoesntMove);
+ return;
+ }
+
+ if (item->state == IDI_ITEM_MOVED) {
+ item->room = IDI_NONE;
+ return;
+ }
+
+ Common::Array<byte>::const_iterator pic;
+ for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+ if (*pic == getCurRoom().curPicture) {
+ item->room = IDI_NONE;
+ item->state = IDI_ITEM_MOVED;
+ return;
+ }
+ }
+ }
+
+ printMessage(_messageIds.itemNotHere);
+}
+
+void AdlEngine::dropItem(byte noun) {
+ Common::Array<Item>::iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ if (item->noun != noun || item->room != IDI_NONE)
+ continue;
+
+ item->room = _state.room;
+ item->state = IDI_ITEM_MOVED;
+ return;
+ }
+
+ printMessage(_messageIds.dontUnderstand);
+}
+
Common::Error AdlEngine::run() {
_display = new Display();
@@ -636,196 +816,6 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
}
}
-void AdlEngine::showRoom() const {
- if (!_state.isDark) {
- drawPic(getCurRoom().curPicture);
- drawItems();
- }
-
- _display->updateHiResScreen();
- printMessage(getCurRoom().description, false);
-}
-
-void AdlEngine::clearScreen() const {
- _display->setMode(DISPLAY_MODE_MIXED);
- _display->clear(0x00);
-}
-
-void AdlEngine::drawItems() const {
- Common::Array<Item>::const_iterator item;
-
- uint dropped = 0;
-
- for (item = _state.items.begin(); item != _state.items.end(); ++item) {
- if (item->room != _state.room)
- continue;
-
- if (item->state == IDI_ITEM_MOVED) {
- if (getCurRoom().picture == getCurRoom().curPicture) {
- const Common::Point &p = _itemOffsets[dropped];
- if (item->isLineArt)
- drawLineArt(_lineArt[item->picture - 1], p);
- else
- drawPic(item->picture, p);
- ++dropped;
- }
- continue;
- }
-
- Common::Array<byte>::const_iterator pic;
-
- for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (*pic == getCurRoom().curPicture) {
- if (item->isLineArt)
- drawLineArt(_lineArt[item->picture - 1], item->position);
- else
- drawPic(item->picture, item->position);
- continue;
- }
- }
- }
-}
-
-void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
- if (bits & 4)
- _display->putPixel(p, color);
-
- bits += quadrant;
-
- if (bits & 1)
- p.x += (bits & 2 ? -1 : 1);
- else
- p.y += (bits & 2 ? 1 : -1);
-}
-
-void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const 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,
- 0xff
- };
-
- byte quadrant = rotation >> 4;
- rotation &= 0xf;
- byte xStep = stepping[rotation];
- byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
-
- Common::Point p(pos);
-
- for (uint i = 0; i < lineArt.size(); ++i) {
- byte b = lineArt[i];
-
- do {
- byte xFrac = 0x80;
- byte yFrac = 0x80;
- for (uint j = 0; j < scaling; ++j) {
- if (xFrac + xStep + 1 > 255)
- drawNextPixel(p, color, b, quadrant);
- xFrac += xStep + 1;
- if (yFrac + yStep > 255)
- drawNextPixel(p, color, b, quadrant + 1);
- yFrac += yStep;
- }
- b >>= 3;
- } while (b != 0);
- }
-}
-
-const Room &AdlEngine::getRoom(uint i) const {
- if (i < 1 || i > _state.rooms.size())
- error("Room %i out of range [1, %i]", i, _state.rooms.size());
-
- return _state.rooms[i - 1];
-}
-
-Room &AdlEngine::getRoom(uint i) {
- if (i < 1 || i > _state.rooms.size())
- error("Room %i out of range [1, %i]", i, _state.rooms.size());
-
- return _state.rooms[i - 1];
-}
-
-const Room &AdlEngine::getCurRoom() const {
- return getRoom(_state.room);
-}
-
-Room &AdlEngine::getCurRoom() {
- return getRoom(_state.room);
-}
-
-const Item &AdlEngine::getItem(uint i) const {
- if (i < 1 || i > _state.items.size())
- error("Item %i out of range [1, %i]", i, _state.items.size());
-
- return _state.items[i - 1];
-}
-
-Item &AdlEngine::getItem(uint i) {
- if (i < 1 || i > _state.items.size())
- error("Item %i out of range [1, %i]", i, _state.items.size());
-
- return _state.items[i - 1];
-}
-
-byte AdlEngine::getVar(uint i) const {
- if (i >= _state.vars.size())
- error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
-
- return _state.vars[i];
-}
-
-void AdlEngine::setVar(uint i, byte value) {
- if (i >= _state.vars.size())
- error("Variable %i out of range [0, %i]", i, _state.vars.size() - 1);
-
- _state.vars[i] = value;
-}
-
-void AdlEngine::takeItem(byte noun) {
- Common::Array<Item>::iterator item;
-
- for (item = _state.items.begin(); item != _state.items.end(); ++item) {
- if (item->noun != noun || item->room != _state.room)
- continue;
-
- if (item->state == IDI_ITEM_DOESNT_MOVE) {
- printMessage(_messageIds.itemDoesntMove);
- return;
- }
-
- if (item->state == IDI_ITEM_MOVED) {
- item->room = IDI_NONE;
- return;
- }
-
- Common::Array<byte>::const_iterator pic;
- for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (*pic == getCurRoom().curPicture) {
- item->room = IDI_NONE;
- item->state = IDI_ITEM_MOVED;
- return;
- }
- }
- }
-
- printMessage(_messageIds.itemNotHere);
-}
-
-void AdlEngine::dropItem(byte noun) {
- Common::Array<Item>::iterator item;
-
- for (item = _state.items.begin(); item != _state.items.end(); ++item) {
- if (item->noun != noun || item->room != IDI_NONE)
- continue;
-
- item->room = _state.room;
- item->state = IDI_ITEM_MOVED;
- return;
- }
-
- printMessage(_messageIds.dontUnderstand);
-}
-
#define ARG(N) (command.script[offset + (N)])
bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint *actions) const {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4ea7566..df917b1 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -149,6 +149,28 @@ protected:
void loadWords(Common::ReadStream &stream, WordMap &map) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
+ // Graphics
+ void clearScreen() const;
+ void drawItems() const;
+ void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
+ void drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
+
+ // Game state functions
+ const Room &getRoom(uint i) const;
+ Room &getRoom(uint i);
+ const Room &getCurRoom() const;
+ Room &getCurRoom();
+ const Item &getItem(uint i) const;
+ Item &getItem(uint i);
+ byte getVar(uint i) const;
+ void setVar(uint i, byte value);
+ void takeItem(byte noun);
+ void dropItem(byte noun);
+ bool matchCommand(const Command &command, byte verb, byte noun, uint *actions = nullptr) const;
+ void doActions(const Command &command, byte noun, byte offset);
+ bool doOneCommand(const Commands &commands, byte verb, byte noun);
+ void doAllCommands(const Commands &commands, byte verb, byte noun);
+
Display *_display;
// Message strings in data file
@@ -193,6 +215,7 @@ private:
virtual void initState() = 0;
virtual void restartGame() = 0;
virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;
+ virtual void showRoom() const = 0;
// Engine
Common::Error run();
@@ -211,29 +234,6 @@ private:
Common::String getWord(const Common::String &line, uint &index) const;
void getInput(uint &verb, uint &noun);
- // Graphics
- void showRoom() const;
- void clearScreen() const;
- void drawItems() const;
- void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
- void drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
-
- // Game state functions
- const Room &getRoom(uint i) const;
- Room &getRoom(uint i);
- const Room &getCurRoom() const;
- Room &getCurRoom();
- const Item &getItem(uint i) const;
- Item &getItem(uint i);
- byte getVar(uint i) const;
- void setVar(uint i, byte value);
- void takeItem(byte noun);
- void dropItem(byte noun);
- bool matchCommand(const Command &command, byte verb, byte noun, uint *actions = nullptr) const;
- void doActions(const Command &command, byte noun, byte offset);
- bool doOneCommand(const Commands &commands, byte verb, byte noun);
- void doAllCommands(const Commands &commands, byte verb, byte noun);
-
const AdlGameDescription *_gameDescription;
bool _isRestarting, _isRestoring;
byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 6e1e31d..c775044 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -239,11 +239,12 @@ void HiRes1Engine::initState() {
// Load room data from executable
_state.rooms.clear();
+ _roomDesc.clear();
f.seek(IDI_HR1_OFS_ROOMS);
for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
Room room;
f.readByte();
- room.description = f.readByte();
+ _roomDesc.push_back(f.readByte());
for (uint j = 0; j < 6; ++j)
room.connections[j] = f.readByte();
room.picture = f.readByte();
@@ -313,6 +314,16 @@ void HiRes1Engine::printMessage(uint idx, bool wait) const {
AdlEngine::printMessage(idx, wait);
}
+void HiRes1Engine::showRoom() const {
+ if (!_state.isDark) {
+ drawPic(getCurRoom().curPicture);
+ drawItems();
+ }
+
+ _display->updateHiResScreen();
+ printMessage(_roomDesc[_state.room - 1], false);
+}
+
void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
// This draws a four-connected line
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 25f4744..422118d 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -97,8 +97,9 @@ private:
void loadData();
void initState();
void restartGame();
- void drawPic(byte pic, Common::Point pos) const;
+ void drawPic(byte pic, Common::Point pos = Common::Point()) const;
void printMessage(uint idx, bool wait = true) const;
+ void showRoom() const;
void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
@@ -106,6 +107,8 @@ private:
struct {
Common::String pressReturn;
} _gameStrings;
+
+ Common::Array<byte> _roomDesc;
};
} // End of namespace Adl
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 1831266..44abc22 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -73,6 +73,9 @@ void HiRes2Engine::restartGame() {
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
}
+void HiRes2Engine::showRoom() const {
+}
+
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes2Engine(syst, gd);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 60c6ca1..e37af5a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -56,6 +56,7 @@ private:
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos) const;
+ void showRoom() const;
};
} // End of namespace Adl
Commit: c44f18a818c36bf714cf59b1a56589b138842503
https://github.com/scummvm/scummvm/commit/c44f18a818c36bf714cf59b1a56589b138842503
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load hires2 room data
Changed paths:
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index df917b1..abdbaff 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -80,6 +80,9 @@ struct AdlGameDescription;
struct Room {
byte description;
byte connections[6];
+ byte track;
+ byte sector;
+ byte offset;
byte picture;
byte curPicture;
};
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c775044..4bdf47a 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -242,7 +242,7 @@ void HiRes1Engine::initState() {
_roomDesc.clear();
f.seek(IDI_HR1_OFS_ROOMS);
for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
- Room room;
+ Room room = { };
f.readByte();
_roomDesc.push_back(f.readByte());
for (uint j = 0; j < 6; ++j)
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 44abc22..4f8ba48 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -64,6 +64,27 @@ void HiRes2Engine::loadData() {
}
void HiRes2Engine::initState() {
+ Common::File f;
+
+ if (!f.open(IDS_HR2_DISK_IMAGE))
+ error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+ _state.rooms.clear();
+ f.seek(IDI_HR2_OFS_ROOMS);
+ for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
+ Room room = { };
+ f.readByte(); // number
+ for (uint j = 0; j < 6; ++j)
+ room.connections[j] = f.readByte();
+ room.track = f.readByte();
+ room.sector = f.readByte();
+ room.offset = f.readByte();
+ f.readByte(); // always 1, possibly disk?
+ room.picture = f.readByte();
+ room.curPicture = f.readByte();
+ f.readByte(); // always 1, possibly disk?
+ _state.rooms.push_back(room);
+ }
}
void HiRes2Engine::restartGame() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index e37af5a..01bb29f 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -44,6 +44,8 @@ namespace Adl {
#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
#define IDI_HR2_OFS_VERBS T(0x19)
#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
+#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
+#define IDI_HR2_NUM_ROOMS 135
class HiRes2Engine : public AdlEngine {
public:
Commit: 641d87f7524781dd1fc7e014e7c8f5bf361eca09
https://github.com/scummvm/scummvm/commit/641d87f7524781dd1fc7e014e7c8f5bf361eca09
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load (some) hires2 strings
Changed paths:
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index abdbaff..d0da3bf 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -194,11 +194,10 @@ protected:
struct {
Common::String enterCommand;
- Common::String dontHaveIt;
- Common::String gettingDark;
Common::String verbError;
Common::String nounError;
Common::String playAgain;
+ Common::String pressReturn;
} _strings;
struct {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 4bdf47a..98e33ab 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -158,12 +158,10 @@ void HiRes1Engine::loadData() {
// Load other strings from executable
_strings.enterCommand = readStringAt(f, IDI_HR1_OFS_STR_ENTER_COMMAND);
- _strings.dontHaveIt = readStringAt(f, IDI_HR1_OFS_STR_DONT_HAVE_IT);
- _strings.gettingDark = readStringAt(f, IDI_HR1_OFS_STR_GETTING_DARK);
_strings.verbError = readStringAt(f, IDI_HR1_OFS_STR_VERB_ERROR);
_strings.nounError = readStringAt(f, IDI_HR1_OFS_STR_NOUN_ERROR);
_strings.playAgain = readStringAt(f, IDI_HR1_OFS_STR_PLAY_AGAIN);
- _gameStrings.pressReturn = readStringAt(f, IDI_HR1_OFS_STR_PRESS_RETURN);
+ _strings.pressReturn = readStringAt(f, IDI_HR1_OFS_STR_PRESS_RETURN);
// Set message IDs
_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
@@ -279,7 +277,7 @@ void HiRes1Engine::initState() {
void HiRes1Engine::restartGame() {
initState();
- _display->printString(_gameStrings.pressReturn);
+ _display->printString(_strings.pressReturn);
inputString(); // Missing in the original
_display->printAsciiString("\r\r\r\r\r");
}
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 422118d..02cec01 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -104,10 +104,6 @@ private:
void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
- struct {
- Common::String pressReturn;
- } _gameStrings;
-
Common::Array<byte> _roomDesc;
};
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 4f8ba48..1c43771 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -56,6 +56,35 @@ void HiRes2Engine::loadData() {
if (!f.open(IDS_HR2_DISK_IMAGE))
error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+ for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
+ f.seek(IDI_HR2_OFS_MESSAGES + i * 4);
+ byte track = f.readByte();
+ byte sector = f.readByte();
+ byte offset = f.readByte();
+ // One more byte follows, disk?
+
+ uint diskOffset = TSO(track, sector, offset);
+
+ Common::String str;
+
+ if (diskOffset != 0)
+ str = readStringAt(f, TSO(track, sector, offset), 0xff);
+
+ _messages.push_back(str);
+ }
+
+ _strings.enterCommand = readStringAt(f, IDI_HR2_OFS_STR_ENTER_COMMAND);
+ _strings.verbError = readStringAt(f, IDI_HR2_OFS_STR_VERB_ERROR);
+ _strings.nounError = readStringAt(f, IDI_HR2_OFS_STR_NOUN_ERROR);
+ _strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
+ _strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
+
+ _messageIds.cantGoThere = IDI_HR2_MSG_CANT_GO_THERE;
+ _messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
+ _messageIds.itemDoesntMove = IDI_HR2_MSG_ITEM_DOESNT_MOVE;
+ _messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
+ _messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
+
f.seek(IDI_HR2_OFS_VERBS);
loadWords(f, _verbs);
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 01bb29f..05926ee 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -45,7 +45,23 @@ namespace Adl {
#define IDI_HR2_OFS_VERBS T(0x19)
#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
+#define IDI_HR2_OFS_MESSAGES TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+
#define IDI_HR2_NUM_ROOMS 135
+#define IDI_HR2_NUM_MESSAGES 254
+
+// Messages used outside of scripts
+#define IDI_HR2_MSG_CANT_GO_THERE 123
+#define IDI_HR2_MSG_DONT_UNDERSTAND 19
+#define IDI_HR2_MSG_ITEM_DOESNT_MOVE 242
+#define IDI_HR2_MSG_ITEM_NOT_HERE 4
+#define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
+
+#define IDI_HR2_OFS_STR_ENTER_COMMAND TSO(0x1a, 0x1, 0xbc)
+#define IDI_HR2_OFS_STR_VERB_ERROR TSO(0x1a, 0x1, 0x4f)
+#define IDI_HR2_OFS_STR_NOUN_ERROR TSO(0x1a, 0x1, 0x8e)
+#define IDI_HR2_OFS_STR_PLAY_AGAIN TSO(0x1a, 0x8, 0x25)
+#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
class HiRes2Engine : public AdlEngine {
public:
Commit: 930bdcfa9101e37b984072102a8b8ef0a25afbf6
https://github.com/scummvm/scummvm/commit/930bdcfa9101e37b984072102a8b8ef0a25afbf6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires2 PIC drawing
Changed paths:
A engines/adl/picture.cpp
A engines/adl/picture.h
engines/adl/display.cpp
engines/adl/display.h
engines/adl/hires2.cpp
engines/adl/module.mk
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 6342504..3795973 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -219,9 +219,24 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
error("Failed to read frame buffer");
}
+void Display::putPixelRaw(const Common::Point &p, byte color) {
+ byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+ color ^= *b;
+ color &= 0x80 | (1 << (p.x % 7));
+ *b ^= color;
+}
+
void Display::putPixel(const Common::Point &p, byte color) {
byte offset = p.x / 7;
+ byte mask = 0x80 | (1 << (p.x % 7));
+ // Since white and black are in both palettes, we leave
+ // the palette bit alone
+ if ((color & 0x7f) == 0x7f || (color & 0x7f) == 0)
+ mask &= 0x7f;
+
+ // Adjust colors starting with bits '01' or '10' for
+ // odd offsets
if (offset & 1) {
byte c = color << 1;
if (c >= 0x40 && c < 0xc0)
@@ -230,10 +245,15 @@ void Display::putPixel(const Common::Point &p, byte color) {
byte *b = _frameBuf + p.y * DISPLAY_PITCH + offset;
color ^= *b;
- color &= 1 << (p.x % 7);
+ color &= mask;
*b ^= color;
}
+bool Display::getPixelBit(const Common::Point &p) const {
+ byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+ return *b & (1 << (p.x % 7));
+}
+
void Display::clear(byte color) {
byte val = 0;
diff --git a/engines/adl/display.h b/engines/adl/display.h
index ff01e3f..67d8bf4 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -61,7 +61,9 @@ public:
// Graphics
void loadFrameBuffer(Common::ReadStream &stream);
+ void putPixelRaw(const Common::Point &p, byte color);
void putPixel(const Common::Point &p, byte color);
+ bool getPixelBit(const Common::Point &p) const;
void clear(byte color);
// Text
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 1c43771..c36e151 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -28,6 +28,7 @@
#include "adl/hires2.h"
#include "adl/display.h"
+#include "adl/picture.h"
namespace Adl {
@@ -121,9 +122,22 @@ void HiRes2Engine::restartGame() {
}
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
+ // Temp hack
+ PictureD test(*_display);
+
+ Common::File f;
+
+ if (!f.open(IDS_HR2_DISK_IMAGE))
+ error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+
+ f.seek(0x1000);
+
+ test.draw(f);
}
void HiRes2Engine::showRoom() const {
+ drawPic(0, Common::Point());
+ _display->updateHiResScreen();
}
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index de69b52..8162e51 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -5,7 +5,8 @@ MODULE_OBJS := \
detection.o \
display.o \
hires1.o \
- hires2.o
+ hires2.o \
+ picture.o
MODULE_DIRS += \
engines/adl
diff --git a/engines/adl/picture.cpp b/engines/adl/picture.cpp
new file mode 100644
index 0000000..567165a
--- /dev/null
+++ b/engines/adl/picture.cpp
@@ -0,0 +1,298 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/picture.h"
+
+#define MIN_COMMAND 0xe0
+
+namespace Adl {
+
+#define NUM_PATTERNS 22
+#define PATTERN_LEN 4
+static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
+ { 0x00, 0x00, 0x00, 0x00 },
+ { 0x80, 0x80, 0x80, 0x80 },
+ { 0xff, 0xff, 0xff, 0xff },
+ { 0x7f, 0x7f, 0x7f, 0x7f },
+ { 0x2a, 0x55, 0x2a, 0x55 },
+ { 0xaa, 0xd5, 0xaa, 0xd5 },
+ { 0x55, 0x2a, 0x55, 0x2a },
+ { 0xd5, 0xaa, 0xd5, 0xaa },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 },
+ { 0x22, 0x44, 0x08, 0x11 },
+ { 0xa2, 0xc4, 0x88, 0x91 },
+ { 0x11, 0x22, 0x44, 0x08 },
+ { 0x91, 0xa2, 0xc4, 0x88 },
+ { 0x6e, 0x5d, 0x3b, 0x77 },
+ { 0xee, 0xdd, 0xbb, 0xf7 },
+ { 0x5d, 0x3b, 0x77, 0x6e },
+ { 0xdd, 0xbb, 0xf7, 0xee },
+ { 0x66, 0x4c, 0x19, 0x33 },
+ { 0xe6, 0xcc, 0x99, 0xb3 },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 }
+};
+
+#define CHECK_COMMAND(X) \
+ do { \
+ if ((X) >= MIN_COMMAND) { \
+ pic.seek(-1, SEEK_CUR); \
+ return; \
+ } \
+ } while (0)
+
+#define READ_BYTE(b) \
+ do { \
+ b = pic.readByte(); \
+ if (pic.eos() || pic.err()) \
+ return; \
+ CHECK_COMMAND(b); \
+ } while (0)
+
+#define READ_POINT(p) \
+ do { \
+ READ_BYTE(p.x); \
+ p.x <<= 1; \
+ READ_BYTE(p.y); \
+ } while (0)
+
+// Draws a four-connected line
+void PictureD::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+ int16 deltaX = p2.x - p1.x;
+ int8 xStep = 1;
+
+ if (deltaX < 0) {
+ deltaX = -deltaX;
+ xStep = -1;
+ }
+
+ int16 deltaY = p2.y - p1.y;
+ int8 yStep = -1;
+
+ if (deltaY > 0) {
+ deltaY = -deltaY;
+ yStep = 1;
+ }
+
+ Common::Point p(p1);
+ int16 steps = deltaX - deltaY + 1;
+ int16 err = deltaX + deltaY;
+
+ while (true) {
+ _display.putPixel(p, color);
+
+ if (--steps == 0)
+ return;
+
+ if (err < 0) {
+ p.y += yStep;
+ err += deltaX;
+ } else {
+ p.x += xStep;
+ err += deltaY;
+ }
+ }
+}
+
+void PictureD::clear() {
+ _display.clear(0xff);
+ _color = 0;
+}
+
+void PictureD::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+ Common::Point p;
+
+ READ_POINT(p);
+
+ if (yFirst)
+ goto doYStep;
+
+ while (true) {
+ int16 n;
+
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+
+ n <<= 1;
+ drawLine(p, Common::Point(n, p.y), _color);
+ p.x = n;
+
+doYStep:
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+ drawLine(p, Common::Point(p.x, n), _color);
+
+ _display.putPixel(Common::Point(p.x + 1, p.y), _color);
+ drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
+
+ p.y = n;
+ }
+}
+
+void PictureD::drawRelativeLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2(p1);
+
+ byte n;
+ READ_BYTE(n);
+
+ byte h = (n & 0x70) >> 4;
+ byte l = n & 7;
+
+ if (n & 0x80)
+ p2.x -= (h << 1);
+ else
+ p2.x += (h << 1);
+
+ if (n & 8)
+ p2.y -= l;
+ else
+ p2.y += l;
+
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+void PictureD::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2;
+
+ READ_POINT(p2);
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+static byte getPatternColor(const Common::Point &p, byte pattern) {
+ if (pattern >= NUM_PATTERNS)
+ error("Invalid fill pattern %i encountered", pattern);
+
+ byte offset = (p.y & 1) << 1;
+ offset += (p.x / 7) & 3;
+
+ return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void PictureD::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
+ const byte color = getPatternColor(p, pattern);
+ _display.putPixelRaw(p, color);
+
+ Common::Point q(p);
+ byte c = color;
+
+ while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 0)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+
+ q = p;
+ c = color;
+ while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 6)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+}
+
+// Basic flood fill
+void PictureD::fill(Common::SeekableReadStream &pic) {
+ byte pattern;
+ READ_BYTE(pattern);
+
+ while (true) {
+ Common::Point p;
+ READ_POINT(p);
+
+ bool stopBit = !_display.getPixelBit(p);
+
+ while (--p.y >= 0) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ }
+
+ while (++p.y < DISPLAY_HEIGHT) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ fillRow(p, stopBit, pattern);
+ }
+ }
+}
+
+void PictureD::draw(Common::SeekableReadStream &pic) {
+ while (true) {
+ byte opcode = pic.readByte();
+
+ if (pic.eos() || pic.err())
+ error("Error reading picture");
+
+ switch (opcode) {
+ case 0xe0:
+ drawCorners(pic, false);
+ break;
+ case 0xe1:
+ drawCorners(pic, true);
+ break;
+ case 0xe2:
+ drawRelativeLines(pic);
+ break;
+ case 0xe3:
+ drawAbsoluteLines(pic);
+ break;
+ case 0xe4:
+ fill(pic);
+ break;
+ case 0xe5:
+ clear();
+ break;
+ case 0xff:
+ return;
+ default:
+ error("Invalid pic opcode %02x", opcode);
+ }
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/picture.h b/engines/adl/picture.h
new file mode 100644
index 0000000..990c856
--- /dev/null
+++ b/engines/adl/picture.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_PICTURE_H
+#define ADL_PICTURE_H
+
+namespace Common{
+class SeekableReadStream;
+class Point;
+}
+
+namespace Adl {
+
+class Display;
+
+class PictureD {
+public:
+ PictureD(Display &display) : _display(display) { }
+
+ void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
+ void draw(Common::SeekableReadStream &pic);
+
+private:
+ void clear();
+ void drawCorners(Common::SeekableReadStream &pic, bool yFirst);
+ void drawRelativeLines(Common::SeekableReadStream &pic);
+ void drawAbsoluteLines(Common::SeekableReadStream &pic);
+ void fillRow(const Common::Point &p, bool fillBit, byte pattern);
+ void fill(Common::SeekableReadStream &pic);
+
+ Display &_display;
+ byte _color;
+};
+
+} // End of namespace Adl
+
+#endif
Commit: 60892c91a5455f1c490c1c1016a9149b6d3a2db2
https://github.com/scummvm/scummvm/commit/60892c91a5455f1c490c1c1016a9149b6d3a2db2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Rename PictureD to Graphics
Changed paths:
A engines/adl/graphics.cpp
A engines/adl/graphics.h
R engines/adl/picture.cpp
R engines/adl/picture.h
engines/adl/hires2.cpp
engines/adl/module.mk
diff --git a/engines/adl/graphics.cpp b/engines/adl/graphics.cpp
new file mode 100644
index 0000000..8e8117d
--- /dev/null
+++ b/engines/adl/graphics.cpp
@@ -0,0 +1,298 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+#define MIN_COMMAND 0xe0
+
+namespace Adl {
+
+#define NUM_PATTERNS 22
+#define PATTERN_LEN 4
+static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
+ { 0x00, 0x00, 0x00, 0x00 },
+ { 0x80, 0x80, 0x80, 0x80 },
+ { 0xff, 0xff, 0xff, 0xff },
+ { 0x7f, 0x7f, 0x7f, 0x7f },
+ { 0x2a, 0x55, 0x2a, 0x55 },
+ { 0xaa, 0xd5, 0xaa, 0xd5 },
+ { 0x55, 0x2a, 0x55, 0x2a },
+ { 0xd5, 0xaa, 0xd5, 0xaa },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 },
+ { 0x22, 0x44, 0x08, 0x11 },
+ { 0xa2, 0xc4, 0x88, 0x91 },
+ { 0x11, 0x22, 0x44, 0x08 },
+ { 0x91, 0xa2, 0xc4, 0x88 },
+ { 0x6e, 0x5d, 0x3b, 0x77 },
+ { 0xee, 0xdd, 0xbb, 0xf7 },
+ { 0x5d, 0x3b, 0x77, 0x6e },
+ { 0xdd, 0xbb, 0xf7, 0xee },
+ { 0x66, 0x4c, 0x19, 0x33 },
+ { 0xe6, 0xcc, 0x99, 0xb3 },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 }
+};
+
+#define CHECK_COMMAND(X) \
+ do { \
+ if ((X) >= MIN_COMMAND) { \
+ pic.seek(-1, SEEK_CUR); \
+ return; \
+ } \
+ } while (0)
+
+#define READ_BYTE(b) \
+ do { \
+ b = pic.readByte(); \
+ if (pic.eos() || pic.err()) \
+ return; \
+ CHECK_COMMAND(b); \
+ } while (0)
+
+#define READ_POINT(p) \
+ do { \
+ READ_BYTE(p.x); \
+ p.x <<= 1; \
+ READ_BYTE(p.y); \
+ } while (0)
+
+// Draws a four-connected line
+void Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+ int16 deltaX = p2.x - p1.x;
+ int8 xStep = 1;
+
+ if (deltaX < 0) {
+ deltaX = -deltaX;
+ xStep = -1;
+ }
+
+ int16 deltaY = p2.y - p1.y;
+ int8 yStep = -1;
+
+ if (deltaY > 0) {
+ deltaY = -deltaY;
+ yStep = 1;
+ }
+
+ Common::Point p(p1);
+ int16 steps = deltaX - deltaY + 1;
+ int16 err = deltaX + deltaY;
+
+ while (true) {
+ _display.putPixel(p, color);
+
+ if (--steps == 0)
+ return;
+
+ if (err < 0) {
+ p.y += yStep;
+ err += deltaX;
+ } else {
+ p.x += xStep;
+ err += deltaY;
+ }
+ }
+}
+
+void Graphics::clear() {
+ _display.clear(0xff);
+ _color = 0;
+}
+
+void Graphics::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+ Common::Point p;
+
+ READ_POINT(p);
+
+ if (yFirst)
+ goto doYStep;
+
+ while (true) {
+ int16 n;
+
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+
+ n <<= 1;
+ drawLine(p, Common::Point(n, p.y), _color);
+ p.x = n;
+
+doYStep:
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+ drawLine(p, Common::Point(p.x, n), _color);
+
+ _display.putPixel(Common::Point(p.x + 1, p.y), _color);
+ drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
+
+ p.y = n;
+ }
+}
+
+void Graphics::drawRelativeLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2(p1);
+
+ byte n;
+ READ_BYTE(n);
+
+ byte h = (n & 0x70) >> 4;
+ byte l = n & 7;
+
+ if (n & 0x80)
+ p2.x -= (h << 1);
+ else
+ p2.x += (h << 1);
+
+ if (n & 8)
+ p2.y -= l;
+ else
+ p2.y += l;
+
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+void Graphics::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2;
+
+ READ_POINT(p2);
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+static byte getPatternColor(const Common::Point &p, byte pattern) {
+ if (pattern >= NUM_PATTERNS)
+ error("Invalid fill pattern %i encountered", pattern);
+
+ byte offset = (p.y & 1) << 1;
+ offset += (p.x / 7) & 3;
+
+ return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void Graphics::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
+ const byte color = getPatternColor(p, pattern);
+ _display.putPixelRaw(p, color);
+
+ Common::Point q(p);
+ byte c = color;
+
+ while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 0)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+
+ q = p;
+ c = color;
+ while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 6)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+}
+
+// Basic flood fill
+void Graphics::fill(Common::SeekableReadStream &pic) {
+ byte pattern;
+ READ_BYTE(pattern);
+
+ while (true) {
+ Common::Point p;
+ READ_POINT(p);
+
+ bool stopBit = !_display.getPixelBit(p);
+
+ while (--p.y >= 0) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ }
+
+ while (++p.y < DISPLAY_HEIGHT) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ fillRow(p, stopBit, pattern);
+ }
+ }
+}
+
+void Graphics::draw(Common::SeekableReadStream &pic) {
+ while (true) {
+ byte opcode = pic.readByte();
+
+ if (pic.eos() || pic.err())
+ error("Error reading picture");
+
+ switch (opcode) {
+ case 0xe0:
+ drawCorners(pic, false);
+ break;
+ case 0xe1:
+ drawCorners(pic, true);
+ break;
+ case 0xe2:
+ drawRelativeLines(pic);
+ break;
+ case 0xe3:
+ drawAbsoluteLines(pic);
+ break;
+ case 0xe4:
+ fill(pic);
+ break;
+ case 0xe5:
+ clear();
+ break;
+ case 0xff:
+ return;
+ default:
+ error("Invalid pic opcode %02x", opcode);
+ }
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
new file mode 100644
index 0000000..9c47820
--- /dev/null
+++ b/engines/adl/graphics.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_PICTURE_H
+#define ADL_PICTURE_H
+
+namespace Common{
+class SeekableReadStream;
+class Point;
+}
+
+namespace Adl {
+
+class Display;
+
+class Graphics {
+public:
+ Graphics(Display &display) : _display(display) { }
+
+ void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
+ void draw(Common::SeekableReadStream &pic);
+
+private:
+ void clear();
+ void drawCorners(Common::SeekableReadStream &pic, bool yFirst);
+ void drawRelativeLines(Common::SeekableReadStream &pic);
+ void drawAbsoluteLines(Common::SeekableReadStream &pic);
+ void fillRow(const Common::Point &p, bool fillBit, byte pattern);
+ void fill(Common::SeekableReadStream &pic);
+
+ Display &_display;
+ byte _color;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index c36e151..7bdfde5 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -28,7 +28,7 @@
#include "adl/hires2.h"
#include "adl/display.h"
-#include "adl/picture.h"
+#include "adl/graphics.h"
namespace Adl {
@@ -123,7 +123,7 @@ void HiRes2Engine::restartGame() {
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
// Temp hack
- PictureD test(*_display);
+ Graphics test(*_display);
Common::File f;
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 8162e51..6901279 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,9 +4,9 @@ MODULE_OBJS := \
adl.o \
detection.o \
display.o \
+ graphics.o \
hires1.o \
- hires2.o \
- picture.o
+ hires2.o
MODULE_DIRS += \
engines/adl
diff --git a/engines/adl/picture.cpp b/engines/adl/picture.cpp
deleted file mode 100644
index 567165a..0000000
--- a/engines/adl/picture.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#include "common/stream.h"
-#include "common/rect.h"
-#include "common/textconsole.h"
-
-#include "adl/display.h"
-#include "adl/picture.h"
-
-#define MIN_COMMAND 0xe0
-
-namespace Adl {
-
-#define NUM_PATTERNS 22
-#define PATTERN_LEN 4
-static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
- { 0x00, 0x00, 0x00, 0x00 },
- { 0x80, 0x80, 0x80, 0x80 },
- { 0xff, 0xff, 0xff, 0xff },
- { 0x7f, 0x7f, 0x7f, 0x7f },
- { 0x2a, 0x55, 0x2a, 0x55 },
- { 0xaa, 0xd5, 0xaa, 0xd5 },
- { 0x55, 0x2a, 0x55, 0x2a },
- { 0xd5, 0xaa, 0xd5, 0xaa },
- { 0x33, 0x66, 0x4c, 0x19 },
- { 0xb3, 0xe6, 0xcc, 0x99 },
- { 0x22, 0x44, 0x08, 0x11 },
- { 0xa2, 0xc4, 0x88, 0x91 },
- { 0x11, 0x22, 0x44, 0x08 },
- { 0x91, 0xa2, 0xc4, 0x88 },
- { 0x6e, 0x5d, 0x3b, 0x77 },
- { 0xee, 0xdd, 0xbb, 0xf7 },
- { 0x5d, 0x3b, 0x77, 0x6e },
- { 0xdd, 0xbb, 0xf7, 0xee },
- { 0x66, 0x4c, 0x19, 0x33 },
- { 0xe6, 0xcc, 0x99, 0xb3 },
- { 0x33, 0x66, 0x4c, 0x19 },
- { 0xb3, 0xe6, 0xcc, 0x99 }
-};
-
-#define CHECK_COMMAND(X) \
- do { \
- if ((X) >= MIN_COMMAND) { \
- pic.seek(-1, SEEK_CUR); \
- return; \
- } \
- } while (0)
-
-#define READ_BYTE(b) \
- do { \
- b = pic.readByte(); \
- if (pic.eos() || pic.err()) \
- return; \
- CHECK_COMMAND(b); \
- } while (0)
-
-#define READ_POINT(p) \
- do { \
- READ_BYTE(p.x); \
- p.x <<= 1; \
- READ_BYTE(p.y); \
- } while (0)
-
-// Draws a four-connected line
-void PictureD::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
- int16 deltaX = p2.x - p1.x;
- int8 xStep = 1;
-
- if (deltaX < 0) {
- deltaX = -deltaX;
- xStep = -1;
- }
-
- int16 deltaY = p2.y - p1.y;
- int8 yStep = -1;
-
- if (deltaY > 0) {
- deltaY = -deltaY;
- yStep = 1;
- }
-
- Common::Point p(p1);
- int16 steps = deltaX - deltaY + 1;
- int16 err = deltaX + deltaY;
-
- while (true) {
- _display.putPixel(p, color);
-
- if (--steps == 0)
- return;
-
- if (err < 0) {
- p.y += yStep;
- err += deltaX;
- } else {
- p.x += xStep;
- err += deltaY;
- }
- }
-}
-
-void PictureD::clear() {
- _display.clear(0xff);
- _color = 0;
-}
-
-void PictureD::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
- Common::Point p;
-
- READ_POINT(p);
-
- if (yFirst)
- goto doYStep;
-
- while (true) {
- int16 n;
-
- READ_BYTE(n);
-
- _display.putPixel(p, _color);
-
- n <<= 1;
- drawLine(p, Common::Point(n, p.y), _color);
- p.x = n;
-
-doYStep:
- READ_BYTE(n);
-
- _display.putPixel(p, _color);
- drawLine(p, Common::Point(p.x, n), _color);
-
- _display.putPixel(Common::Point(p.x + 1, p.y), _color);
- drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
-
- p.y = n;
- }
-}
-
-void PictureD::drawRelativeLines(Common::SeekableReadStream &pic) {
- Common::Point p1;
-
- READ_POINT(p1);
- _display.putPixel(p1, _color);
-
- while (true) {
- Common::Point p2(p1);
-
- byte n;
- READ_BYTE(n);
-
- byte h = (n & 0x70) >> 4;
- byte l = n & 7;
-
- if (n & 0x80)
- p2.x -= (h << 1);
- else
- p2.x += (h << 1);
-
- if (n & 8)
- p2.y -= l;
- else
- p2.y += l;
-
- drawLine(p1, p2, _color);
- p1 = p2;
- }
-}
-
-void PictureD::drawAbsoluteLines(Common::SeekableReadStream &pic) {
- Common::Point p1;
-
- READ_POINT(p1);
- _display.putPixel(p1, _color);
-
- while (true) {
- Common::Point p2;
-
- READ_POINT(p2);
- drawLine(p1, p2, _color);
- p1 = p2;
- }
-}
-
-static byte getPatternColor(const Common::Point &p, byte pattern) {
- if (pattern >= NUM_PATTERNS)
- error("Invalid fill pattern %i encountered", pattern);
-
- byte offset = (p.y & 1) << 1;
- offset += (p.x / 7) & 3;
-
- return fillPatterns[pattern][offset % PATTERN_LEN];
-}
-
-void PictureD::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
- const byte color = getPatternColor(p, pattern);
- _display.putPixelRaw(p, color);
-
- Common::Point q(p);
- byte c = color;
-
- while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
- if ((q.x % 7) == 0)
- c = getPatternColor(q, pattern);
- _display.putPixelRaw(q, c);
- }
-
- q = p;
- c = color;
- while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
- if ((q.x % 7) == 6)
- c = getPatternColor(q, pattern);
- _display.putPixelRaw(q, c);
- }
-}
-
-// Basic flood fill
-void PictureD::fill(Common::SeekableReadStream &pic) {
- byte pattern;
- READ_BYTE(pattern);
-
- while (true) {
- Common::Point p;
- READ_POINT(p);
-
- bool stopBit = !_display.getPixelBit(p);
-
- while (--p.y >= 0) {
- if (_display.getPixelBit(p) == stopBit)
- break;
- if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
- break;
- }
-
- while (++p.y < DISPLAY_HEIGHT) {
- if (_display.getPixelBit(p) == stopBit)
- break;
- if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
- break;
- fillRow(p, stopBit, pattern);
- }
- }
-}
-
-void PictureD::draw(Common::SeekableReadStream &pic) {
- while (true) {
- byte opcode = pic.readByte();
-
- if (pic.eos() || pic.err())
- error("Error reading picture");
-
- switch (opcode) {
- case 0xe0:
- drawCorners(pic, false);
- break;
- case 0xe1:
- drawCorners(pic, true);
- break;
- case 0xe2:
- drawRelativeLines(pic);
- break;
- case 0xe3:
- drawAbsoluteLines(pic);
- break;
- case 0xe4:
- fill(pic);
- break;
- case 0xe5:
- clear();
- break;
- case 0xff:
- return;
- default:
- error("Invalid pic opcode %02x", opcode);
- }
- }
-}
-
-} // End of namespace Adl
diff --git a/engines/adl/picture.h b/engines/adl/picture.h
deleted file mode 100644
index 990c856..0000000
--- a/engines/adl/picture.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ADL_PICTURE_H
-#define ADL_PICTURE_H
-
-namespace Common{
-class SeekableReadStream;
-class Point;
-}
-
-namespace Adl {
-
-class Display;
-
-class PictureD {
-public:
- PictureD(Display &display) : _display(display) { }
-
- void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
- void draw(Common::SeekableReadStream &pic);
-
-private:
- void clear();
- void drawCorners(Common::SeekableReadStream &pic, bool yFirst);
- void drawRelativeLines(Common::SeekableReadStream &pic);
- void drawAbsoluteLines(Common::SeekableReadStream &pic);
- void fillRow(const Common::Point &p, bool fillBit, byte pattern);
- void fill(Common::SeekableReadStream &pic);
-
- Display &_display;
- byte _color;
-};
-
-} // End of namespace Adl
-
-#endif
Commit: 148814b2a6c3dffb53b8d902eb7fcfb68110bea3
https://github.com/scummvm/scummvm/commit/148814b2a6c3dffb53b8d902eb7fcfb68110bea3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Move hires1 drawing functions into class
Changed paths:
A engines/adl/graphics_v1.cpp
A engines/adl/graphics_v2.cpp
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/graphics.cpp
engines/adl/graphics.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
engines/adl/module.mk
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 47623d4..a17339f 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -38,16 +38,19 @@
#include "adl/adl.h"
#include "adl/display.h"
#include "adl/detection.h"
+#include "adl/graphics.h"
namespace Adl {
AdlEngine::~AdlEngine() {
delete _display;
+ delete _graphics;
}
AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
Engine(syst),
_display(nullptr),
+ _graphics(nullptr),
_gameDescription(gd),
_isRestarting(false),
_isRestoring(false),
@@ -82,6 +85,14 @@ Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint
return readString(stream, until);
}
+Common::File *AdlEngine::openFile(const Common::String &name) const {
+ Common::File *f = new Common::File();
+ if (!f->open(name))
+ error("Error opening '%s'", name.c_str());
+
+ return f;
+}
+
void AdlEngine::printMessage(uint idx, bool wait) const {
Common::String msg = _messages[idx - 1];
wordWrap(msg);
@@ -281,10 +292,7 @@ void AdlEngine::drawItems() const {
if (item->state == IDI_ITEM_MOVED) {
if (getCurRoom().picture == getCurRoom().curPicture) {
const Common::Point &p = _itemOffsets[dropped];
- if (item->isLineArt)
- drawLineArt(_lineArt[item->picture - 1], p);
- else
- drawPic(item->picture, p);
+ drawItem(*item, p);
++dropped;
}
continue;
@@ -294,61 +302,13 @@ void AdlEngine::drawItems() const {
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
if (*pic == getCurRoom().curPicture) {
- if (item->isLineArt)
- drawLineArt(_lineArt[item->picture - 1], item->position);
- else
- drawPic(item->picture, item->position);
+ drawItem(*item, item->position);
continue;
}
}
}
}
-void AdlEngine::drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const {
- if (bits & 4)
- _display->putPixel(p, color);
-
- bits += quadrant;
-
- if (bits & 1)
- p.x += (bits & 2 ? -1 : 1);
- else
- p.y += (bits & 2 ? 1 : -1);
-}
-
-void AdlEngine::drawLineArt(const Common::Array<byte> &lineArt, const 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,
- 0xff
- };
-
- byte quadrant = rotation >> 4;
- rotation &= 0xf;
- byte xStep = stepping[rotation];
- byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
-
- Common::Point p(pos);
-
- for (uint i = 0; i < lineArt.size(); ++i) {
- byte b = lineArt[i];
-
- do {
- byte xFrac = 0x80;
- byte yFrac = 0x80;
- for (uint j = 0; j < scaling; ++j) {
- if (xFrac + xStep + 1 > 255)
- drawNextPixel(p, color, b, quadrant);
- xFrac += xStep + 1;
- if (yFrac + yStep > 255)
- drawNextPixel(p, color, b, quadrant + 1);
- yFrac += yStep;
- }
- b >>= 3;
- } while (b != 0);
- }
-}
-
const Room &AdlEngine::getRoom(uint i) const {
if (i < 1 || i > _state.rooms.size())
error("Room %i out of range [1, %i]", i, _state.rooms.size());
@@ -447,7 +407,7 @@ void AdlEngine::dropItem(byte noun) {
Common::Error AdlEngine::run() {
_display = new Display();
- loadData();
+ init();
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot >= 0) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d0da3bf..d8c631e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -37,6 +37,7 @@ class SeekableReadStream;
namespace Adl {
class Display;
+class GraphicsMan;
struct AdlGameDescription;
// Conditional opcodes
@@ -142,6 +143,7 @@ protected:
Common::String readString(Common::ReadStream &stream, byte until = 0) const;
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
+ Common::File *openFile(const Common::String &name) const;
virtual void printMessage(uint idx, bool wait = true) const;
void delay(uint32 ms) const;
@@ -155,8 +157,6 @@ protected:
// Graphics
void clearScreen() const;
void drawItems() const;
- void drawNextPixel(Common::Point &p, byte color, byte bits, byte quadrant) const;
- void drawLineArt(const Common::Array<byte> &lineArt, const Common::Point &pos, byte rotation = 0, byte scaling = 1, byte color = 0x7f) const;
// Game state functions
const Room &getRoom(uint i) const;
@@ -175,6 +175,7 @@ protected:
void doAllCommands(const Commands &commands, byte verb, byte noun);
Display *_display;
+ GraphicsMan *_graphics;
// Message strings in data file
Common::Array<Common::String> _messages;
@@ -182,9 +183,6 @@ protected:
Common::Array<Picture> _pictures;
// Dropped item screen offsets
Common::Array<Common::Point> _itemOffsets;
- // Drawings consisting of horizontal and vertical lines only, but
- // supporting scaling and rotation
- Common::Array<Common::Array<byte> > _lineArt;
// <room, verb, noun, script> lists
Commands _roomCommands;
Commands _globalCommands;
@@ -213,10 +211,10 @@ protected:
private:
virtual void runIntro() const { }
- virtual void loadData() = 0;
+ virtual void init() = 0;
virtual void initState() = 0;
virtual void restartGame() = 0;
- virtual void drawPic(byte pic, Common::Point pos = Common::Point()) const = 0;
+ virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
virtual void showRoom() const = 0;
// Engine
diff --git a/engines/adl/graphics.cpp b/engines/adl/graphics.cpp
index 8e8117d..f9af442 100644
--- a/engines/adl/graphics.cpp
+++ b/engines/adl/graphics.cpp
@@ -22,67 +22,14 @@
#include "common/stream.h"
#include "common/rect.h"
-#include "common/textconsole.h"
#include "adl/display.h"
#include "adl/graphics.h"
-#define MIN_COMMAND 0xe0
-
namespace Adl {
-#define NUM_PATTERNS 22
-#define PATTERN_LEN 4
-static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
- { 0x00, 0x00, 0x00, 0x00 },
- { 0x80, 0x80, 0x80, 0x80 },
- { 0xff, 0xff, 0xff, 0xff },
- { 0x7f, 0x7f, 0x7f, 0x7f },
- { 0x2a, 0x55, 0x2a, 0x55 },
- { 0xaa, 0xd5, 0xaa, 0xd5 },
- { 0x55, 0x2a, 0x55, 0x2a },
- { 0xd5, 0xaa, 0xd5, 0xaa },
- { 0x33, 0x66, 0x4c, 0x19 },
- { 0xb3, 0xe6, 0xcc, 0x99 },
- { 0x22, 0x44, 0x08, 0x11 },
- { 0xa2, 0xc4, 0x88, 0x91 },
- { 0x11, 0x22, 0x44, 0x08 },
- { 0x91, 0xa2, 0xc4, 0x88 },
- { 0x6e, 0x5d, 0x3b, 0x77 },
- { 0xee, 0xdd, 0xbb, 0xf7 },
- { 0x5d, 0x3b, 0x77, 0x6e },
- { 0xdd, 0xbb, 0xf7, 0xee },
- { 0x66, 0x4c, 0x19, 0x33 },
- { 0xe6, 0xcc, 0x99, 0xb3 },
- { 0x33, 0x66, 0x4c, 0x19 },
- { 0xb3, 0xe6, 0xcc, 0x99 }
-};
-
-#define CHECK_COMMAND(X) \
- do { \
- if ((X) >= MIN_COMMAND) { \
- pic.seek(-1, SEEK_CUR); \
- return; \
- } \
- } while (0)
-
-#define READ_BYTE(b) \
- do { \
- b = pic.readByte(); \
- if (pic.eos() || pic.err()) \
- return; \
- CHECK_COMMAND(b); \
- } while (0)
-
-#define READ_POINT(p) \
- do { \
- READ_BYTE(p.x); \
- p.x <<= 1; \
- READ_BYTE(p.y); \
- } while (0)
-
// Draws a four-connected line
-void Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
+void GraphicsMan::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
int16 deltaX = p2.x - p1.x;
int8 xStep = 1;
@@ -119,180 +66,4 @@ void Graphics::drawLine(const Common::Point &p1, const Common::Point &p2, byte c
}
}
-void Graphics::clear() {
- _display.clear(0xff);
- _color = 0;
-}
-
-void Graphics::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
- Common::Point p;
-
- READ_POINT(p);
-
- if (yFirst)
- goto doYStep;
-
- while (true) {
- int16 n;
-
- READ_BYTE(n);
-
- _display.putPixel(p, _color);
-
- n <<= 1;
- drawLine(p, Common::Point(n, p.y), _color);
- p.x = n;
-
-doYStep:
- READ_BYTE(n);
-
- _display.putPixel(p, _color);
- drawLine(p, Common::Point(p.x, n), _color);
-
- _display.putPixel(Common::Point(p.x + 1, p.y), _color);
- drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
-
- p.y = n;
- }
-}
-
-void Graphics::drawRelativeLines(Common::SeekableReadStream &pic) {
- Common::Point p1;
-
- READ_POINT(p1);
- _display.putPixel(p1, _color);
-
- while (true) {
- Common::Point p2(p1);
-
- byte n;
- READ_BYTE(n);
-
- byte h = (n & 0x70) >> 4;
- byte l = n & 7;
-
- if (n & 0x80)
- p2.x -= (h << 1);
- else
- p2.x += (h << 1);
-
- if (n & 8)
- p2.y -= l;
- else
- p2.y += l;
-
- drawLine(p1, p2, _color);
- p1 = p2;
- }
-}
-
-void Graphics::drawAbsoluteLines(Common::SeekableReadStream &pic) {
- Common::Point p1;
-
- READ_POINT(p1);
- _display.putPixel(p1, _color);
-
- while (true) {
- Common::Point p2;
-
- READ_POINT(p2);
- drawLine(p1, p2, _color);
- p1 = p2;
- }
-}
-
-static byte getPatternColor(const Common::Point &p, byte pattern) {
- if (pattern >= NUM_PATTERNS)
- error("Invalid fill pattern %i encountered", pattern);
-
- byte offset = (p.y & 1) << 1;
- offset += (p.x / 7) & 3;
-
- return fillPatterns[pattern][offset % PATTERN_LEN];
-}
-
-void Graphics::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
- const byte color = getPatternColor(p, pattern);
- _display.putPixelRaw(p, color);
-
- Common::Point q(p);
- byte c = color;
-
- while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
- if ((q.x % 7) == 0)
- c = getPatternColor(q, pattern);
- _display.putPixelRaw(q, c);
- }
-
- q = p;
- c = color;
- while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
- if ((q.x % 7) == 6)
- c = getPatternColor(q, pattern);
- _display.putPixelRaw(q, c);
- }
-}
-
-// Basic flood fill
-void Graphics::fill(Common::SeekableReadStream &pic) {
- byte pattern;
- READ_BYTE(pattern);
-
- while (true) {
- Common::Point p;
- READ_POINT(p);
-
- bool stopBit = !_display.getPixelBit(p);
-
- while (--p.y >= 0) {
- if (_display.getPixelBit(p) == stopBit)
- break;
- if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
- break;
- }
-
- while (++p.y < DISPLAY_HEIGHT) {
- if (_display.getPixelBit(p) == stopBit)
- break;
- if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
- break;
- fillRow(p, stopBit, pattern);
- }
- }
-}
-
-void Graphics::draw(Common::SeekableReadStream &pic) {
- while (true) {
- byte opcode = pic.readByte();
-
- if (pic.eos() || pic.err())
- error("Error reading picture");
-
- switch (opcode) {
- case 0xe0:
- drawCorners(pic, false);
- break;
- case 0xe1:
- drawCorners(pic, true);
- break;
- case 0xe2:
- drawRelativeLines(pic);
- break;
- case 0xe3:
- drawAbsoluteLines(pic);
- break;
- case 0xe4:
- fill(pic);
- break;
- case 0xe5:
- clear();
- break;
- case 0xff:
- return;
- default:
- error("Invalid pic opcode %02x", opcode);
- }
- }
-}
-
} // End of namespace Adl
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index 9c47820..ec29ee0 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -32,12 +32,32 @@ namespace Adl {
class Display;
-class Graphics {
+class GraphicsMan {
public:
- Graphics(Display &display) : _display(display) { }
+ virtual ~GraphicsMan() { }
+ virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) = 0;
+protected:
+ GraphicsMan(Display &display) : _display(display) { }
void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
- void draw(Common::SeekableReadStream &pic);
+
+ Display &_display;
+};
+
+class Graphics_v1 : public GraphicsMan {
+public:
+ Graphics_v1(Display &display) : GraphicsMan(display) { }
+ void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
+ 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;
+};
+
+class Graphics_v2 : public GraphicsMan {
+public:
+ Graphics_v2(Display &display) : GraphicsMan(display), _color(0) { }
+ void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
private:
void clear();
@@ -47,7 +67,6 @@ private:
void fillRow(const Common::Point &p, bool fillBit, byte pattern);
void fill(Common::SeekableReadStream &pic);
- Display &_display;
byte _color;
};
diff --git a/engines/adl/graphics_v1.cpp b/engines/adl/graphics_v1.cpp
new file mode 100644
index 0000000..edf16b8
--- /dev/null
+++ b/engines/adl/graphics_v1.cpp
@@ -0,0 +1,120 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+namespace Adl {
+
+void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+ 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) {
+ _display.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 {
+ if (bits & 4)
+ _display.putPixel(p, color);
+
+ bits += quadrant;
+
+ if (bits & 1)
+ p.x += (bits & 2 ? -1 : 1);
+ else
+ p.y += (bits & 2 ? 1 : -1);
+}
+
+void Graphics_v1::drawCorners(Common::ReadStream &corners, const 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,
+ 0xff
+ };
+
+ byte quadrant = rotation >> 4;
+ rotation &= 0xf;
+ byte xStep = stepping[rotation];
+ byte yStep = stepping[(rotation ^ 0xf) + 1] + 1;
+
+ Common::Point p(pos);
+
+ while (true) {
+ byte b = corners.readByte();
+
+ if (corners.eos() || corners.err())
+ error("Error reading corners");
+
+ if (b == 0)
+ return;
+
+ do {
+ byte xFrac = 0x80;
+ byte yFrac = 0x80;
+ for (uint j = 0; j < scaling; ++j) {
+ if (xFrac + xStep + 1 > 255)
+ drawCornerPixel(p, color, b, quadrant);
+ xFrac += xStep + 1;
+ if (yFrac + yStep > 255)
+ drawCornerPixel(p, color, b, quadrant + 1);
+ yFrac += yStep;
+ }
+ b >>= 3;
+ } while (b != 0);
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
new file mode 100644
index 0000000..289f43e
--- /dev/null
+++ b/engines/adl/graphics_v2.cpp
@@ -0,0 +1,260 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+#include "common/rect.h"
+#include "common/textconsole.h"
+
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+namespace Adl {
+
+#define NUM_PATTERNS 22
+#define PATTERN_LEN 4
+static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
+ { 0x00, 0x00, 0x00, 0x00 },
+ { 0x80, 0x80, 0x80, 0x80 },
+ { 0xff, 0xff, 0xff, 0xff },
+ { 0x7f, 0x7f, 0x7f, 0x7f },
+ { 0x2a, 0x55, 0x2a, 0x55 },
+ { 0xaa, 0xd5, 0xaa, 0xd5 },
+ { 0x55, 0x2a, 0x55, 0x2a },
+ { 0xd5, 0xaa, 0xd5, 0xaa },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 },
+ { 0x22, 0x44, 0x08, 0x11 },
+ { 0xa2, 0xc4, 0x88, 0x91 },
+ { 0x11, 0x22, 0x44, 0x08 },
+ { 0x91, 0xa2, 0xc4, 0x88 },
+ { 0x6e, 0x5d, 0x3b, 0x77 },
+ { 0xee, 0xdd, 0xbb, 0xf7 },
+ { 0x5d, 0x3b, 0x77, 0x6e },
+ { 0xdd, 0xbb, 0xf7, 0xee },
+ { 0x66, 0x4c, 0x19, 0x33 },
+ { 0xe6, 0xcc, 0x99, 0xb3 },
+ { 0x33, 0x66, 0x4c, 0x19 },
+ { 0xb3, 0xe6, 0xcc, 0x99 }
+};
+
+#define MIN_COMMAND 0xe0
+
+#define CHECK_COMMAND(X) \
+ do { \
+ if ((X) >= MIN_COMMAND) { \
+ pic.seek(-1, SEEK_CUR); \
+ return; \
+ } \
+ } while (0)
+
+#define READ_BYTE(b) \
+ do { \
+ b = pic.readByte(); \
+ if (pic.eos() || pic.err()) \
+ error("Error reading picture"); \
+ CHECK_COMMAND(b); \
+ } while (0)
+
+#define READ_POINT(p) \
+ do { \
+ READ_BYTE(p.x); \
+ p.x <<= 1; \
+ READ_BYTE(p.y); \
+ } while (0)
+
+void Graphics_v2::clear() {
+ _display.clear(0xff);
+ _color = 0;
+}
+
+void Graphics_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
+ Common::Point p;
+
+ READ_POINT(p);
+
+ if (yFirst)
+ goto doYStep;
+
+ while (true) {
+ int16 n;
+
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+
+ n <<= 1;
+ drawLine(p, Common::Point(n, p.y), _color);
+ p.x = n;
+
+doYStep:
+ READ_BYTE(n);
+
+ _display.putPixel(p, _color);
+ drawLine(p, Common::Point(p.x, n), _color);
+
+ _display.putPixel(Common::Point(p.x + 1, p.y), _color);
+ drawLine(Common::Point(p.x + 1, p.y), Common::Point(p.x + 1, n), _color);
+
+ p.y = n;
+ }
+}
+
+void Graphics_v2::drawRelativeLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2(p1);
+
+ byte n;
+ READ_BYTE(n);
+
+ byte h = (n & 0x70) >> 4;
+ byte l = n & 7;
+
+ if (n & 0x80)
+ p2.x -= (h << 1);
+ else
+ p2.x += (h << 1);
+
+ if (n & 8)
+ p2.y -= l;
+ else
+ p2.y += l;
+
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+void Graphics_v2::drawAbsoluteLines(Common::SeekableReadStream &pic) {
+ Common::Point p1;
+
+ READ_POINT(p1);
+ _display.putPixel(p1, _color);
+
+ while (true) {
+ Common::Point p2;
+
+ READ_POINT(p2);
+ drawLine(p1, p2, _color);
+ p1 = p2;
+ }
+}
+
+static byte getPatternColor(const Common::Point &p, byte pattern) {
+ if (pattern >= NUM_PATTERNS)
+ error("Invalid fill pattern %i encountered in picture", pattern);
+
+ byte offset = (p.y & 1) << 1;
+ offset += (p.x / 7) & 3;
+
+ return fillPatterns[pattern][offset % PATTERN_LEN];
+}
+
+void Graphics_v2::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
+ const byte color = getPatternColor(p, pattern);
+ _display.putPixelRaw(p, color);
+
+ Common::Point q(p);
+ byte c = color;
+
+ while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 0)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+
+ q = p;
+ c = color;
+ while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
+ if ((q.x % 7) == 6)
+ c = getPatternColor(q, pattern);
+ _display.putPixelRaw(q, c);
+ }
+}
+
+// Basic flood fill
+void Graphics_v2::fill(Common::SeekableReadStream &pic) {
+ byte pattern;
+ READ_BYTE(pattern);
+
+ while (true) {
+ Common::Point p;
+ READ_POINT(p);
+
+ bool stopBit = !_display.getPixelBit(p);
+
+ while (--p.y >= 0) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ }
+
+ while (++p.y < DISPLAY_HEIGHT) {
+ if (_display.getPixelBit(p) == stopBit)
+ break;
+ if (_display.getPixelBit(Common::Point(p.x + 1, p.y)) == stopBit)
+ break;
+ fillRow(p, stopBit, pattern);
+ }
+ }
+}
+
+void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+ while (true) {
+ byte opcode = pic.readByte();
+
+ if (pic.eos() || pic.err())
+ error("Error reading picture");
+
+ switch (opcode) {
+ case 0xe0:
+ drawCorners(pic, false);
+ break;
+ case 0xe1:
+ drawCorners(pic, true);
+ break;
+ case 0xe2:
+ drawRelativeLines(pic);
+ break;
+ case 0xe3:
+ drawAbsoluteLines(pic);
+ break;
+ case 0xe4:
+ fill(pic);
+ break;
+ case 0xe5:
+ clear();
+ break;
+ case 0xff:
+ return;
+ default:
+ error("Invalid pic opcode %02x", opcode);
+ }
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 98e33ab..7354738 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -136,7 +136,9 @@ void HiRes1Engine::runIntro() const {
delay(2000);
}
-void HiRes1Engine::loadData() {
+void HiRes1Engine::init() {
+ _graphics = new Graphics_v1(*_display);
+
Common::File f;
if (!f.open(IDS_HR1_MESSAGES))
@@ -196,21 +198,10 @@ void HiRes1Engine::loadData() {
}
// Load right-angle line art
- f.seek(IDI_HR1_OFS_LINE_ART);
- uint16 lineArtTotal = f.readUint16LE();
- for (uint i = 0; i < lineArtTotal; ++i) {
- f.seek(IDI_HR1_OFS_LINE_ART + 2 + i * 2);
- uint16 offset = f.readUint16LE();
- f.seek(IDI_HR1_OFS_LINE_ART + offset);
-
- Common::Array<byte> lineArt;
- byte b = f.readByte();
- while (b != 0) {
- lineArt.push_back(b);
- b = f.readByte();
- }
- _lineArt.push_back(lineArt);
- }
+ f.seek(IDI_HR1_OFS_CORNERS);
+ uint16 cornersCount = f.readUint16LE();
+ for (uint i = 0; i < cornersCount; ++i)
+ _corners.push_back(IDI_HR1_OFS_CORNERS + f.readUint16LE());
if (f.eos() || f.err())
error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
@@ -290,7 +281,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
error("Failed to open file '%s'", name.c_str());
f.seek(_pictures[pic].offset);
- drawPic(f, pos);
+ _graphics->drawPic(f, pos, 0x7f);
}
void HiRes1Engine::printMessage(uint idx, bool wait) const {
@@ -312,6 +303,16 @@ void HiRes1Engine::printMessage(uint idx, bool wait) const {
AdlEngine::printMessage(idx, wait);
}
+void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
+ if (item.isLineArt) {
+ Common::File *f = openFile(IDS_HR1_EXE_1);
+ f->seek(_corners[item.picture - 1]);
+ static_cast<Graphics_v1 *>(_graphics)->drawCorners(*f, pos);
+ delete f;
+ } else
+ drawPic(item.picture, pos);
+}
+
void HiRes1Engine::showRoom() const {
if (!_state.isDark) {
drawPic(getCurRoom().curPicture);
@@ -322,82 +323,6 @@ void HiRes1Engine::showRoom() const {
printMessage(_roomDesc[_state.room - 1], false);
}
-void HiRes1Engine::drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const {
- // This draws a four-connected line
-
- int16 deltaX = p2.x - p1.x;
- int8 xStep = 1;
-
- if (deltaX < 0) {
- deltaX = -deltaX;
- xStep = -1;
- }
-
- int16 deltaY = p2.y - p1.y;
- int8 yStep = -1;
-
- if (deltaY > 0) {
- deltaY = -deltaY;
- yStep = 1;
- }
-
- Common::Point p(p1);
- int16 steps = deltaX - deltaY + 1;
- int16 err = deltaX + deltaY;
-
- while (1) {
- _display->putPixel(p, color);
-
- if (--steps == 0)
- return;
-
- if (err < 0) {
- p.y += yStep;
- err += deltaX;
- } else {
- p.x += xStep;
- err += deltaY;
- }
- }
-}
-
-void HiRes1Engine::drawPic(Common::ReadStream &stream, const Common::Point &pos) const {
- byte x, y;
- bool bNewLine = false;
- byte oldX = 0, oldY = 0;
- while (1) {
- x = stream.readByte();
- y = stream.readByte();
-
- if (stream.err() || stream.eos())
- error("Failed to read 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) {
- _display->putPixel(Common::Point(x, y), 0x7f);
- bNewLine = false;
- } else {
- drawLine(Common::Point(oldX, oldY), Common::Point(x, y), 0x7f);
- }
-
- oldX = x;
- oldY = y;
- }
-}
-
Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes1Engine(syst, gd);
}
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 02cec01..96e2fd0 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -26,6 +26,7 @@
#include "common/str.h"
#include "adl/adl.h"
+#include "adl/graphics.h"
namespace Common {
class ReadStream;
@@ -82,7 +83,7 @@ namespace Adl {
#define IDI_HR1_OFS_CMDS_1 0x3d00
#define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
-#define IDI_HR1_OFS_LINE_ART 0x4f00
+#define IDI_HR1_OFS_CORNERS 0x4f00
#define IDI_HR1_OFS_VERBS 0x3800
#define IDI_HR1_OFS_NOUNS 0x0f00
@@ -94,16 +95,16 @@ public:
private:
// AdlEngine
void runIntro() const;
- void loadData();
+ void init();
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
void printMessage(uint idx, bool wait = true) const;
+ void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom() const;
- void drawLine(const Common::Point &p1, const Common::Point &p2, byte color) const;
- void drawPic(Common::ReadStream &stream, const Common::Point &pos) const;
-
+ Common::File _exe;
+ Common::Array<uint> _corners;
Common::Array<byte> _roomDesc;
};
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 7bdfde5..19f447e 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -51,7 +51,9 @@ void HiRes2Engine::runIntro() const {
delay(2000);
}
-void HiRes2Engine::loadData() {
+void HiRes2Engine::init() {
+ _graphics = new Graphics_v2(*_display);
+
Common::File f;
if (!f.open(IDS_HR2_DISK_IMAGE))
@@ -122,8 +124,7 @@ void HiRes2Engine::restartGame() {
}
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
- // Temp hack
- Graphics test(*_display);
+ // Temp hack to show a pic
Common::File f;
@@ -132,7 +133,7 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
f.seek(0x1000);
- test.draw(f);
+ _graphics->drawPic(f, pos, 0);
}
void HiRes2Engine::showRoom() const {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 05926ee..f09a62f 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -70,10 +70,11 @@ public:
private:
// AdlEngine
void runIntro() const;
- void loadData();
+ void init();
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos) const;
+ void drawItem(const Item &item, const Common::Point &pos) const { }
void showRoom() const;
};
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 6901279..de4d645 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -5,6 +5,8 @@ MODULE_OBJS := \
detection.o \
display.o \
graphics.o \
+ graphics_v1.o \
+ graphics_v2.o \
hires1.o \
hires2.o
Commit: 0686ba9de8f77a1928d2d7aa4736384eb0715494
https://github.com/scummvm/scummvm/commit/0686ba9de8f77a1928d2d7aa4736384eb0715494
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean up file error handling
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires2.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index a17339f..e25af25 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -85,12 +85,9 @@ Common::String AdlEngine::readStringAt(Common::SeekableReadStream &stream, uint
return readString(stream, until);
}
-Common::File *AdlEngine::openFile(const Common::String &name) const {
- Common::File *f = new Common::File();
- if (!f->open(name))
+void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
+ if (!file.open(name))
error("Error opening '%s'", name.c_str());
-
- return f;
}
void AdlEngine::printMessage(uint idx, bool wait) const {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d8c631e..c457291 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -143,7 +143,7 @@ protected:
Common::String readString(Common::ReadStream &stream, byte until = 0) const;
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
- Common::File *openFile(const Common::String &name) const;
+ void openFile(Common::File &file, const Common::String &name) const;
virtual void printMessage(uint idx, bool wait = true) const;
void delay(uint32 ms) const;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 7354738..59a9e84 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -25,6 +25,7 @@
#include "common/error.h"
#include "common/file.h"
#include "common/stream.h"
+#include "common/ptr.h"
#include "adl/hires1.h"
#include "adl/display.h"
@@ -34,8 +35,7 @@ namespace Adl {
void HiRes1Engine::runIntro() const {
Common::File file;
- if (!file.open(IDS_HR1_EXE_0))
- error("Failed to open file '" IDS_HR1_EXE_0 "'");
+ openFile(file, IDS_HR1_EXE_0);
file.seek(IDI_HR1_OFS_LOGO_0);
_display->setMode(DISPLAY_MODE_HIRES);
@@ -49,8 +49,7 @@ void HiRes1Engine::runIntro() const {
_display->setMode(DISPLAY_MODE_TEXT);
Common::File basic;
- if (!basic.open(IDS_HR1_LOADER))
- error("Failed to open file '" IDS_HR1_LOADER "'");
+ openFile(basic, IDS_HR1_LOADER);
Common::String str;
@@ -126,10 +125,8 @@ void HiRes1Engine::runIntro() const {
_display->setMode(DISPLAY_MODE_MIXED);
- if (!file.open(IDS_HR1_EXE_1))
- error("Failed to open file '" IDS_HR1_EXE_1 "'");
-
// Title screen shown during loading
+ openFile(file, IDS_HR1_EXE_1);
file.seek(IDI_HR1_OFS_LOGO_1);
_display->loadFrameBuffer(file);
_display->updateHiResScreen();
@@ -140,17 +137,13 @@ void HiRes1Engine::init() {
_graphics = new Graphics_v1(*_display);
Common::File f;
-
- if (!f.open(IDS_HR1_MESSAGES))
- error("Failed to open file '" IDS_HR1_MESSAGES "'");
+ openFile(f, IDS_HR1_MESSAGES);
for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
_messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
f.close();
-
- if (!f.open(IDS_HR1_EXE_1))
- error("Failed to open file '" IDS_HR1_EXE_1 "'");
+ openFile(f, IDS_HR1_EXE_1);
// Some messages have overrides inside the executable
_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(f, IDI_HR1_OFS_STR_CANT_GO_THERE);
@@ -223,8 +216,7 @@ void HiRes1Engine::initState() {
_state.vars.clear();
_state.vars.resize(IDI_HR1_NUM_VARS);
- if (!f.open(IDS_HR1_EXE_1))
- error("Failed to open file '" IDS_HR1_EXE_1 "'");
+ openFile(f, IDS_HR1_EXE_1);
// Load room data from executable
_state.rooms.clear();
@@ -277,9 +269,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
Common::File f;
Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
- if (!f.open(name))
- error("Failed to open file '%s'", name.c_str());
-
+ openFile(f, name);
f.seek(_pictures[pic].offset);
_graphics->drawPic(f, pos, 0x7f);
}
@@ -305,10 +295,10 @@ void HiRes1Engine::printMessage(uint idx, bool wait) const {
void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
if (item.isLineArt) {
- Common::File *f = openFile(IDS_HR1_EXE_1);
- f->seek(_corners[item.picture - 1]);
- static_cast<Graphics_v1 *>(_graphics)->drawCorners(*f, pos);
- delete f;
+ Common::File f;
+ openFile(f, IDS_HR1_EXE_1);
+ f.seek(_corners[item.picture - 1]);
+ static_cast<Graphics_v1 *>(_graphics)->drawCorners(f, pos);
} else
drawPic(item.picture, pos);
}
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 19f447e..3655b2a 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -34,10 +34,7 @@ namespace Adl {
void HiRes2Engine::runIntro() const {
Common::File f;
-
- if (!f.open(IDS_HR2_DISK_IMAGE))
- error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
-
+ openFile(f, IDS_HR2_DISK_IMAGE);
f.seek(IDI_HR2_OFS_INTRO_TEXT);
_display->setMode(DISPLAY_MODE_TEXT);
@@ -55,9 +52,7 @@ void HiRes2Engine::init() {
_graphics = new Graphics_v2(*_display);
Common::File f;
-
- if (!f.open(IDS_HR2_DISK_IMAGE))
- error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+ openFile(f, IDS_HR2_DISK_IMAGE);
for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
f.seek(IDI_HR2_OFS_MESSAGES + i * 4);
@@ -97,9 +92,7 @@ void HiRes2Engine::init() {
void HiRes2Engine::initState() {
Common::File f;
-
- if (!f.open(IDS_HR2_DISK_IMAGE))
- error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
+ openFile(f, IDS_HR2_DISK_IMAGE);
_state.rooms.clear();
f.seek(IDI_HR2_OFS_ROOMS);
@@ -127,10 +120,7 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
// Temp hack to show a pic
Common::File f;
-
- if (!f.open(IDS_HR2_DISK_IMAGE))
- error("Failed to open file '" IDS_HR2_DISK_IMAGE "'");
-
+ openFile(f, IDS_HR2_DISK_IMAGE);
f.seek(0x1000);
_graphics->drawPic(f, pos, 0);
Commit: b4aea80723460417f3514c8d27a41d69195cd23f
https://github.com/scummvm/scummvm/commit/b4aea80723460417f3514c8d27a41d69195cd23f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires2 word wrapping
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/display.cpp
engines/adl/display.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e25af25..3ce3989 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -161,12 +161,13 @@ Common::String AdlEngine::inputString(byte prompt) const {
}
}
-byte AdlEngine::inputKey() const {
+byte AdlEngine::inputKey(bool showCursor) const {
Common::EventManager *ev = g_system->getEventManager();
byte key = 0;
- _display->showCursor(true);
+ if (showCursor)
+ _display->showCursor(true);
while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
Common::Event event;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index c457291..b118a37 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -149,7 +149,7 @@ protected:
void delay(uint32 ms) const;
Common::String inputString(byte prompt = 0) const;
- byte inputKey() const;
+ byte inputKey(bool showCursor = true) const;
void loadWords(Common::ReadStream &stream, WordMap &map) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
@@ -215,7 +215,7 @@ private:
virtual void initState() = 0;
virtual void restartGame() = 0;
virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
- virtual void showRoom() const = 0;
+ virtual void showRoom() = 0;
// Engine
Common::Error run();
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 3795973..2ecfbeb 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -41,8 +41,6 @@ namespace Adl {
#define DISPLAY_PITCH (DISPLAY_WIDTH / 7)
#define DISPLAY_SIZE (DISPLAY_PITCH * DISPLAY_HEIGHT)
-#define TEXT_WIDTH 40
-#define TEXT_HEIGHT 24
#define TEXT_BUF_SIZE (TEXT_WIDTH * TEXT_HEIGHT)
#define COLOR_PALETTE_ENTRIES 8
@@ -291,21 +289,23 @@ void Display::moveCursorTo(const Common::Point &pos) {
error("Cursor position (%i, %i) out of bounds", pos.x, pos.y);
}
+// FIXME: This does not currently update the surfaces
+void Display::printChar(char c) {
+ if (c == APPLECHAR('\r'))
+ _cursorPos = (_cursorPos / TEXT_WIDTH + 1) * TEXT_WIDTH;
+ else if ((byte)c < 0x80 || (byte)c >= 0xa0) {
+ setCharAtCursor(c);
+ ++_cursorPos;
+ }
+
+ if (_cursorPos == TEXT_BUF_SIZE)
+ scrollUp();
+}
+
void Display::printString(const Common::String &str) {
Common::String::const_iterator c;
- for (c = str.begin(); c != str.end(); ++c) {
- byte b = *c;
-
- if (*c == APPLECHAR('\r'))
- _cursorPos = (_cursorPos / TEXT_WIDTH + 1) * TEXT_WIDTH;
- else if (b < 0x80 || b >= 0xa0) {
- setCharAtCursor(b);
- ++_cursorPos;
- }
-
- if (_cursorPos == TEXT_BUF_SIZE)
- scrollUp();
- }
+ for (c = str.begin(); c != str.end(); ++c)
+ printChar(*c);
updateTextScreen();
}
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 67d8bf4..2946a7e 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 TEXT_WIDTH 40
+#define TEXT_HEIGHT 24
enum DisplayMode {
DISPLAY_MODE_HIRES,
@@ -71,6 +73,7 @@ public:
void moveCursorTo(const Common::Point &pos);
void moveCursorForward();
void moveCursorBackward();
+ void printChar(char c);
void printString(const Common::String &str);
void printAsciiString(const Common::String &str);
void setCharAtCursor(byte c);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 59a9e84..438d9c2 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -303,7 +303,7 @@ void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
drawPic(item.picture, pos);
}
-void HiRes1Engine::showRoom() const {
+void HiRes1Engine::showRoom() {
if (!_state.isDark) {
drawPic(getCurRoom().curPicture);
drawItems();
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 96e2fd0..028148b 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -101,7 +101,7 @@ private:
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
void printMessage(uint idx, bool wait = true) const;
void drawItem(const Item &item, const Common::Point &pos) const;
- void showRoom() const;
+ void showRoom();
Common::File _exe;
Common::Array<uint> _corners;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 3655b2a..575bab9 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -110,6 +110,17 @@ void HiRes2Engine::initState() {
f.readByte(); // always 1, possibly disk?
_state.rooms.push_back(room);
}
+
+ loadRoom(_state.room);
+}
+
+void HiRes2Engine::loadRoom(uint i) {
+ Common::File f;
+ openFile(f, IDS_HR2_DISK_IMAGE);
+ Room &room = getRoom(i);
+ uint offset = TSO(room.track, room.sector, room.offset);
+ f.seek(offset);
+ _roomData.description = readStringAt(f, offset + f.readByte(), 0xff);
}
void HiRes2Engine::restartGame() {
@@ -126,9 +137,72 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
_graphics->drawPic(f, pos, 0);
}
-void HiRes2Engine::showRoom() const {
+void HiRes2Engine::showRoom() {
+ _linesPrinted = 0;
drawPic(0, Common::Point());
_display->updateHiResScreen();
+ printString(_roomData.description);
+}
+
+void HiRes2Engine::checkTextOverflow(char c) {
+ if (c != APPLECHAR('\r'))
+ return;
+
+ ++_linesPrinted;
+
+ if (_linesPrinted < 4)
+ return;
+
+ _linesPrinted = 0;
+ // Bell
+
+ while (true) {
+ char key = inputKey(false);
+
+ if (shouldQuit())
+ return;
+
+ if (key == APPLECHAR('\r'))
+ break;
+
+ // Bell
+ // Bell
+ // Bell
+ }
+}
+
+void HiRes2Engine::printString(const Common::String &str) {
+ Common::String s(str);
+ byte endPos = TEXT_WIDTH - 1;
+ byte pos = 0;
+
+ while (true) {
+ while (pos != endPos && pos != s.size()) {
+ s.setChar(APPLECHAR(s[pos]), pos);
+ ++pos;
+ }
+
+ if (pos == s.size())
+ break;
+
+ while (s[pos] != APPLECHAR(' ') && s[pos] != APPLECHAR('\r'))
+ --pos;
+
+ s.setChar(APPLECHAR('\r'), pos);
+ endPos = pos + TEXT_WIDTH;
+ ++pos;
+ }
+
+ pos = 0;
+ while (pos != s.size()) {
+ checkTextOverflow(s[pos]);
+ _display->printChar(s[pos]);
+ ++pos;
+ }
+
+ checkTextOverflow(APPLECHAR('\r'));
+ _display->printChar(APPLECHAR('\r'));
+ _display->updateTextScreen();
}
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index f09a62f..91bbf0a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -63,9 +63,20 @@ namespace Adl {
#define IDI_HR2_OFS_STR_PLAY_AGAIN TSO(0x1a, 0x8, 0x25)
#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
+struct Picture2 {
+ byte track;
+ byte sector;
+ byte offset;
+};
+
+struct RoomData {
+ Common::String description;
+ Common::Array<Picture2> pictures;
+};
+
class HiRes2Engine : public AdlEngine {
public:
- HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
+ HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _linesPrinted(0) { }
private:
// AdlEngine
@@ -75,7 +86,14 @@ private:
void restartGame();
void drawPic(byte pic, Common::Point pos) const;
void drawItem(const Item &item, const Common::Point &pos) const { }
- void showRoom() const;
+ void showRoom();
+
+ void loadRoom(uint i);
+ void checkTextOverflow(char c);
+ void printString(const Common::String &str);
+
+ RoomData _roomData;
+ uint _linesPrinted;
};
} // End of namespace Adl
Commit: 0664b51d2f3c61a2cba64cc6c42b00d86057d908
https://github.com/scummvm/scummvm/commit/0664b51d2f3c61a2cba64cc6c42b00d86057d908
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add bell function
Changed paths:
A engines/adl/speaker.cpp
A engines/adl/speaker.h
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/module.mk
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 3ce3989..74fc93c 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -39,12 +39,14 @@
#include "adl/display.h"
#include "adl/detection.h"
#include "adl/graphics.h"
+#include "adl/speaker.h"
namespace Adl {
AdlEngine::~AdlEngine() {
delete _display;
delete _graphics;
+ delete _speaker;
}
AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
@@ -62,6 +64,24 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
_canRestoreNow(false) {
}
+bool AdlEngine::pollEvent(Common::Event &event) {
+ if (g_system->getEventManager()->pollEvent(event)) {
+ if (event.type != Common::EVENT_KEYDOWN)
+ return false;
+
+ if (event.kbd.flags & Common::KBD_CTRL) {
+ if (event.kbd.keycode == Common::KEYCODE_q) {
+ quitGame();
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
Common::String AdlEngine::readString(Common::ReadStream &stream, byte until) const {
Common::String str;
@@ -100,23 +120,11 @@ void AdlEngine::printMessage(uint idx, bool wait) const {
}
void AdlEngine::delay(uint32 ms) const {
- Common::EventManager *ev = g_system->getEventManager();
-
uint32 start = g_system->getMillis();
- while (!g_engine->shouldQuit() && g_system->getMillis() - start < ms) {
+ while (!shouldQuit() && g_system->getMillis() - start < ms) {
Common::Event event;
- if (ev->pollEvent(event)) {
- if (event.type == Common::EVENT_KEYDOWN && (event.kbd.flags & Common::KBD_CTRL)) {
- switch(event.kbd.keycode) {
- case Common::KEYCODE_q:
- g_engine->quitGame();
- break;
- default:
- break;
- }
- }
- }
+ pollEvent(event);
g_system->delayMillis(16);
}
}
@@ -130,7 +138,7 @@ Common::String AdlEngine::inputString(byte prompt) const {
while (1) {
byte b = inputKey();
- if (g_engine->shouldQuit() || _isRestoring)
+ if (shouldQuit() || _isRestoring)
return 0;
if (b == 0)
@@ -162,25 +170,17 @@ Common::String AdlEngine::inputString(byte prompt) const {
}
byte AdlEngine::inputKey(bool showCursor) const {
- Common::EventManager *ev = g_system->getEventManager();
-
byte key = 0;
if (showCursor)
_display->showCursor(true);
- while (!g_engine->shouldQuit() && !_isRestoring && key == 0) {
+ while (!shouldQuit() && !_isRestoring && key == 0) {
Common::Event event;
- if (ev->pollEvent(event)) {
+ if (pollEvent(event)) {
if (event.type != Common::EVENT_KEYDOWN)
continue;
- if (event.kbd.flags & Common::KBD_CTRL) {
- if (event.kbd.keycode == Common::KEYCODE_q)
- g_engine->quitGame();
- continue;
- }
-
switch (event.kbd.keycode) {
case Common::KEYCODE_BACKSPACE:
case Common::KEYCODE_RETURN:
@@ -307,6 +307,10 @@ void AdlEngine::drawItems() const {
}
}
+void AdlEngine::bell(uint count) const {
+ _speaker->bell(count);
+}
+
const Room &AdlEngine::getRoom(uint i) const {
if (i < 1 || i > _state.rooms.size())
error("Room %i out of range [1, %i]", i, _state.rooms.size());
@@ -403,6 +407,7 @@ void AdlEngine::dropItem(byte noun) {
}
Common::Error AdlEngine::run() {
+ _speaker = new Speaker();
_display = new Display();
init();
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index b118a37..9ccd02b 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -26,18 +26,26 @@
#include "common/array.h"
#include "common/rect.h"
#include "common/str.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
#include "engines/engine.h"
+#include "audio/mixer.h"
+#include "audio/softsynth/pcspk.h"
+
namespace Common {
class ReadStream;
class SeekableReadStream;
+class File;
+struct Event;
}
namespace Adl {
class Display;
class GraphicsMan;
+class Speaker;
struct AdlGameDescription;
// Conditional opcodes
@@ -138,6 +146,8 @@ class AdlEngine : public Engine {
public:
virtual ~AdlEngine();
+ static bool pollEvent(Common::Event &event);
+
protected:
AdlEngine(OSystem *syst, const AdlGameDescription *gd);
@@ -158,6 +168,9 @@ protected:
void clearScreen() const;
void drawItems() const;
+ // Sound
+ void bell(uint count = 1) const;
+
// Game state functions
const Room &getRoom(uint i) const;
Room &getRoom(uint i);
@@ -176,6 +189,7 @@ protected:
Display *_display;
GraphicsMan *_graphics;
+ Speaker *_speaker;
// Message strings in data file
Common::Array<Common::String> _messages;
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index de4d645..35e1228 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -8,7 +8,8 @@ MODULE_OBJS := \
graphics_v1.o \
graphics_v2.o \
hires1.o \
- hires2.o
+ hires2.o \
+ speaker.o
MODULE_DIRS += \
engines/adl
diff --git a/engines/adl/speaker.cpp b/engines/adl/speaker.cpp
new file mode 100644
index 0000000..532d361
--- /dev/null
+++ b/engines/adl/speaker.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "common/events.h"
+
+#include "engines/engine.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+
+#include "adl/speaker.h"
+#include "adl/adl.h"
+
+namespace Adl {
+
+// Number of times to duplicate each sample
+#define SAMPLE_DUP 4
+// Bell frequency in Hz
+#define BELL_FREQ 1000
+// Sample rate
+#define SAMPLE_RATE (BELL_FREQ * SAMPLE_DUP * 2)
+// Number of waves per 0.1 seconds (bell length)
+#define BELL_WAVE_COUNT (SAMPLE_RATE / 10 / SAMPLE_DUP / 2)
+// Length of bell in samples
+#define BELL_LEN (BELL_WAVE_COUNT * SAMPLE_DUP * 2)
+// Length of silence in samples
+#define SILENCE_LEN (SAMPLE_RATE / 80)
+
+Speaker::~Speaker() {
+ delete[] _bell;
+ delete[] _silence;
+}
+
+Speaker::Speaker() {
+ _bell = new byte[BELL_LEN];
+
+ byte *buf = _bell;
+ for (uint i = 0; i < BELL_WAVE_COUNT; ++i) {
+ for (uint j = 0; j < SAMPLE_DUP; ++j)
+ *buf++ = 0x00;
+ for (uint j = 0; j < SAMPLE_DUP; ++j)
+ *buf++ = 0xff;
+ }
+
+ _silence = new byte[SILENCE_LEN];
+
+ buf = _silence;
+ for (uint i = 0; i < SILENCE_LEN; ++i)
+ *buf++ = 0x80;
+}
+
+void Speaker::bell(uint count) {
+ Audio::QueuingAudioStream *stream = Audio::makeQueuingAudioStream(SAMPLE_RATE, false);
+ Audio::SoundHandle handle;
+
+ stream->queueBuffer(_bell, BELL_LEN, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+
+ for (uint i = 1; i < count; ++i) {
+ stream->queueBuffer(_silence, SILENCE_LEN, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+ stream->queueBuffer(_bell, BELL_LEN, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED);
+ }
+
+ stream->finish();
+
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &handle, stream);
+
+ while (!g_engine->shouldQuit() && g_system->getMixer()->isSoundHandleActive(handle)) {
+ Common::Event event;
+ static_cast<AdlEngine *>(g_engine)->pollEvent(event);
+ g_system->delayMillis(16);
+ }
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/speaker.h b/engines/adl/speaker.h
new file mode 100644
index 0000000..31aaac3
--- /dev/null
+++ b/engines/adl/speaker.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_SPEAKER_H
+#define ADL_SPEAKER_H
+
+#include "common/types.h"
+
+#include "audio/mixer.h"
+
+namespace Audio {
+class AudioStream;
+}
+
+namespace Adl {
+
+class Speaker {
+public:
+ Speaker();
+ ~Speaker();
+
+ void bell(uint count);
+
+private:
+ byte *_bell, *_silence;
+};
+
+} // End of namespace Adl
+
+#endif
Commit: 7cef93739c24bb017e31bb2d5c359a93582426cd
https://github.com/scummvm/scummvm/commit/7cef93739c24bb017e31bb2d5c359a93582426cd
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Hook up bell in hires2
Changed paths:
engines/adl/hires2.cpp
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 575bab9..19acf19 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -154,7 +154,8 @@ void HiRes2Engine::checkTextOverflow(char c) {
return;
_linesPrinted = 0;
- // Bell
+ _display->updateTextScreen();
+ bell();
while (true) {
char key = inputKey(false);
@@ -165,9 +166,7 @@ void HiRes2Engine::checkTextOverflow(char c) {
if (key == APPLECHAR('\r'))
break;
- // Bell
- // Bell
- // Bell
+ bell(3);
}
}
Commit: 1e5fff86c875958408f3a5532451139626a4dc56
https://github.com/scummvm/scummvm/commit/1e5fff86c875958408f3a5532451139626a4dc56
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix hires2 message printing
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 74fc93c..81c9054 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -110,7 +110,7 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
error("Error opening '%s'", name.c_str());
}
-void AdlEngine::printMessage(uint idx, bool wait) const {
+void AdlEngine::printMessage(uint idx, bool wait) {
Common::String msg = _messages[idx - 1];
wordWrap(msg);
_display->printString(msg);
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9ccd02b..20e8fbc 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -155,7 +155,7 @@ protected:
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
void openFile(Common::File &file, const Common::String &name) const;
- virtual void printMessage(uint idx, bool wait = true) const;
+ virtual void printMessage(uint idx, bool wait = true);
void delay(uint32 ms) const;
Common::String inputString(byte prompt = 0) const;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 438d9c2..368b08c 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -274,7 +274,7 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
_graphics->drawPic(f, pos, 0x7f);
}
-void HiRes1Engine::printMessage(uint idx, bool wait) const {
+void HiRes1Engine::printMessage(uint idx, bool wait) {
// Messages with hardcoded overrides don't delay after printing.
// It's unclear if this is a bug or not. In some cases the result
// is that these strings will scroll past the four-line text window
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 028148b..9c31a39 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -99,7 +99,7 @@ private:
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
- void printMessage(uint idx, bool wait = true) const;
+ void printMessage(uint idx, bool wait = true);
void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom();
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 19acf19..f44dfc4 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -59,7 +59,7 @@ void HiRes2Engine::init() {
byte track = f.readByte();
byte sector = f.readByte();
byte offset = f.readByte();
- // One more byte follows, disk?
+ // One more byte follows, disk? or size maybe?
uint diskOffset = TSO(track, sector, offset);
@@ -144,6 +144,10 @@ void HiRes2Engine::showRoom() {
printString(_roomData.description);
}
+void HiRes2Engine::printMessage(uint idx, bool wait) {
+ printString(_messages[idx - 1]);
+}
+
void HiRes2Engine::checkTextOverflow(char c) {
if (c != APPLECHAR('\r'))
return;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 91bbf0a..d88e43a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -87,6 +87,7 @@ private:
void drawPic(byte pic, Common::Point pos) const;
void drawItem(const Item &item, const Common::Point &pos) const { }
void showRoom();
+ void printMessage(uint idx, bool wait);
void loadRoom(uint i);
void checkTextOverflow(char c);
Commit: 0a6b7fb6a6414caa4d8654a75e07b6a33ef6cce3
https://github.com/scummvm/scummvm/commit/0a6b7fb6a6414caa4d8654a75e07b6a33ef6cce3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add loading of room picture index for hires2
Changed paths:
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index f44dfc4..226a8e3 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -110,17 +110,31 @@ void HiRes2Engine::initState() {
f.readByte(); // always 1, possibly disk?
_state.rooms.push_back(room);
}
-
- loadRoom(_state.room);
}
-void HiRes2Engine::loadRoom(uint i) {
+void HiRes2Engine::loadRoom(byte roomNr) {
Common::File f;
openFile(f, IDS_HR2_DISK_IMAGE);
- Room &room = getRoom(i);
+ Room &room = getRoom(roomNr);
uint offset = TSO(room.track, room.sector, room.offset);
f.seek(offset);
- _roomData.description = readStringAt(f, offset + f.readByte(), 0xff);
+ uint16 descOffset = f.readUint16LE();
+ /* uint16 commandOffset =*/ f.readUint16LE();
+
+ // There's no picture count. The original engine always checks at most
+ // five pictures. We use the description offset to bound our search.
+ uint16 picCount = (descOffset - 4) / 5;
+
+ for (uint i = 0; i < picCount; ++i) {
+ Picture2 pic;
+ pic.nr = f.readByte();
+ pic.track = f.readByte();
+ pic.sector = f.readByte();
+ pic.offset = f.readByte();
+ f.readByte();
+ _roomData.pictures.push_back(pic);
+ }
+ _roomData.description = readStringAt(f, offset + descOffset, 0xff);
}
void HiRes2Engine::restartGame() {
@@ -128,18 +142,24 @@ void HiRes2Engine::restartGame() {
}
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
- // Temp hack to show a pic
-
- Common::File f;
- openFile(f, IDS_HR2_DISK_IMAGE);
- f.seek(0x1000);
+ Common::Array<Picture2>::const_iterator roomPic;
+
+ for (roomPic = _roomData.pictures.begin(); roomPic != _roomData.pictures.end(); ++roomPic) {
+ if (roomPic->nr == pic) {
+ Common::File f;
+ openFile(f, IDS_HR2_DISK_IMAGE);
+ f.seek(TSO(roomPic->track, roomPic->sector, roomPic->offset));
+ _graphics->drawPic(f, pos, 0);
+ }
+ }
- _graphics->drawPic(f, pos, 0);
+ // Check global pic list here
}
void HiRes2Engine::showRoom() {
+ loadRoom(_state.room);
_linesPrinted = 0;
- drawPic(0, Common::Point());
+ drawPic(getCurRoom().curPicture, Common::Point());
_display->updateHiResScreen();
printString(_roomData.description);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index d88e43a..58831c4 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -64,6 +64,7 @@ namespace Adl {
#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
struct Picture2 {
+ byte nr;
byte track;
byte sector;
byte offset;
@@ -89,7 +90,7 @@ private:
void showRoom();
void printMessage(uint idx, bool wait);
- void loadRoom(uint i);
+ void loadRoom(byte roomNr);
void checkTextOverflow(char c);
void printString(const Common::String &str);
Commit: 7ff7e0def4670fee3346c4b75aa1e79d2f684bb0
https://github.com/scummvm/scummvm/commit/7ff7e0def4670fee3346c4b75aa1e79d2f684bb0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add hires2 command loading
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 81c9054..1afc530 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -273,6 +273,11 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
}
}
+void AdlEngine::checkInput(byte verb, byte noun) {
+ if (!doOneCommand(_roomCommands, verb, noun))
+ printMessage(_messageIds.dontUnderstand);
+}
+
void AdlEngine::clearScreen() const {
_display->setMode(DISPLAY_MODE_MIXED);
_display->clear(0x00);
@@ -448,8 +453,7 @@ Common::Error AdlEngine::run() {
// If we just restored from the GMM, we skip this command
// set, as no command has been input by the user
if (!_isRestoring)
- if (!doOneCommand(_roomCommands, verb, noun))
- printMessage(_messageIds.dontUnderstand);
+ checkInput(verb, noun);
}
if (_isRestoring) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 20e8fbc..97077f9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -163,6 +163,7 @@ protected:
void loadWords(Common::ReadStream &stream, WordMap &map) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
+ virtual void checkInput(byte verb, byte noun);
// Graphics
void clearScreen() const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 226a8e3..8b12746 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -83,6 +83,13 @@ void HiRes2Engine::init() {
_messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
+ // Load commands from executable
+ f.seek(IDI_HR2_OFS_CMDS_1);
+ readCommands(f, _roomCommands);
+
+ f.seek(IDI_HR2_OFS_CMDS_0);
+ // readCommands(f, _globalCommands);
+
f.seek(IDI_HR2_OFS_VERBS);
loadWords(f, _verbs);
@@ -91,6 +98,9 @@ void HiRes2Engine::init() {
}
void HiRes2Engine::initState() {
+ _state.vars.clear();
+ _state.vars.resize(IDI_HR2_NUM_VARS);
+
Common::File f;
openFile(f, IDS_HR2_DISK_IMAGE);
@@ -119,7 +129,7 @@ void HiRes2Engine::loadRoom(byte roomNr) {
uint offset = TSO(room.track, room.sector, room.offset);
f.seek(offset);
uint16 descOffset = f.readUint16LE();
- /* uint16 commandOffset =*/ f.readUint16LE();
+ uint16 commandOffset = f.readUint16LE();
// There's no picture count. The original engine always checks at most
// five pictures. We use the description offset to bound our search.
@@ -134,7 +144,12 @@ void HiRes2Engine::loadRoom(byte roomNr) {
f.readByte();
_roomData.pictures.push_back(pic);
}
+
_roomData.description = readStringAt(f, offset + descOffset, 0xff);
+
+ f.seek(offset + commandOffset);
+
+ readCommands(f, _roomData.commands);
}
void HiRes2Engine::restartGame() {
@@ -158,16 +173,23 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
void HiRes2Engine::showRoom() {
loadRoom(_state.room);
- _linesPrinted = 0;
drawPic(getCurRoom().curPicture, Common::Point());
_display->updateHiResScreen();
printString(_roomData.description);
+ _linesPrinted = 0;
}
void HiRes2Engine::printMessage(uint idx, bool wait) {
printString(_messages[idx - 1]);
}
+void HiRes2Engine::checkInput(byte verb, byte noun) {
+ if (doOneCommand(_roomData.commands, verb, noun))
+ return;
+
+ AdlEngine::checkInput(verb, noun);
+}
+
void HiRes2Engine::checkTextOverflow(char c) {
if (c != APPLECHAR('\r'))
return;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 58831c4..f9d6d92 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -47,8 +47,12 @@ namespace Adl {
#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
#define IDI_HR2_OFS_MESSAGES TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+#define IDI_HR2_OFS_CMDS_0 TS(0x1f, 0x7)
+#define IDI_HR2_OFS_CMDS_1 TS(0x1d, 0x7)
+
#define IDI_HR2_NUM_ROOMS 135
#define IDI_HR2_NUM_MESSAGES 254
+#define IDI_HR2_NUM_VARS 40
// Messages used outside of scripts
#define IDI_HR2_MSG_CANT_GO_THERE 123
@@ -73,6 +77,7 @@ struct Picture2 {
struct RoomData {
Common::String description;
Common::Array<Picture2> pictures;
+ Commands commands;
};
class HiRes2Engine : public AdlEngine {
@@ -89,6 +94,7 @@ private:
void drawItem(const Item &item, const Common::Point &pos) const { }
void showRoom();
void printMessage(uint idx, bool wait);
+ void checkInput(byte verb, byte noun);
void loadRoom(byte roomNr);
void checkTextOverflow(char c);
Commit: 46528f2c04d593f50e8c1a04d25c6cd663c3d209
https://github.com/scummvm/scummvm/commit/46528f2c04d593f50e8c1a04d25c6cd663c3d209
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix flood fill palette setting
Changed paths:
engines/adl/display.cpp
engines/adl/display.h
engines/adl/graphics_v2.cpp
diff --git a/engines/adl/display.cpp b/engines/adl/display.cpp
index 2ecfbeb..b7f6eb9 100644
--- a/engines/adl/display.cpp
+++ b/engines/adl/display.cpp
@@ -217,13 +217,6 @@ void Display::loadFrameBuffer(Common::ReadStream &stream) {
error("Failed to read frame buffer");
}
-void Display::putPixelRaw(const Common::Point &p, byte color) {
- byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
- color ^= *b;
- color &= 0x80 | (1 << (p.x % 7));
- *b ^= color;
-}
-
void Display::putPixel(const Common::Point &p, byte color) {
byte offset = p.x / 7;
byte mask = 0x80 | (1 << (p.x % 7));
@@ -241,14 +234,19 @@ void Display::putPixel(const Common::Point &p, byte color) {
color ^= 0x7f;
}
- byte *b = _frameBuf + p.y * DISPLAY_PITCH + offset;
- color ^= *b;
- color &= mask;
- *b ^= color;
+ writeFrameBuffer(p, color, mask);
+}
+
+void Display::setPixelBit(const Common::Point &p, byte color) {
+ writeFrameBuffer(p, color, 1 << (p.x % 7));
+}
+
+void Display::setPixelPalette(const Common::Point &p, byte color) {
+ writeFrameBuffer(p, color, 0x80);
}
bool Display::getPixelBit(const Common::Point &p) const {
- byte *b = _frameBuf + p.y * DISPLAY_PITCH + (p.x / 7);
+ byte *b = _frameBuf + p.y * DISPLAY_PITCH + p.x / 7;
return *b & (1 << (p.x % 7));
}
@@ -328,6 +326,13 @@ void Display::showCursor(bool enable) {
_showCursor = enable;
}
+void Display::writeFrameBuffer(const Common::Point &p, byte color, byte mask) {
+ byte *b = _frameBuf + p.y * DISPLAY_PITCH + p.x / 7;
+ color ^= *b;
+ color &= mask;
+ *b ^= color;
+}
+
void Display::showScanlines(bool enable) {
byte pal[COLOR_PALETTE_ENTRIES * 3] = { };
diff --git a/engines/adl/display.h b/engines/adl/display.h
index 2946a7e..bc27b7c 100644
--- a/engines/adl/display.h
+++ b/engines/adl/display.h
@@ -63,8 +63,9 @@ public:
// Graphics
void loadFrameBuffer(Common::ReadStream &stream);
- void putPixelRaw(const Common::Point &p, byte color);
void putPixel(const Common::Point &p, byte color);
+ void setPixelBit(const Common::Point &p, byte color);
+ void setPixelPalette(const Common::Point &p, byte color);
bool getPixelBit(const Common::Point &p) const;
void clear(byte color);
@@ -80,6 +81,7 @@ public:
void showCursor(bool enable);
private:
+ void writeFrameBuffer(const Common::Point &p, byte color, byte mask);
void updateHiResSurface();
void showScanlines(bool enable);
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index 289f43e..d829b95 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -26,6 +26,7 @@
#include "adl/display.h"
#include "adl/graphics.h"
+#include "adl/adl.h"
namespace Adl {
@@ -175,23 +176,33 @@ static byte getPatternColor(const Common::Point &p, byte pattern) {
void Graphics_v2::fillRow(const Common::Point &p, bool stopBit, byte pattern) {
const byte color = getPatternColor(p, pattern);
- _display.putPixelRaw(p, color);
+ _display.setPixelPalette(p, color);
+ _display.setPixelBit(p, color);
Common::Point q(p);
byte c = color;
- while (++q.x < DISPLAY_WIDTH && _display.getPixelBit(q) != stopBit) {
- if ((q.x % 7) == 0)
+ while (++q.x < DISPLAY_WIDTH) {
+ if ((q.x % 7) == 0) {
c = getPatternColor(q, pattern);
- _display.putPixelRaw(q, c);
+ // Palette is set before the first bit is tested
+ _display.setPixelPalette(q, c);
+ }
+ if (_display.getPixelBit(q) == stopBit)
+ break;
+ _display.setPixelBit(q, c);
}
q = p;
c = color;
- while (--q.x >= 0 && _display.getPixelBit(q) != stopBit) {
- if ((q.x % 7) == 6)
+ while (--q.x >= 0) {
+ if ((q.x % 7) == 6) {
c = getPatternColor(q, pattern);
- _display.putPixelRaw(q, c);
+ _display.setPixelPalette(q, c);
+ }
+ if (_display.getPixelBit(q) == stopBit)
+ break;
+ _display.setPixelBit(q, c);
}
}
Commit: df4daf954fe1bc379094b4a699267537f1f46916
https://github.com/scummvm/scummvm/commit/df4daf954fe1bc379094b4a699267537f1f46916
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load hires2 items
Changed paths:
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 8b12746..8dba9a6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -120,6 +120,32 @@ void HiRes2Engine::initState() {
f.readByte(); // always 1, possibly disk?
_state.rooms.push_back(room);
}
+
+ _state.items.clear();
+ f.seek(IDI_HR2_OFS_ITEMS);
+ while (f.readByte() != 0xff) {
+ Item item;
+ item.noun = f.readByte();
+ item.room = f.readByte();
+ item.picture = f.readByte();
+ item.isLineArt = f.readByte(); // Is this still used in this way?
+ item.position.x = f.readByte();
+ item.position.y = f.readByte();
+ item.state = f.readByte();
+ item.description = f.readByte();
+
+ f.readByte();
+
+ byte size = f.readByte();
+
+ for (uint i = 0; i < size; ++i)
+ item.roomPictures.push_back(f.readByte());
+
+ _state.items.push_back(item);
+
+ // One unknown extra byte compared to hires1
+ f.readByte();
+ }
}
void HiRes2Engine::loadRoom(byte roomNr) {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index f9d6d92..6c7904b 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -46,6 +46,7 @@ namespace Adl {
#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
#define IDI_HR2_OFS_MESSAGES TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+#define IDI_HR2_OFS_ITEMS T(0x21)
#define IDI_HR2_OFS_CMDS_0 TS(0x1f, 0x7)
#define IDI_HR2_OFS_CMDS_1 TS(0x1d, 0x7)
Commit: 0593460b1bd1d70e3848f1d5195d83384c347c92
https://github.com/scummvm/scummvm/commit/0593460b1bd1d70e3848f1d5195d83384c347c92
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Enable global commands in hires2
Changed paths:
engines/adl/hires2.cpp
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 8dba9a6..be2e016 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -88,7 +88,7 @@ void HiRes2Engine::init() {
readCommands(f, _roomCommands);
f.seek(IDI_HR2_OFS_CMDS_0);
- // readCommands(f, _globalCommands);
+ readCommands(f, _globalCommands);
f.seek(IDI_HR2_OFS_VERBS);
loadWords(f, _verbs);
Commit: a653fa2f459957029978f14618ff634ec3485cf8
https://github.com/scummvm/scummvm/commit/a653fa2f459957029978f14618ff634ec3485cf8
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add partial hires2 item drawing
Changed paths:
engines/adl/graphics_v2.cpp
engines/adl/hires1.cpp
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index d829b95..c705b9c 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -235,6 +235,8 @@ void Graphics_v2::fill(Common::SeekableReadStream &pic) {
}
void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+ _color = color;
+
while (true) {
byte opcode = pic.readByte();
@@ -260,6 +262,30 @@ void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &
case 0xe5:
clear();
break;
+ case 0xf0:
+ _color = 0x00;
+ break;
+ case 0xf1:
+ _color = 0x2a;
+ break;
+ case 0xf2:
+ _color = 0x55;
+ break;
+ case 0xf3:
+ _color = 0x7f;
+ break;
+ case 0xf4:
+ _color = 0x80;
+ break;
+ case 0xf5:
+ _color = 0xaa;
+ break;
+ case 0xf6:
+ _color = 0xd5;
+ break;
+ case 0xf7:
+ _color = 0xff;
+ break;
case 0xff:
return;
default:
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 368b08c..9527d4e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -237,7 +237,7 @@ void HiRes1Engine::initState() {
_state.items.clear();
f.seek(IDI_HR1_OFS_ITEMS);
while (f.readByte() != 0xff) {
- Item item;
+ Item item = { };
item.noun = f.readByte();
item.room = f.readByte();
item.picture = f.readByte();
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index be2e016..e547520 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -32,6 +32,14 @@
namespace Adl {
+static void readPictureMeta(Common::ReadStream &f, Picture2 &pic) {
+ pic.nr = f.readByte();
+ pic.track = f.readByte();
+ pic.sector = f.readByte();
+ pic.offset = f.readByte();
+ f.readByte();
+}
+
void HiRes2Engine::runIntro() const {
Common::File f;
openFile(f, IDS_HR2_DISK_IMAGE);
@@ -83,6 +91,14 @@ void HiRes2Engine::init() {
_messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
+ // Load item picture data
+ f.seek(IDI_HR2_OFS_ITEM_PICS);
+ for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
+ Picture2 pic;
+ readPictureMeta(f, pic);
+ _itemPics.push_back(pic);
+ }
+
// Load commands from executable
f.seek(IDI_HR2_OFS_CMDS_1);
readCommands(f, _roomCommands);
@@ -124,7 +140,7 @@ void HiRes2Engine::initState() {
_state.items.clear();
f.seek(IDI_HR2_OFS_ITEMS);
while (f.readByte() != 0xff) {
- Item item;
+ Item item = { };
item.noun = f.readByte();
item.room = f.readByte();
item.picture = f.readByte();
@@ -134,17 +150,17 @@ void HiRes2Engine::initState() {
item.state = f.readByte();
item.description = f.readByte();
- f.readByte();
+ f.readByte(); // Struct size
- byte size = f.readByte();
+ byte picListSize = f.readByte();
+
+ // Flag to keep track of what has been drawn on the screen
+ f.readByte();
- for (uint i = 0; i < size; ++i)
+ for (uint i = 0; i < picListSize; ++i)
item.roomPictures.push_back(f.readByte());
_state.items.push_back(item);
-
- // One unknown extra byte compared to hires1
- f.readByte();
}
}
@@ -163,11 +179,7 @@ void HiRes2Engine::loadRoom(byte roomNr) {
for (uint i = 0; i < picCount; ++i) {
Picture2 pic;
- pic.nr = f.readByte();
- pic.track = f.readByte();
- pic.sector = f.readByte();
- pic.offset = f.readByte();
- f.readByte();
+ readPictureMeta(f, pic);
_roomData.pictures.push_back(pic);
}
@@ -191,15 +203,26 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
openFile(f, IDS_HR2_DISK_IMAGE);
f.seek(TSO(roomPic->track, roomPic->sector, roomPic->offset));
_graphics->drawPic(f, pos, 0);
+ return;
}
}
// Check global pic list here
}
+void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
+ const Picture2 &pic = _itemPics[item.picture - 1];
+ Common::File f;
+ openFile(f, IDS_HR2_DISK_IMAGE);
+ f.seek(TSO(pic.track, pic.sector, pic.offset));
+ f.readByte(); // Skip clear opcode
+ _graphics->drawPic(f, pos, 0);
+}
+
void HiRes2Engine::showRoom() {
loadRoom(_state.room);
drawPic(getCurRoom().curPicture, Common::Point());
+ drawItems();
_display->updateHiResScreen();
printString(_roomData.description);
_linesPrinted = 0;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 6c7904b..631b341 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -46,6 +46,7 @@ namespace Adl {
#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
#define IDI_HR2_OFS_MESSAGES TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+#define IDI_HR2_OFS_ITEM_PICS TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
#define IDI_HR2_OFS_ITEMS T(0x21)
#define IDI_HR2_OFS_CMDS_0 TS(0x1f, 0x7)
@@ -54,6 +55,7 @@ namespace Adl {
#define IDI_HR2_NUM_ROOMS 135
#define IDI_HR2_NUM_MESSAGES 254
#define IDI_HR2_NUM_VARS 40
+#define IDI_HR2_NUM_ITEM_PICS 38
// Messages used outside of scripts
#define IDI_HR2_MSG_CANT_GO_THERE 123
@@ -92,7 +94,7 @@ private:
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos) const;
- void drawItem(const Item &item, const Common::Point &pos) const { }
+ void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom();
void printMessage(uint idx, bool wait);
void checkInput(byte verb, byte noun);
@@ -102,6 +104,7 @@ private:
void printString(const Common::String &str);
RoomData _roomData;
+ Common::Array<Picture2> _itemPics;
uint _linesPrinted;
};
Commit: 6fd580fb6661e6cf2e7935aae925457e7c92e822
https://github.com/scummvm/scummvm/commit/6fd580fb6661e6cf2e7935aae925457e7c92e822
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add pic offsetting
Changed paths:
engines/adl/graphics.h
engines/adl/graphics_v2.cpp
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index ec29ee0..95f4159 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -68,6 +68,7 @@ private:
void fill(Common::SeekableReadStream &pic);
byte _color;
+ Common::Point _offset;
};
} // End of namespace Adl
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index c705b9c..7da4eed 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -30,6 +30,8 @@
namespace Adl {
+// FIXME: Add clipping
+
#define NUM_PATTERNS 22
#define PATTERN_LEN 4
static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
@@ -78,8 +80,10 @@ static const byte fillPatterns[NUM_PATTERNS][PATTERN_LEN] = {
#define READ_POINT(p) \
do { \
READ_BYTE(p.x); \
+ p.x += _offset.x; \
p.x <<= 1; \
READ_BYTE(p.y); \
+ p.y += _offset.y; \
} while (0)
void Graphics_v2::clear() {
@@ -99,6 +103,7 @@ void Graphics_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
int16 n;
READ_BYTE(n);
+ n += _offset.x;
_display.putPixel(p, _color);
@@ -108,6 +113,7 @@ void Graphics_v2::drawCorners(Common::SeekableReadStream &pic, bool yFirst) {
doYStep:
READ_BYTE(n);
+ n += _offset.y;
_display.putPixel(p, _color);
drawLine(p, Common::Point(p.x, n), _color);
@@ -236,6 +242,7 @@ void Graphics_v2::fill(Common::SeekableReadStream &pic) {
void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
_color = color;
+ _offset = pos;
while (true) {
byte opcode = pic.readByte();
Commit: c0b33afc4a41e3c00dfafa6e1262ce17ed68c15c
https://github.com/scummvm/scummvm/commit/c0b33afc4a41e3c00dfafa6e1262ce17ed68c15c
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load hires2 dropped item offsets
Changed paths:
engines/adl/adl.cpp
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1afc530..bd1cc84 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -304,7 +304,8 @@ void AdlEngine::drawItems() const {
Common::Array<byte>::const_iterator pic;
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (*pic == getCurRoom().curPicture) {
+ // IDI_NONE check was added in hires2
+ if (*pic == getCurRoom().curPicture || *pic == IDI_NONE) {
drawItem(*item, item->position);
continue;
}
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index e547520..b99f9fc 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -106,6 +106,15 @@ void HiRes2Engine::init() {
f.seek(IDI_HR2_OFS_CMDS_0);
readCommands(f, _globalCommands);
+ // Load dropped item offsets
+ f.seek(IDI_HR2_OFS_ITEM_OFFSETS);
+ for (uint i = 0; i < IDI_HR2_NUM_ITEM_OFFSETS; ++i) {
+ Common::Point p;
+ p.x = f.readByte();
+ p.y = f.readByte();
+ _itemOffsets.push_back(p);
+ }
+
f.seek(IDI_HR2_OFS_VERBS);
loadWords(f, _verbs);
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 631b341..516ea52 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -41,21 +41,23 @@ namespace Adl {
#define TS(TRACK, SECTOR) TSO(TRACK, SECTOR, 0)
#define T(TRACK) TS(TRACK, 0)
-#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
-#define IDI_HR2_OFS_VERBS T(0x19)
-#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
-#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
-#define IDI_HR2_OFS_MESSAGES TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
-#define IDI_HR2_OFS_ITEM_PICS TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
-#define IDI_HR2_OFS_ITEMS T(0x21)
-
-#define IDI_HR2_OFS_CMDS_0 TS(0x1f, 0x7)
-#define IDI_HR2_OFS_CMDS_1 TS(0x1d, 0x7)
+#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
+#define IDI_HR2_OFS_VERBS T(0x19)
+#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
+#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
+#define IDI_HR2_OFS_MESSAGES TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
+#define IDI_HR2_OFS_ITEM_PICS TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
+#define IDI_HR2_OFS_ITEMS T(0x21)
+#define IDI_HR2_OFS_ITEM_OFFSETS TSO(0x1b, 0x4, 0x15)
+
+#define IDI_HR2_OFS_CMDS_0 TS(0x1f, 0x7)
+#define IDI_HR2_OFS_CMDS_1 TS(0x1d, 0x7)
#define IDI_HR2_NUM_ROOMS 135
#define IDI_HR2_NUM_MESSAGES 254
#define IDI_HR2_NUM_VARS 40
#define IDI_HR2_NUM_ITEM_PICS 38
+#define IDI_HR2_NUM_ITEM_OFFSETS 16
// Messages used outside of scripts
#define IDI_HR2_MSG_CANT_GO_THERE 123
Commit: 64cf93198fc560d31cc24003d164f656751d2e76
https://github.com/scummvm/scummvm/commit/64cf93198fc560d31cc24003d164f656751d2e76
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use functors to implement opcodes
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index bd1cc84..ad5f559 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -278,6 +278,71 @@ void AdlEngine::checkInput(byte verb, byte noun) {
printMessage(_messageIds.dontUnderstand);
}
+typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
+#define SetOpcodeTable(x) table = &x;
+#define Opcode(x) table->push_back(new OpcodeV1(this, &AdlEngine::x))
+#define OpcodeUnImpl() table->push_back(new OpcodeV1(this, 0))
+
+void AdlEngine::setupOpcodeTables() {
+ Common::Array<const Opcode *> *table = 0;
+
+ SetOpcodeTable(_condOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ OpcodeUnImpl();
+ OpcodeUnImpl();
+ Opcode(o1_isItemInRoom);
+ // 0x04
+ OpcodeUnImpl();
+ Opcode(o1_isMovesGrEq);
+ Opcode(o1_isVarEq);
+ OpcodeUnImpl();
+ // 0x08
+ OpcodeUnImpl();
+ Opcode(o1_isCurPicEq);
+ Opcode(o1_isItemPicEq);
+
+ SetOpcodeTable(_actOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o1_varAdd);
+ Opcode(o1_varSub);
+ Opcode(o1_varSet);
+ // 0x04
+ Opcode(o1_listInv);
+ Opcode(o1_moveItem);
+ Opcode(o1_setRoom);
+ Opcode(o1_setCurPic);
+ // 0x08
+ Opcode(o1_setPic);
+ Opcode(o1_printMsg);
+ Opcode(o1_setLight);
+ Opcode(o1_setDark);
+ // 0x0c
+ OpcodeUnImpl();
+ Opcode(o1_quit);
+ OpcodeUnImpl();
+ Opcode(o1_save);
+ // 0x10
+ Opcode(o1_restore);
+ Opcode(o1_restart);
+ Opcode(o1_placeItem);
+ Opcode(o1_setItemPic);
+ // 0x14
+ Opcode(o1_resetPic);
+ Opcode(o1_goDirection);
+ Opcode(o1_goDirection);
+ Opcode(o1_goDirection);
+ // 0x18
+ Opcode(o1_goDirection);
+ Opcode(o1_goDirection);
+ Opcode(o1_goDirection);
+ Opcode(o1_takeItem);
+ // 0x1c
+ Opcode(o1_dropItem);
+ Opcode(o1_setRoomPic);
+}
+
void AdlEngine::clearScreen() const {
_display->setMode(DISPLAY_MODE_MIXED);
_display->clear(0x00);
@@ -416,6 +481,8 @@ Common::Error AdlEngine::run() {
_speaker = new Speaker();
_display = new Display();
+ setupOpcodeTables();
+
init();
int saveSlot = ConfMan.getInt("save_slot");
@@ -657,8 +724,9 @@ bool AdlEngine::canSaveGameStateCurrently() {
// "SAVE GAME". This prevents saving via the GMM in situations where
// it wouldn't otherwise be possible to do so.
for (cmd = _roomCommands.begin(); cmd != _roomCommands.end(); ++cmd) {
+ ScriptEnv env(*cmd, _saveVerb, _saveNoun);
uint offset;
- if (matchCommand(*cmd, _saveVerb, _saveNoun, &offset))
+ if (matchCommand(env, &offset))
return cmd->script[offset] == IDO_ACT_SAVE;
}
@@ -784,198 +852,249 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
}
}
-#define ARG(N) (command.script[offset + (N)])
+typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
-bool AdlEngine::matchCommand(const Command &command, byte verb, byte noun, uint *actions) const {
- if (command.room != IDI_NONE && command.room != _state.room)
+#define ARG(N) (env.cmd.script[env.ip + (N)])
+
+bool AdlEngine::o1_isItemInRoom(ScriptEnv &env) {
+ if (getItem(ARG(1)).room != ARG(2))
return false;
+ env.ip += 3;
+ return true;
+}
- if (command.verb != IDI_NONE && command.verb != verb)
+bool AdlEngine::o1_isMovesGrEq(ScriptEnv &env) {
+ if (ARG(1) > _state.moves)
return false;
+ env.ip += 2;
+ return true;
+}
- if (command.noun != IDI_NONE && command.noun != noun)
+bool AdlEngine::o1_isVarEq(ScriptEnv &env) {
+ if (getVar(ARG(1)) != ARG(2))
return false;
+ env.ip += 3;
+ return true;
+}
- uint offset = 0;
- for (uint i = 0; i < command.numCond; ++i) {
- switch (ARG(0)) {
- case IDO_CND_ITEM_IN_ROOM:
- if (getItem(ARG(1)).room != ARG(2))
- return false;
- offset += 3;
- break;
- case IDO_CND_MOVES_GE:
- if (ARG(1) > _state.moves)
- return false;
- offset += 2;
- break;
- case IDO_CND_VAR_EQ:
- if (getVar(ARG(1)) != ARG(2))
- return false;
- offset += 3;
- break;
- case IDO_CND_CUR_PIC_EQ:
- if (getCurRoom().curPicture != ARG(1))
- return false;
- offset += 2;
- break;
- case IDO_CND_ITEM_PIC_EQ:
- if (getItem(ARG(1)).picture != ARG(2))
- return false;
- offset += 3;
- break;
- default:
- error("Invalid condition opcode %02x", command.script[offset]);
- }
+bool AdlEngine::o1_isCurPicEq(ScriptEnv &env) {
+ if (getCurRoom().curPicture != ARG(1))
+ return false;
+ env.ip += 2;
+ return true;
+}
+
+bool AdlEngine::o1_isItemPicEq(ScriptEnv &env) {
+ if (getItem(ARG(1)).picture != ARG(2))
+ return false;
+ env.ip += 3;
+ return true;
+}
+
+bool AdlEngine::o1_varAdd(ScriptEnv &env) {
+ setVar(ARG(2), getVar(ARG(2) + ARG(1)));
+ env.ip += 3;
+ return true;
+}
+
+bool AdlEngine::o1_varSub(ScriptEnv &env) {
+ setVar(ARG(2), getVar(ARG(2)) - ARG(1));
+ env.ip += 3;
+ return true;
+}
+
+bool AdlEngine::o1_varSet(ScriptEnv &env) {
+ setVar(ARG(1), ARG(2));
+ env.ip += 3;
+ return true;
+}
+
+bool AdlEngine::o1_listInv(ScriptEnv &env) {
+ Common::Array<Item>::const_iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->room == IDI_NONE)
+ printMessage(item->description);
+
+ ++env.ip;
+ return true;
+}
+
+bool AdlEngine::o1_moveItem(ScriptEnv &env) {
+ getItem(ARG(1)).room = ARG(2);
+ env.ip += 3;
+ return true;
+}
+
+bool AdlEngine::o1_setRoom(ScriptEnv &env) {
+ getCurRoom().curPicture = getCurRoom().picture;
+ _state.room = ARG(1);
+ env.ip += 2;
+ return true;
+}
+
+bool AdlEngine::o1_setCurPic(ScriptEnv &env) {
+ getCurRoom().curPicture = ARG(1);
+ env.ip += 2;
+ return true;
+}
+
+bool AdlEngine::o1_setPic(ScriptEnv &env) {
+ getCurRoom().picture = getCurRoom().curPicture = ARG(1);
+ env.ip += 2;
+ return true;
+}
+
+bool AdlEngine::o1_printMsg(ScriptEnv &env) {
+ printMessage(ARG(1));
+ env.ip += 2;
+ return true;
+}
+
+bool AdlEngine::o1_setLight(ScriptEnv &env) {
+ _state.isDark = false;
+ ++env.ip;
+ return true;
+}
+
+bool AdlEngine::o1_setDark(ScriptEnv &env) {
+ _state.isDark = true;
+ ++env.ip;
+ return true;
+}
+
+bool AdlEngine::o1_save(ScriptEnv &env) {
+ saveGameState(0, "");
+ ++env.ip;
+ return true;
+}
+
+bool AdlEngine::o1_restore(ScriptEnv &env) {
+ loadGameState(0);
+ ++env.ip;
+ _isRestoring = false;
+ return true;
+}
+
+bool AdlEngine::o1_restart(ScriptEnv &env) {
+ _display->printString(_strings.playAgain);
+ Common::String input = inputString();
+
+ if (input.size() == 0 || input[0] != APPLECHAR('N')) {
+ _isRestarting = true;
+ _display->clear(0x00);
+ _display->updateHiResScreen();
+ restartGame();
+ return false;
}
- if (actions)
- *actions = offset;
+ return o1_quit(env);
+}
+
+bool AdlEngine::o1_quit(ScriptEnv &env) {
+ printMessage(_messageIds.thanksForPlaying);
+ quitGame();
+ return false;
+}
+bool AdlEngine::o1_placeItem(ScriptEnv &env) {
+ getItem(ARG(1)).room = ARG(2);
+ getItem(ARG(1)).position.x = ARG(3);
+ getItem(ARG(1)).position.y = ARG(4);
+ env.ip += 5;
return true;
}
-void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
- for (uint i = 0; i < command.numAct; ++i) {
- switch (ARG(0)) {
- case IDO_ACT_VAR_ADD:
- setVar(ARG(2), getVar(ARG(2) + ARG(1)));
- offset += 3;
- break;
- case IDO_ACT_VAR_SUB:
- setVar(ARG(2), getVar(ARG(2)) - ARG(1));
- offset += 3;
- break;
- case IDO_ACT_VAR_SET:
- setVar(ARG(1), ARG(2));
- offset += 3;
- break;
- case IDO_ACT_LIST_ITEMS: {
- Common::Array<Item>::const_iterator item;
+bool AdlEngine::o1_setItemPic(ScriptEnv &env) {
+ getItem(ARG(2)).picture = ARG(1);
+ env.ip += 3;
+ return true;
+}
- for (item = _state.items.begin(); item != _state.items.end(); ++item)
- if (item->room == IDI_NONE)
- printMessage(item->description);
+bool AdlEngine::o1_resetPic(ScriptEnv &env) {
+ getCurRoom().curPicture = getCurRoom().picture;
+ ++env.ip;
+ return true;
+}
- ++offset;
- break;
- }
- case IDO_ACT_MOVE_ITEM:
- getItem(ARG(1)).room = ARG(2);
- offset += 3;
- break;
- case IDO_ACT_SET_ROOM:
- getCurRoom().curPicture = getCurRoom().picture;
- _state.room = ARG(1);
- offset += 2;
- break;
- case IDO_ACT_SET_CUR_PIC:
- getCurRoom().curPicture = ARG(1);
- offset += 2;
- break;
- case IDO_ACT_SET_PIC:
- getCurRoom().picture = getCurRoom().curPicture = ARG(1);
- offset += 2;
- break;
- case IDO_ACT_PRINT_MSG:
- printMessage(ARG(1));
- offset += 2;
- break;
- case IDO_ACT_SET_LIGHT:
- _state.isDark = false;
- ++offset;
- break;
- case IDO_ACT_SET_DARK:
- _state.isDark = true;
- ++offset;
- break;
- case IDO_ACT_SAVE:
- saveGameState(0, "");
- ++offset;
- break;
- case IDO_ACT_LOAD:
- loadGameState(0);
- ++offset;
- // Original engine does not jump out of the loop,
- // so we don't either.
- // We reset the restore flag, as the restore game
- // process is complete
- _isRestoring = false;
- break;
- case IDO_ACT_RESTART: {
- _display->printString(_strings.playAgain);
- Common::String input = inputString();
- if (input.size() == 0 || input[0] != APPLECHAR('N')) {
- _isRestarting = true;
- _display->clear(0x00);
- _display->updateHiResScreen();
- restartGame();
- return;
- }
- // Fall-through
- }
- case IDO_ACT_QUIT:
- printMessage(_messageIds.thanksForPlaying);
- quitGame();
- return;
- case IDO_ACT_PLACE_ITEM:
- getItem(ARG(1)).room = ARG(2);
- getItem(ARG(1)).position.x = ARG(3);
- getItem(ARG(1)).position.y = ARG(4);
- offset += 5;
- break;
- case IDO_ACT_SET_ITEM_PIC:
- getItem(ARG(2)).picture = ARG(1);
- offset += 3;
- break;
- case IDO_ACT_RESET_PIC:
- getCurRoom().curPicture = getCurRoom().picture;
- ++offset;
- break;
- case IDO_ACT_GO_NORTH:
- case IDO_ACT_GO_SOUTH:
- case IDO_ACT_GO_EAST:
- case IDO_ACT_GO_WEST:
- case IDO_ACT_GO_UP:
- case IDO_ACT_GO_DOWN: {
- byte room = getCurRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
-
- if (room == 0) {
- printMessage(_messageIds.cantGoThere);
- return;
- }
+bool AdlEngine::o1_goDirection(ScriptEnv &env) {
+ byte room = getCurRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
- getCurRoom().curPicture = getCurRoom().picture;
- _state.room = room;
- return;
- }
- case IDO_ACT_TAKE_ITEM:
- takeItem(noun);
- ++offset;
- break;
- case IDO_ACT_DROP_ITEM:
- dropItem(noun);
- ++offset;
- break;
- case IDO_ACT_SET_ROOM_PIC:
- getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
- offset += 3;
- break;
- default:
- error("Invalid action opcode %02x", ARG(0));
- }
+ if (room == 0) {
+ printMessage(_messageIds.cantGoThere);
+ return false;
}
+
+ getCurRoom().curPicture = getCurRoom().picture;
+ _state.room = room;
+ return false;
+}
+
+bool AdlEngine::o1_takeItem(ScriptEnv &env) {
+ takeItem(env.noun);
+ ++env.ip;
+ return true;
+}
+
+bool AdlEngine::o1_dropItem(ScriptEnv &env) {
+ dropItem(env.noun);
+ ++env.ip;
+ return true;
+}
+
+bool AdlEngine::o1_setRoomPic(ScriptEnv &env) {
+ getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
+ env.ip += 3;
+ return true;
}
#undef ARG
+bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
+ if (env.cmd.room != IDI_NONE && env.cmd.room != _state.room)
+ return false;
+
+ if (env.cmd.verb != IDI_NONE && env.cmd.verb != env.verb)
+ return false;
+
+ if (env.cmd.noun != IDI_NONE && env.cmd.noun != env.noun)
+ return false;
+
+ for (uint i = 0; i < env.cmd.numCond; ++i) {
+ byte op = env.cmd.script[env.ip];
+
+ if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
+ error("Unimplemented condition opcode %02x", op);
+
+ if (!(*_condOpcodes[op])(env))
+ return false;
+ }
+
+ if (actions)
+ *actions = env.ip;
+
+ return true;
+}
+
+void AdlEngine::doActions(ScriptEnv &env) {
+ for (uint i = 0; i < env.cmd.numAct; ++i) {
+ byte op = env.cmd.script[env.ip];
+
+ if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
+ error("Unimplemented action opcode %02x", op);
+
+ if (!(*_actOpcodes[op])(env))
+ return;
+ }
+}
+
bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
- uint offset = 0;
- if (matchCommand(*cmd, verb, noun, &offset)) {
- doActions(*cmd, noun, offset);
+ ScriptEnv env(*cmd, verb, noun);
+ if (matchCommand(env)) {
+ doActions(env);
return true;
}
}
@@ -987,9 +1106,9 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
- uint offset = 0;
- if (matchCommand(*cmd, verb, noun, &offset))
- doActions(*cmd, noun, offset);
+ ScriptEnv env(*cmd, verb, noun);
+ if (matchCommand(env))
+ doActions(env);
}
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 97077f9..e007b15 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -28,6 +28,7 @@
#include "common/str.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
+#include "common/func.h"
#include "engines/engine.h"
@@ -47,6 +48,9 @@ class Display;
class GraphicsMan;
class Speaker;
struct AdlGameDescription;
+struct ScriptEnv;
+
+typedef Common::Functor1<ScriptEnv &, bool> Opcode;
// Conditional opcodes
#define IDO_CND_ITEM_IN_ROOM 0x03
@@ -101,11 +105,22 @@ struct Picture {
uint16 offset;
};
+typedef Common::Array<byte> Script;
+
struct Command {
byte room;
byte verb, noun;
byte numCond, numAct;
- Common::Array<byte> script;
+ Script script;
+};
+
+struct ScriptEnv {
+ ScriptEnv(const Command &cmd_, byte verb_, byte noun_) :
+ cmd(cmd_), verb(verb_), noun(noun_), ip(0) { }
+
+ const Command &cmd;
+ byte verb, noun;
+ byte ip;
};
enum {
@@ -165,6 +180,38 @@ protected:
void readCommands(Common::ReadStream &stream, Commands &commands);
virtual void checkInput(byte verb, byte noun);
+ virtual void setupOpcodeTables();
+
+ // Opcodes
+ bool o1_isItemInRoom(ScriptEnv &env);
+ bool o1_isMovesGrEq(ScriptEnv &env);
+ bool o1_isVarEq(ScriptEnv &env);
+ bool o1_isCurPicEq(ScriptEnv &env);
+ bool o1_isItemPicEq(ScriptEnv &env);
+
+ bool o1_varAdd(ScriptEnv &env);
+ bool o1_varSub(ScriptEnv &env);
+ bool o1_varSet(ScriptEnv &env);
+ bool o1_listInv(ScriptEnv &env);
+ bool o1_moveItem(ScriptEnv &env);
+ bool o1_setRoom(ScriptEnv &env);
+ bool o1_setCurPic(ScriptEnv &env);
+ bool o1_setPic(ScriptEnv &env);
+ bool o1_printMsg(ScriptEnv &env);
+ bool o1_setLight(ScriptEnv &env);
+ bool o1_setDark(ScriptEnv &env);
+ bool o1_save(ScriptEnv &env);
+ bool o1_restore(ScriptEnv &env);
+ bool o1_restart(ScriptEnv &env);
+ bool o1_quit(ScriptEnv &env);
+ bool o1_placeItem(ScriptEnv &env);
+ bool o1_setItemPic(ScriptEnv &env);
+ bool o1_resetPic(ScriptEnv &env);
+ bool o1_goDirection(ScriptEnv &env);
+ bool o1_takeItem(ScriptEnv &env);
+ bool o1_dropItem(ScriptEnv &env);
+ bool o1_setRoomPic(ScriptEnv &env);
+
// Graphics
void clearScreen() const;
void drawItems() const;
@@ -183,8 +230,8 @@ protected:
void setVar(uint i, byte value);
void takeItem(byte noun);
void dropItem(byte noun);
- bool matchCommand(const Command &command, byte verb, byte noun, uint *actions = nullptr) const;
- void doActions(const Command &command, byte noun, byte offset);
+ bool matchCommand(ScriptEnv &env, uint *actions = nullptr) const;
+ void doActions(ScriptEnv &env);
bool doOneCommand(const Commands &commands, byte verb, byte noun);
void doAllCommands(const Commands &commands, byte verb, byte noun);
@@ -192,6 +239,8 @@ protected:
GraphicsMan *_graphics;
Speaker *_speaker;
+ // Opcodes
+ Common::Array<const Opcode *> _condOpcodes, _actOpcodes;
// Message strings in data file
Common::Array<Common::String> _messages;
// Picture data
Commit: eaacfe1eede00d6370d1abb0afe2f0e6cf622b16
https://github.com/scummvm/scummvm/commit/eaacfe1eede00d6370d1abb0afe2f0e6cf622b16
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use template for direction opcode
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index ad5f559..8d501d8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -330,13 +330,13 @@ void AdlEngine::setupOpcodeTables() {
Opcode(o1_setItemPic);
// 0x14
Opcode(o1_resetPic);
- Opcode(o1_goDirection);
- Opcode(o1_goDirection);
- Opcode(o1_goDirection);
+ Opcode(o1_goDirection<IDI_DIR_NORTH>);
+ Opcode(o1_goDirection<IDI_DIR_SOUTH>);
+ Opcode(o1_goDirection<IDI_DIR_EAST>);
// 0x18
- Opcode(o1_goDirection);
- Opcode(o1_goDirection);
- Opcode(o1_goDirection);
+ Opcode(o1_goDirection<IDI_DIR_WEST>);
+ Opcode(o1_goDirection<IDI_DIR_UP>);
+ Opcode(o1_goDirection<IDI_DIR_DOWN>);
Opcode(o1_takeItem);
// 0x1c
Opcode(o1_dropItem);
@@ -1017,8 +1017,9 @@ bool AdlEngine::o1_resetPic(ScriptEnv &env) {
return true;
}
+template <Direction D>
bool AdlEngine::o1_goDirection(ScriptEnv &env) {
- byte room = getCurRoom().connections[ARG(0) - IDO_ACT_GO_NORTH];
+ byte room = getCurRoom().connections[D];
if (room == 0) {
printMessage(_messageIds.cantGoThere);
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e007b15..ce42114 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -90,9 +90,19 @@ typedef Common::Functor1<ScriptEnv &, bool> Opcode;
#define IDI_WORD_SIZE 8
+enum Direction {
+ IDI_DIR_NORTH,
+ IDI_DIR_SOUTH,
+ IDI_DIR_EAST,
+ IDI_DIR_WEST,
+ IDI_DIR_UP,
+ IDI_DIR_DOWN,
+ IDI_DIR_TOTAL
+};
+
struct Room {
byte description;
- byte connections[6];
+ byte connections[IDI_DIR_TOTAL];
byte track;
byte sector;
byte offset;
@@ -207,6 +217,7 @@ protected:
bool o1_placeItem(ScriptEnv &env);
bool o1_setItemPic(ScriptEnv &env);
bool o1_resetPic(ScriptEnv &env);
+ template <Direction D>
bool o1_goDirection(ScriptEnv &env);
bool o1_takeItem(ScriptEnv &env);
bool o1_dropItem(ScriptEnv &env);
Commit: 37656db0d4959ab454eccd7d35668e0b46861fa6
https://github.com/scummvm/scummvm/commit/37656db0d4959ab454eccd7d35668e0b46861fa6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean up opcodes
Changed paths:
engines/adl/adl.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 8d501d8..6f946b8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -854,129 +854,129 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
-#define ARG(N) (env.cmd.script[env.ip + (N)])
+#define ARG(N) (e.cmd.script[e.ip + (N)])
-bool AdlEngine::o1_isItemInRoom(ScriptEnv &env) {
+bool AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
if (getItem(ARG(1)).room != ARG(2))
return false;
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_isMovesGrEq(ScriptEnv &env) {
+bool AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
if (ARG(1) > _state.moves)
return false;
- env.ip += 2;
+ e.ip += 2;
return true;
}
-bool AdlEngine::o1_isVarEq(ScriptEnv &env) {
+bool AdlEngine::o1_isVarEq(ScriptEnv &e) {
if (getVar(ARG(1)) != ARG(2))
return false;
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_isCurPicEq(ScriptEnv &env) {
+bool AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
if (getCurRoom().curPicture != ARG(1))
return false;
- env.ip += 2;
+ e.ip += 2;
return true;
}
-bool AdlEngine::o1_isItemPicEq(ScriptEnv &env) {
+bool AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
if (getItem(ARG(1)).picture != ARG(2))
return false;
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_varAdd(ScriptEnv &env) {
+bool AdlEngine::o1_varAdd(ScriptEnv &e) {
setVar(ARG(2), getVar(ARG(2) + ARG(1)));
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_varSub(ScriptEnv &env) {
+bool AdlEngine::o1_varSub(ScriptEnv &e) {
setVar(ARG(2), getVar(ARG(2)) - ARG(1));
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_varSet(ScriptEnv &env) {
+bool AdlEngine::o1_varSet(ScriptEnv &e) {
setVar(ARG(1), ARG(2));
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_listInv(ScriptEnv &env) {
+bool AdlEngine::o1_listInv(ScriptEnv &e) {
Common::Array<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
if (item->room == IDI_NONE)
printMessage(item->description);
- ++env.ip;
+ ++e.ip;
return true;
}
-bool AdlEngine::o1_moveItem(ScriptEnv &env) {
+bool AdlEngine::o1_moveItem(ScriptEnv &e) {
getItem(ARG(1)).room = ARG(2);
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_setRoom(ScriptEnv &env) {
+bool AdlEngine::o1_setRoom(ScriptEnv &e) {
getCurRoom().curPicture = getCurRoom().picture;
_state.room = ARG(1);
- env.ip += 2;
+ e.ip += 2;
return true;
}
-bool AdlEngine::o1_setCurPic(ScriptEnv &env) {
+bool AdlEngine::o1_setCurPic(ScriptEnv &e) {
getCurRoom().curPicture = ARG(1);
- env.ip += 2;
+ e.ip += 2;
return true;
}
-bool AdlEngine::o1_setPic(ScriptEnv &env) {
+bool AdlEngine::o1_setPic(ScriptEnv &e) {
getCurRoom().picture = getCurRoom().curPicture = ARG(1);
- env.ip += 2;
+ e.ip += 2;
return true;
}
-bool AdlEngine::o1_printMsg(ScriptEnv &env) {
+bool AdlEngine::o1_printMsg(ScriptEnv &e) {
printMessage(ARG(1));
- env.ip += 2;
+ e.ip += 2;
return true;
}
-bool AdlEngine::o1_setLight(ScriptEnv &env) {
+bool AdlEngine::o1_setLight(ScriptEnv &e) {
_state.isDark = false;
- ++env.ip;
+ ++e.ip;
return true;
}
-bool AdlEngine::o1_setDark(ScriptEnv &env) {
+bool AdlEngine::o1_setDark(ScriptEnv &e) {
_state.isDark = true;
- ++env.ip;
+ ++e.ip;
return true;
}
-bool AdlEngine::o1_save(ScriptEnv &env) {
+bool AdlEngine::o1_save(ScriptEnv &e) {
saveGameState(0, "");
- ++env.ip;
+ ++e.ip;
return true;
}
-bool AdlEngine::o1_restore(ScriptEnv &env) {
+bool AdlEngine::o1_restore(ScriptEnv &e) {
loadGameState(0);
- ++env.ip;
+ ++e.ip;
_isRestoring = false;
return true;
}
-bool AdlEngine::o1_restart(ScriptEnv &env) {
+bool AdlEngine::o1_restart(ScriptEnv &e) {
_display->printString(_strings.playAgain);
Common::String input = inputString();
@@ -988,37 +988,37 @@ bool AdlEngine::o1_restart(ScriptEnv &env) {
return false;
}
- return o1_quit(env);
+ return o1_quit(e);
}
-bool AdlEngine::o1_quit(ScriptEnv &env) {
+bool AdlEngine::o1_quit(ScriptEnv &e) {
printMessage(_messageIds.thanksForPlaying);
quitGame();
return false;
}
-bool AdlEngine::o1_placeItem(ScriptEnv &env) {
+bool AdlEngine::o1_placeItem(ScriptEnv &e) {
getItem(ARG(1)).room = ARG(2);
getItem(ARG(1)).position.x = ARG(3);
getItem(ARG(1)).position.y = ARG(4);
- env.ip += 5;
+ e.ip += 5;
return true;
}
-bool AdlEngine::o1_setItemPic(ScriptEnv &env) {
+bool AdlEngine::o1_setItemPic(ScriptEnv &e) {
getItem(ARG(2)).picture = ARG(1);
- env.ip += 3;
+ e.ip += 3;
return true;
}
-bool AdlEngine::o1_resetPic(ScriptEnv &env) {
+bool AdlEngine::o1_resetPic(ScriptEnv &e) {
getCurRoom().curPicture = getCurRoom().picture;
- ++env.ip;
+ ++e.ip;
return true;
}
template <Direction D>
-bool AdlEngine::o1_goDirection(ScriptEnv &env) {
+bool AdlEngine::o1_goDirection(ScriptEnv &e) {
byte room = getCurRoom().connections[D];
if (room == 0) {
@@ -1031,21 +1031,21 @@ bool AdlEngine::o1_goDirection(ScriptEnv &env) {
return false;
}
-bool AdlEngine::o1_takeItem(ScriptEnv &env) {
- takeItem(env.noun);
- ++env.ip;
+bool AdlEngine::o1_takeItem(ScriptEnv &e) {
+ takeItem(e.noun);
+ ++e.ip;
return true;
}
-bool AdlEngine::o1_dropItem(ScriptEnv &env) {
- dropItem(env.noun);
- ++env.ip;
+bool AdlEngine::o1_dropItem(ScriptEnv &e) {
+ dropItem(e.noun);
+ ++e.ip;
return true;
}
-bool AdlEngine::o1_setRoomPic(ScriptEnv &env) {
+bool AdlEngine::o1_setRoomPic(ScriptEnv &e) {
getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
- env.ip += 3;
+ e.ip += 3;
return true;
}
Commit: a9afe17169295b69c50bc3a727f4dd8034c24f2e
https://github.com/scummvm/scummvm/commit/a9afe17169295b69c50bc3a727f4dd8034c24f2e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Replace opcode arg macro with function
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 6f946b8..069e360 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -854,57 +854,55 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
-#define ARG(N) (e.cmd.script[e.ip + (N)])
-
bool AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
- if (getItem(ARG(1)).room != ARG(2))
+ if (getItem(e.arg(1)).room != e.arg(2))
return false;
e.ip += 3;
return true;
}
bool AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
- if (ARG(1) > _state.moves)
+ if (e.arg(1) > _state.moves)
return false;
e.ip += 2;
return true;
}
bool AdlEngine::o1_isVarEq(ScriptEnv &e) {
- if (getVar(ARG(1)) != ARG(2))
+ if (getVar(e.arg(1)) != e.arg(2))
return false;
e.ip += 3;
return true;
}
bool AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
- if (getCurRoom().curPicture != ARG(1))
+ if (getCurRoom().curPicture != e.arg(1))
return false;
e.ip += 2;
return true;
}
bool AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
- if (getItem(ARG(1)).picture != ARG(2))
+ if (getItem(e.arg(1)).picture != e.arg(2))
return false;
e.ip += 3;
return true;
}
bool AdlEngine::o1_varAdd(ScriptEnv &e) {
- setVar(ARG(2), getVar(ARG(2) + ARG(1)));
+ setVar(e.arg(2), getVar(e.arg(2) + e.arg(1)));
e.ip += 3;
return true;
}
bool AdlEngine::o1_varSub(ScriptEnv &e) {
- setVar(ARG(2), getVar(ARG(2)) - ARG(1));
+ setVar(e.arg(2), getVar(e.arg(2)) - e.arg(1));
e.ip += 3;
return true;
}
bool AdlEngine::o1_varSet(ScriptEnv &e) {
- setVar(ARG(1), ARG(2));
+ setVar(e.arg(1), e.arg(2));
e.ip += 3;
return true;
}
@@ -921,32 +919,32 @@ bool AdlEngine::o1_listInv(ScriptEnv &e) {
}
bool AdlEngine::o1_moveItem(ScriptEnv &e) {
- getItem(ARG(1)).room = ARG(2);
+ getItem(e.arg(1)).room = e.arg(2);
e.ip += 3;
return true;
}
bool AdlEngine::o1_setRoom(ScriptEnv &e) {
getCurRoom().curPicture = getCurRoom().picture;
- _state.room = ARG(1);
+ _state.room = e.arg(1);
e.ip += 2;
return true;
}
bool AdlEngine::o1_setCurPic(ScriptEnv &e) {
- getCurRoom().curPicture = ARG(1);
+ getCurRoom().curPicture = e.arg(1);
e.ip += 2;
return true;
}
bool AdlEngine::o1_setPic(ScriptEnv &e) {
- getCurRoom().picture = getCurRoom().curPicture = ARG(1);
+ getCurRoom().picture = getCurRoom().curPicture = e.arg(1);
e.ip += 2;
return true;
}
bool AdlEngine::o1_printMsg(ScriptEnv &e) {
- printMessage(ARG(1));
+ printMessage(e.arg(1));
e.ip += 2;
return true;
}
@@ -998,15 +996,15 @@ bool AdlEngine::o1_quit(ScriptEnv &e) {
}
bool AdlEngine::o1_placeItem(ScriptEnv &e) {
- getItem(ARG(1)).room = ARG(2);
- getItem(ARG(1)).position.x = ARG(3);
- getItem(ARG(1)).position.y = ARG(4);
+ getItem(e.arg(1)).room = e.arg(2);
+ getItem(e.arg(1)).position.x = e.arg(3);
+ getItem(e.arg(1)).position.y = e.arg(4);
e.ip += 5;
return true;
}
bool AdlEngine::o1_setItemPic(ScriptEnv &e) {
- getItem(ARG(2)).picture = ARG(1);
+ getItem(e.arg(2)).picture = e.arg(1);
e.ip += 3;
return true;
}
@@ -1044,13 +1042,11 @@ bool AdlEngine::o1_dropItem(ScriptEnv &e) {
}
bool AdlEngine::o1_setRoomPic(ScriptEnv &e) {
- getRoom(ARG(1)).picture = getRoom(ARG(1)).curPicture = ARG(2);
+ getRoom(e.arg(1)).picture = getRoom(e.arg(1)).curPicture = e.arg(2);
e.ip += 3;
return true;
}
-#undef ARG
-
bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
if (env.cmd.room != IDI_NONE && env.cmd.room != _state.room)
return false;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ce42114..8e4a7fe 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -124,10 +124,15 @@ struct Command {
Script script;
};
-struct ScriptEnv {
+class ScriptEnv {
+public:
ScriptEnv(const Command &cmd_, byte verb_, byte noun_) :
cmd(cmd_), verb(verb_), noun(noun_), ip(0) { }
+ byte op() const { return cmd.script[ip]; }
+ // We keep this 1-based for easier comparison with the original engine
+ byte arg(uint i) const { return cmd.script[ip + i]; }
+
const Command &cmd;
byte verb, noun;
byte ip;
Commit: f93ae5479e21877e3c527b7a7383f3e1edb8e22f
https://github.com/scummvm/scummvm/commit/f93ae5479e21877e3c527b7a7383f3e1edb8e22f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Make opcodes return arg count
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 069e360..7128928 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -278,7 +278,7 @@ void AdlEngine::checkInput(byte verb, byte noun) {
printMessage(_messageIds.dontUnderstand);
}
-typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
#define SetOpcodeTable(x) table = &x;
#define Opcode(x) table->push_back(new OpcodeV1(this, &AdlEngine::x))
#define OpcodeUnImpl() table->push_back(new OpcodeV1(this, 0))
@@ -852,129 +852,111 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
}
}
-typedef Common::Functor1Mem<ScriptEnv &, bool, AdlEngine> OpcodeV1;
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
-bool AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
+int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
if (getItem(e.arg(1)).room != e.arg(2))
- return false;
- e.ip += 3;
- return true;
+ return -1;
+ return 2;
}
-bool AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
+int AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
if (e.arg(1) > _state.moves)
- return false;
- e.ip += 2;
- return true;
+ return -1;
+ return 1;
}
-bool AdlEngine::o1_isVarEq(ScriptEnv &e) {
+int AdlEngine::o1_isVarEq(ScriptEnv &e) {
if (getVar(e.arg(1)) != e.arg(2))
- return false;
- e.ip += 3;
- return true;
+ return -1;
+ return 2;
}
-bool AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
+int AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
if (getCurRoom().curPicture != e.arg(1))
- return false;
- e.ip += 2;
- return true;
+ return -1;
+ return 1;
}
-bool AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
+int AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
if (getItem(e.arg(1)).picture != e.arg(2))
- return false;
- e.ip += 3;
- return true;
+ return -1;
+ return 2;
}
-bool AdlEngine::o1_varAdd(ScriptEnv &e) {
+int AdlEngine::o1_varAdd(ScriptEnv &e) {
setVar(e.arg(2), getVar(e.arg(2) + e.arg(1)));
- e.ip += 3;
- return true;
+ return 2;
}
-bool AdlEngine::o1_varSub(ScriptEnv &e) {
+int AdlEngine::o1_varSub(ScriptEnv &e) {
setVar(e.arg(2), getVar(e.arg(2)) - e.arg(1));
- e.ip += 3;
- return true;
+ return 2;
}
-bool AdlEngine::o1_varSet(ScriptEnv &e) {
+int AdlEngine::o1_varSet(ScriptEnv &e) {
setVar(e.arg(1), e.arg(2));
- e.ip += 3;
- return true;
+ return 2;
}
-bool AdlEngine::o1_listInv(ScriptEnv &e) {
+int AdlEngine::o1_listInv(ScriptEnv &e) {
Common::Array<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
if (item->room == IDI_NONE)
printMessage(item->description);
- ++e.ip;
- return true;
+ return 0;
}
-bool AdlEngine::o1_moveItem(ScriptEnv &e) {
+int AdlEngine::o1_moveItem(ScriptEnv &e) {
getItem(e.arg(1)).room = e.arg(2);
- e.ip += 3;
- return true;
+ return 2;
}
-bool AdlEngine::o1_setRoom(ScriptEnv &e) {
+int AdlEngine::o1_setRoom(ScriptEnv &e) {
getCurRoom().curPicture = getCurRoom().picture;
_state.room = e.arg(1);
- e.ip += 2;
- return true;
+ return 1;
}
-bool AdlEngine::o1_setCurPic(ScriptEnv &e) {
+int AdlEngine::o1_setCurPic(ScriptEnv &e) {
getCurRoom().curPicture = e.arg(1);
- e.ip += 2;
- return true;
+ return 1;
}
-bool AdlEngine::o1_setPic(ScriptEnv &e) {
+int AdlEngine::o1_setPic(ScriptEnv &e) {
getCurRoom().picture = getCurRoom().curPicture = e.arg(1);
- e.ip += 2;
- return true;
+ return 1;
}
-bool AdlEngine::o1_printMsg(ScriptEnv &e) {
+int AdlEngine::o1_printMsg(ScriptEnv &e) {
printMessage(e.arg(1));
- e.ip += 2;
- return true;
+ return 1;
}
-bool AdlEngine::o1_setLight(ScriptEnv &e) {
+int AdlEngine::o1_setLight(ScriptEnv &e) {
_state.isDark = false;
- ++e.ip;
- return true;
+ return 0;
}
-bool AdlEngine::o1_setDark(ScriptEnv &e) {
+int AdlEngine::o1_setDark(ScriptEnv &e) {
_state.isDark = true;
- ++e.ip;
- return true;
+ return 0;
}
-bool AdlEngine::o1_save(ScriptEnv &e) {
+int AdlEngine::o1_save(ScriptEnv &e) {
saveGameState(0, "");
- ++e.ip;
- return true;
+ return 0;
}
-bool AdlEngine::o1_restore(ScriptEnv &e) {
+int AdlEngine::o1_restore(ScriptEnv &e) {
loadGameState(0);
- ++e.ip;
_isRestoring = false;
- return true;
+ return 0;
}
-bool AdlEngine::o1_restart(ScriptEnv &e) {
+int AdlEngine::o1_restart(ScriptEnv &e) {
_display->printString(_strings.playAgain);
Common::String input = inputString();
@@ -983,68 +965,62 @@ bool AdlEngine::o1_restart(ScriptEnv &e) {
_display->clear(0x00);
_display->updateHiResScreen();
restartGame();
- return false;
+ return -1;
}
return o1_quit(e);
}
-bool AdlEngine::o1_quit(ScriptEnv &e) {
+int AdlEngine::o1_quit(ScriptEnv &e) {
printMessage(_messageIds.thanksForPlaying);
quitGame();
- return false;
+ return -1;
}
-bool AdlEngine::o1_placeItem(ScriptEnv &e) {
+int AdlEngine::o1_placeItem(ScriptEnv &e) {
getItem(e.arg(1)).room = e.arg(2);
getItem(e.arg(1)).position.x = e.arg(3);
getItem(e.arg(1)).position.y = e.arg(4);
- e.ip += 5;
- return true;
+ return 4;
}
-bool AdlEngine::o1_setItemPic(ScriptEnv &e) {
+int AdlEngine::o1_setItemPic(ScriptEnv &e) {
getItem(e.arg(2)).picture = e.arg(1);
- e.ip += 3;
- return true;
+ return 2;
}
-bool AdlEngine::o1_resetPic(ScriptEnv &e) {
+int AdlEngine::o1_resetPic(ScriptEnv &e) {
getCurRoom().curPicture = getCurRoom().picture;
- ++e.ip;
- return true;
+ return 0;
}
template <Direction D>
-bool AdlEngine::o1_goDirection(ScriptEnv &e) {
+int AdlEngine::o1_goDirection(ScriptEnv &e) {
byte room = getCurRoom().connections[D];
if (room == 0) {
printMessage(_messageIds.cantGoThere);
- return false;
+ return -1;
}
getCurRoom().curPicture = getCurRoom().picture;
_state.room = room;
- return false;
+ return -1;
}
-bool AdlEngine::o1_takeItem(ScriptEnv &e) {
+int AdlEngine::o1_takeItem(ScriptEnv &e) {
takeItem(e.noun);
- ++e.ip;
- return true;
+ return 0;
}
-bool AdlEngine::o1_dropItem(ScriptEnv &e) {
+int AdlEngine::o1_dropItem(ScriptEnv &e) {
dropItem(e.noun);
- ++e.ip;
- return true;
+ return 0;
}
-bool AdlEngine::o1_setRoomPic(ScriptEnv &e) {
+int AdlEngine::o1_setRoomPic(ScriptEnv &e) {
getRoom(e.arg(1)).picture = getRoom(e.arg(1)).curPicture = e.arg(2);
- e.ip += 3;
- return true;
+ return 2;
}
bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
@@ -1063,8 +1039,12 @@ bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
error("Unimplemented condition opcode %02x", op);
- if (!(*_condOpcodes[op])(env))
+ int numArgs = (*_condOpcodes[op])(env);
+
+ if (numArgs < 0)
return false;
+
+ env.ip += numArgs + 1;
}
if (actions)
@@ -1080,8 +1060,12 @@ void AdlEngine::doActions(ScriptEnv &env) {
if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
error("Unimplemented action opcode %02x", op);
- if (!(*_actOpcodes[op])(env))
+ int numArgs = (*_actOpcodes[op])(env);
+
+ if (numArgs < 0)
return;
+
+ env.ip += numArgs + 1;
}
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 8e4a7fe..1d93553 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -50,8 +50,6 @@ class Speaker;
struct AdlGameDescription;
struct ScriptEnv;
-typedef Common::Functor1<ScriptEnv &, bool> Opcode;
-
// Conditional opcodes
#define IDO_CND_ITEM_IN_ROOM 0x03
#define IDO_CND_MOVES_GE 0x05
@@ -198,35 +196,35 @@ protected:
virtual void setupOpcodeTables();
// Opcodes
- bool o1_isItemInRoom(ScriptEnv &env);
- bool o1_isMovesGrEq(ScriptEnv &env);
- bool o1_isVarEq(ScriptEnv &env);
- bool o1_isCurPicEq(ScriptEnv &env);
- bool o1_isItemPicEq(ScriptEnv &env);
-
- bool o1_varAdd(ScriptEnv &env);
- bool o1_varSub(ScriptEnv &env);
- bool o1_varSet(ScriptEnv &env);
- bool o1_listInv(ScriptEnv &env);
- bool o1_moveItem(ScriptEnv &env);
- bool o1_setRoom(ScriptEnv &env);
- bool o1_setCurPic(ScriptEnv &env);
- bool o1_setPic(ScriptEnv &env);
- bool o1_printMsg(ScriptEnv &env);
- bool o1_setLight(ScriptEnv &env);
- bool o1_setDark(ScriptEnv &env);
- bool o1_save(ScriptEnv &env);
- bool o1_restore(ScriptEnv &env);
- bool o1_restart(ScriptEnv &env);
- bool o1_quit(ScriptEnv &env);
- bool o1_placeItem(ScriptEnv &env);
- bool o1_setItemPic(ScriptEnv &env);
- bool o1_resetPic(ScriptEnv &env);
+ int o1_isItemInRoom(ScriptEnv &e);
+ int o1_isMovesGrEq(ScriptEnv &e);
+ int o1_isVarEq(ScriptEnv &e);
+ int o1_isCurPicEq(ScriptEnv &e);
+ int o1_isItemPicEq(ScriptEnv &e);
+
+ int o1_varAdd(ScriptEnv &e);
+ int o1_varSub(ScriptEnv &e);
+ int o1_varSet(ScriptEnv &e);
+ int o1_listInv(ScriptEnv &e);
+ int o1_moveItem(ScriptEnv &e);
+ int o1_setRoom(ScriptEnv &e);
+ int o1_setCurPic(ScriptEnv &e);
+ int o1_setPic(ScriptEnv &e);
+ int o1_printMsg(ScriptEnv &e);
+ int o1_setLight(ScriptEnv &e);
+ int o1_setDark(ScriptEnv &e);
+ int o1_save(ScriptEnv &e);
+ int o1_restore(ScriptEnv &e);
+ int o1_restart(ScriptEnv &e);
+ int o1_quit(ScriptEnv &e);
+ int o1_placeItem(ScriptEnv &e);
+ int o1_setItemPic(ScriptEnv &e);
+ int o1_resetPic(ScriptEnv &e);
template <Direction D>
- bool o1_goDirection(ScriptEnv &env);
- bool o1_takeItem(ScriptEnv &env);
- bool o1_dropItem(ScriptEnv &env);
- bool o1_setRoomPic(ScriptEnv &env);
+ int o1_goDirection(ScriptEnv &e);
+ int o1_takeItem(ScriptEnv &e);
+ int o1_dropItem(ScriptEnv &e);
+ int o1_setRoomPic(ScriptEnv &e);
// Graphics
void clearScreen() const;
@@ -256,6 +254,7 @@ protected:
Speaker *_speaker;
// Opcodes
+ typedef Common::Functor1<ScriptEnv &, int> Opcode;
Common::Array<const Opcode *> _condOpcodes, _actOpcodes;
// Message strings in data file
Common::Array<Common::String> _messages;
Commit: 0cb889b55e43007bc0fd74d7bccf7aa130fdac6a
https://github.com/scummvm/scummvm/commit/0cb889b55e43007bc0fd74d7bccf7aa130fdac6a
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Remove unused opcode #defines
Changed paths:
engines/adl/adl.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 1d93553..c12fb55 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -50,41 +50,9 @@ class Speaker;
struct AdlGameDescription;
struct ScriptEnv;
-// Conditional opcodes
-#define IDO_CND_ITEM_IN_ROOM 0x03
-#define IDO_CND_MOVES_GE 0x05
-#define IDO_CND_VAR_EQ 0x06
-#define IDO_CND_CUR_PIC_EQ 0x09
-#define IDO_CND_ITEM_PIC_EQ 0x0a
-
-// Action opcodes
-#define IDO_ACT_VAR_ADD 0x01
-#define IDO_ACT_VAR_SUB 0x02
-#define IDO_ACT_VAR_SET 0x03
-#define IDO_ACT_LIST_ITEMS 0x04
-#define IDO_ACT_MOVE_ITEM 0x05
-#define IDO_ACT_SET_ROOM 0x06
-#define IDO_ACT_SET_CUR_PIC 0x07
-#define IDO_ACT_SET_PIC 0x08
-#define IDO_ACT_PRINT_MSG 0x09
-#define IDO_ACT_SET_LIGHT 0x0a
-#define IDO_ACT_SET_DARK 0x0b
-#define IDO_ACT_QUIT 0x0d
+// Save and restore opcodes
#define IDO_ACT_SAVE 0x0f
#define IDO_ACT_LOAD 0x10
-#define IDO_ACT_RESTART 0x11
-#define IDO_ACT_PLACE_ITEM 0x12
-#define IDO_ACT_SET_ITEM_PIC 0x13
-#define IDO_ACT_RESET_PIC 0x14
-#define IDO_ACT_GO_NORTH 0x15
-#define IDO_ACT_GO_SOUTH 0x16
-#define IDO_ACT_GO_EAST 0x17
-#define IDO_ACT_GO_WEST 0x18
-#define IDO_ACT_GO_UP 0x19
-#define IDO_ACT_GO_DOWN 0x1a
-#define IDO_ACT_TAKE_ITEM 0x1b
-#define IDO_ACT_DROP_ITEM 0x1c
-#define IDO_ACT_SET_ROOM_PIC 0x1d
#define IDI_WORD_SIZE 8
Commit: 60a9a592f5641655d1e0b00731603298bc938ac7
https://github.com/scummvm/scummvm/commit/60a9a592f5641655d1e0b00731603298bc938ac7
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean up script handling
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 7128928..31c4485 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -724,10 +724,9 @@ bool AdlEngine::canSaveGameStateCurrently() {
// "SAVE GAME". This prevents saving via the GMM in situations where
// it wouldn't otherwise be possible to do so.
for (cmd = _roomCommands.begin(); cmd != _roomCommands.end(); ++cmd) {
- ScriptEnv env(*cmd, _saveVerb, _saveNoun);
- uint offset;
- if (matchCommand(env, &offset))
- return cmd->script[offset] == IDO_ACT_SAVE;
+ ScriptEnv env(*cmd, _state.room, _saveVerb, _saveNoun);
+ if (matchCommand(env))
+ return env.op() == IDO_ACT_SAVE;
}
return false;
@@ -1009,12 +1008,12 @@ int AdlEngine::o1_goDirection(ScriptEnv &e) {
}
int AdlEngine::o1_takeItem(ScriptEnv &e) {
- takeItem(e.noun);
+ takeItem(e.getNoun());
return 0;
}
int AdlEngine::o1_dropItem(ScriptEnv &e) {
- dropItem(e.noun);
+ dropItem(e.getNoun());
return 0;
}
@@ -1023,18 +1022,12 @@ int AdlEngine::o1_setRoomPic(ScriptEnv &e) {
return 2;
}
-bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
- if (env.cmd.room != IDI_NONE && env.cmd.room != _state.room)
- return false;
-
- if (env.cmd.verb != IDI_NONE && env.cmd.verb != env.verb)
+bool AdlEngine::matchCommand(ScriptEnv &env) const {
+ if (!env.isMatch())
return false;
- if (env.cmd.noun != IDI_NONE && env.cmd.noun != env.noun)
- return false;
-
- for (uint i = 0; i < env.cmd.numCond; ++i) {
- byte op = env.cmd.script[env.ip];
+ for (uint i = 0; i < env.getCondCount(); ++i) {
+ byte op = env.op();
if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
error("Unimplemented condition opcode %02x", op);
@@ -1044,18 +1037,15 @@ bool AdlEngine::matchCommand(ScriptEnv &env, uint *actions) const {
if (numArgs < 0)
return false;
- env.ip += numArgs + 1;
+ env.skip(numArgs + 1);
}
- if (actions)
- *actions = env.ip;
-
return true;
}
void AdlEngine::doActions(ScriptEnv &env) {
- for (uint i = 0; i < env.cmd.numAct; ++i) {
- byte op = env.cmd.script[env.ip];
+ for (uint i = 0; i < env.getActCount(); ++i) {
+ byte op = env.op();
if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
error("Unimplemented action opcode %02x", op);
@@ -1065,7 +1055,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
if (numArgs < 0)
return;
- env.ip += numArgs + 1;
+ env.skip(numArgs + 1);
}
}
@@ -1073,7 +1063,7 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
- ScriptEnv env(*cmd, verb, noun);
+ ScriptEnv env(*cmd, _state.room, verb, noun);
if (matchCommand(env)) {
doActions(env);
return true;
@@ -1087,7 +1077,7 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
- ScriptEnv env(*cmd, verb, noun);
+ ScriptEnv env(*cmd, _state.room, verb, noun);
if (matchCommand(env))
doActions(env);
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index c12fb55..e7c36ae 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -54,6 +54,8 @@ struct ScriptEnv;
#define IDO_ACT_SAVE 0x0f
#define IDO_ACT_LOAD 0x10
+#define IDI_NONE 0xfe
+
#define IDI_WORD_SIZE 8
enum Direction {
@@ -92,16 +94,28 @@ struct Command {
class ScriptEnv {
public:
- ScriptEnv(const Command &cmd_, byte verb_, byte noun_) :
- cmd(cmd_), verb(verb_), noun(noun_), ip(0) { }
+ ScriptEnv(const Command &cmd, byte room, byte verb, byte noun) :
+ _cmd(cmd), _room(room), _verb(verb), _noun(noun), _ip(0) { }
- byte op() const { return cmd.script[ip]; }
+ byte op() const { return _cmd.script[_ip]; }
// We keep this 1-based for easier comparison with the original engine
- byte arg(uint i) const { return cmd.script[ip + i]; }
+ byte arg(uint i) const { return _cmd.script[_ip + i]; }
+ void skip(uint i) { _ip += i; }
- const Command &cmd;
- byte verb, noun;
- byte ip;
+ bool isMatch() const {
+ return (_cmd.room == IDI_NONE || _cmd.room == _room) &&
+ (_cmd.verb == IDI_NONE || _cmd.verb == _verb) &&
+ (_cmd.noun == IDI_NONE || _cmd.noun == _noun);
+ }
+
+ byte getCondCount() const { return _cmd.numCond; }
+ byte getActCount() const { return _cmd.numAct; }
+ byte getNoun() const { return _noun; }
+
+private:
+ const Command &_cmd;
+ const byte _room, _verb, _noun;
+ byte _ip;
};
enum {
@@ -110,8 +124,6 @@ enum {
IDI_ITEM_DOESNT_MOVE
};
-#define IDI_NONE 0xfe
-
struct Item {
byte noun;
byte room;
@@ -212,7 +224,7 @@ protected:
void setVar(uint i, byte value);
void takeItem(byte noun);
void dropItem(byte noun);
- bool matchCommand(ScriptEnv &env, uint *actions = nullptr) const;
+ bool matchCommand(ScriptEnv &env) const;
void doActions(ScriptEnv &env);
bool doOneCommand(const Commands &commands, byte verb, byte noun);
void doAllCommands(const Commands &commands, byte verb, byte noun);
Commit: ddf1151a534cf215cc0ffe972163489c319bdc63
https://github.com/scummvm/scummvm/commit/ddf1151a534cf215cc0ffe972163489c319bdc63
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add new class for second generation ADL
Changed paths:
A engines/adl/adl_v2.cpp
A engines/adl/adl_v2.h
engines/adl/hires2.h
engines/adl/module.mk
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
new file mode 100644
index 0000000..55ea15d
--- /dev/null
+++ b/engines/adl/adl_v2.cpp
@@ -0,0 +1,126 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "adl/adl_v2.h"
+
+namespace Adl {
+
+AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine(syst, gd) {
+}
+
+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))
+#define OpcodeUnImpl() table->push_back(new OpcodeV2(this, 0))
+
+void AdlEngine_v2::setupOpcodeTables() {
+ Common::Array<const Opcode *> *table = 0;
+
+ SetOpcodeTable(_condOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ OpcodeUnImpl();
+ OpcodeUnImpl();
+ Opcode(o2_isItemInRoom);
+ // 0x04
+ OpcodeUnImpl();
+ Opcode(o1_isMovesGrEq);
+ Opcode(o1_isVarEq);
+ OpcodeUnImpl();
+ // 0x08
+ OpcodeUnImpl();
+ Opcode(o1_isCurPicEq);
+ Opcode(o1_isItemPicEq);
+
+ SetOpcodeTable(_actOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o1_varAdd);
+ Opcode(o1_varSub);
+ Opcode(o1_varSet);
+ // 0x04
+ Opcode(o1_listInv);
+ Opcode(o2_moveItem);
+ Opcode(o1_setRoom);
+ Opcode(o1_setCurPic);
+ // 0x08
+ Opcode(o1_setPic);
+ Opcode(o1_printMsg);
+ Opcode(o1_setLight);
+ Opcode(o1_setDark);
+ // 0x0c
+ OpcodeUnImpl();
+ Opcode(o1_quit);
+ OpcodeUnImpl();
+ Opcode(o1_save);
+ // 0x10
+ Opcode(o1_restore);
+ Opcode(o1_restart);
+ Opcode(o1_placeItem);
+ Opcode(o1_setItemPic);
+ // 0x14
+ Opcode(o1_resetPic);
+ Opcode(o1_goDirection<IDI_DIR_NORTH>);
+ Opcode(o1_goDirection<IDI_DIR_SOUTH>);
+ Opcode(o1_goDirection<IDI_DIR_EAST>);
+ // 0x18
+ Opcode(o1_goDirection<IDI_DIR_WEST>);
+ Opcode(o1_goDirection<IDI_DIR_UP>);
+ Opcode(o1_goDirection<IDI_DIR_DOWN>);
+ Opcode(o1_takeItem);
+ // 0x1c
+ Opcode(o1_dropItem);
+ Opcode(o1_setRoomPic);
+}
+
+int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
+ byte room = e.arg(2);
+
+ if (room == IDI_CUR_ROOM)
+ room = _state.room;
+
+ if (getItem(e.arg(1)).room != room)
+ return -1;
+
+ return 2;
+}
+
+int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
+ byte room = e.arg(2);
+
+ if (room == IDI_CUR_ROOM)
+ room = _state.room;
+
+ Item &item = getItem(e.arg(1));
+
+ // Not implemented: set redraw flag if item room == displayed room
+
+ // Set items that move from inventory to a room to state "dropped"
+ if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
+ item.state = IDI_ITEM_MOVED;
+
+ item.room = room;
+ return 2;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
new file mode 100644
index 0000000..2e8b0f0
--- /dev/null
+++ b/engines/adl/adl_v2.h
@@ -0,0 +1,49 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_ADL_V2_H
+#define ADL_ADL_V2_H
+
+#include "adl/adl.h"
+
+#define IDI_CUR_ROOM 0xfc
+#define IDI_VOID_ROOM 0xfd
+
+namespace Adl {
+
+class AdlEngine_v2 : public AdlEngine {
+public:
+ virtual ~AdlEngine_v2() { }
+
+protected:
+ AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
+
+ virtual void setupOpcodeTables();
+
+ int o2_isItemInRoom(ScriptEnv &e);
+
+ int o2_moveItem(ScriptEnv &e);
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 516ea52..8ed51b8 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -25,7 +25,7 @@
#include "common/str.h"
-#include "adl/adl.h"
+#include "adl/adl_v2.h"
namespace Common {
class ReadStream;
@@ -85,9 +85,9 @@ struct RoomData {
Commands commands;
};
-class HiRes2Engine : public AdlEngine {
+class HiRes2Engine : public AdlEngine_v2 {
public:
- HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _linesPrinted(0) { }
+ HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd), _linesPrinted(0) { }
private:
// AdlEngine
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 35e1228..7599957 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -2,6 +2,7 @@ MODULE := engines/adl
MODULE_OBJS := \
adl.o \
+ adl_v2.o \
detection.o \
display.o \
graphics.o \
Commit: fab489c530fb89ce92dcfa0ce62f0ca2f3dcc676
https://github.com/scummvm/scummvm/commit/fab489c530fb89ce92dcfa0ce62f0ca2f3dcc676
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Rename IDI_ITEM_MOVED to IDI_ITEM_DROPPED
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 31c4485..778d821 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -357,7 +357,7 @@ void AdlEngine::drawItems() const {
if (item->room != _state.room)
continue;
- if (item->state == IDI_ITEM_MOVED) {
+ if (item->state == IDI_ITEM_DROPPED) {
if (getCurRoom().picture == getCurRoom().curPicture) {
const Common::Point &p = _itemOffsets[dropped];
drawItem(*item, p);
@@ -444,7 +444,7 @@ void AdlEngine::takeItem(byte noun) {
return;
}
- if (item->state == IDI_ITEM_MOVED) {
+ if (item->state == IDI_ITEM_DROPPED) {
item->room = IDI_NONE;
return;
}
@@ -453,7 +453,7 @@ void AdlEngine::takeItem(byte noun) {
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
if (*pic == getCurRoom().curPicture) {
item->room = IDI_NONE;
- item->state = IDI_ITEM_MOVED;
+ item->state = IDI_ITEM_DROPPED;
return;
}
}
@@ -470,7 +470,7 @@ void AdlEngine::dropItem(byte noun) {
continue;
item->room = _state.room;
- item->state = IDI_ITEM_MOVED;
+ item->state = IDI_ITEM_DROPPED;
return;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e7c36ae..d4fe9ed 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -120,7 +120,7 @@ private:
enum {
IDI_ITEM_NOT_MOVED,
- IDI_ITEM_MOVED,
+ IDI_ITEM_DROPPED,
IDI_ITEM_DOESNT_MOVE
};
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 55ea15d..6c6a710 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -117,7 +117,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
// Set items that move from inventory to a room to state "dropped"
if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
- item.state = IDI_ITEM_MOVED;
+ item.state = IDI_ITEM_DROPPED;
item.room = room;
return 2;
Commit: 8d1901c39bbfd22ff3540e2db68897f2aae652d9
https://github.com/scummvm/scummvm/commit/8d1901c39bbfd22ff3540e2db68897f2aae652d9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires2 cond opcodes 0x01 and 0x04
Changed paths:
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires2.cpp
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d4fe9ed..9e29d1f 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -76,6 +76,7 @@ struct Room {
byte offset;
byte picture;
byte curPicture;
+ bool isFirstTime;
};
struct Picture {
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 6c6a710..7560504 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -43,7 +43,7 @@ void AdlEngine_v2::setupOpcodeTables() {
OpcodeUnImpl();
Opcode(o2_isItemInRoom);
// 0x04
- OpcodeUnImpl();
+ Opcode(o2_isNounNotInRoom);
Opcode(o1_isMovesGrEq);
Opcode(o1_isVarEq);
OpcodeUnImpl();
@@ -93,6 +93,17 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o1_setRoomPic);
}
+int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
+ bool oldFlag = getCurRoom().isFirstTime;
+
+ getCurRoom().isFirstTime = false;
+
+ if (!oldFlag)
+ return -1;
+
+ return 0;
+}
+
int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
byte room = e.arg(2);
@@ -105,6 +116,21 @@ int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
return 2;
}
+int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
+ Common::Array<Item>::const_iterator item;
+
+ byte room = e.arg(1);
+
+ if (room == IDI_CUR_ROOM)
+ room = _state.room;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->noun == e.getNoun() && (item->room == room))
+ return -1;
+
+ return 1;
+}
+
int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
byte room = e.arg(2);
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 2e8b0f0..61c811b 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -39,7 +39,9 @@ protected:
virtual void setupOpcodeTables();
+ int o2_isFirstTime(ScriptEnv &e);
int o2_isItemInRoom(ScriptEnv &e);
+ int o2_isNounNotInRoom(ScriptEnv &e);
int o2_moveItem(ScriptEnv &e);
};
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index b99f9fc..6f517da 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -142,7 +142,7 @@ void HiRes2Engine::initState() {
f.readByte(); // always 1, possibly disk?
room.picture = f.readByte();
room.curPicture = f.readByte();
- f.readByte(); // always 1, possibly disk?
+ room.isFirstTime = f.readByte();
_state.rooms.push_back(room);
}
Commit: ee8c63183d82aa4deebf87ca6c7a63671684d25f
https://github.com/scummvm/scummvm/commit/ee8c63183d82aa4deebf87ca6c7a63671684d25f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires2 random cond opcode
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 7560504..3a938b3 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -20,12 +20,19 @@
*
*/
+#include "common/random.h"
+
#include "adl/adl_v2.h"
namespace Adl {
+AdlEngine_v2::~AdlEngine_v2() {
+ delete _random;
+}
+
AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
AdlEngine(syst, gd) {
+ _random = new Common::RandomSource("adl");
}
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v2> OpcodeV2;
@@ -39,8 +46,8 @@ void AdlEngine_v2::setupOpcodeTables() {
SetOpcodeTable(_condOpcodes);
// 0x00
OpcodeUnImpl();
- OpcodeUnImpl();
- OpcodeUnImpl();
+ Opcode(o2_isFirstTime);
+ Opcode(o2_isRandomGT);
Opcode(o2_isItemInRoom);
// 0x04
Opcode(o2_isNounNotInRoom);
@@ -104,6 +111,15 @@ int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
return 0;
}
+int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
+ byte rnd = _random->getRandomNumber(255);
+
+ if (e.arg(1) >= rnd)
+ return -1;
+
+ return 1;
+}
+
int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
byte room = e.arg(2);
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 61c811b..5513da3 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -28,11 +28,15 @@
#define IDI_CUR_ROOM 0xfc
#define IDI_VOID_ROOM 0xfd
+namespace Common{
+class RandomSource;
+}
+
namespace Adl {
class AdlEngine_v2 : public AdlEngine {
public:
- virtual ~AdlEngine_v2() { }
+ virtual ~AdlEngine_v2();
protected:
AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
@@ -40,10 +44,14 @@ protected:
virtual void setupOpcodeTables();
int o2_isFirstTime(ScriptEnv &e);
+ int o2_isRandomGT(ScriptEnv &e);
int o2_isItemInRoom(ScriptEnv &e);
int o2_isNounNotInRoom(ScriptEnv &e);
int o2_moveItem(ScriptEnv &e);
+
+private:
+ Common::RandomSource *_random;
};
} // End of namespace Adl
Commit: d09247bacaea68af05703218373479cdb0f558bd
https://github.com/scummvm/scummvm/commit/d09247bacaea68af05703218373479cdb0f558bd
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix move counter
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/hires1.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 778d821..036e8f1 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -294,7 +294,7 @@ void AdlEngine::setupOpcodeTables() {
Opcode(o1_isItemInRoom);
// 0x04
OpcodeUnImpl();
- Opcode(o1_isMovesGrEq);
+ Opcode(o1_isMovesGT);
Opcode(o1_isVarEq);
OpcodeUnImpl();
// 0x08
@@ -859,8 +859,8 @@ int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
return 2;
}
-int AdlEngine::o1_isMovesGrEq(ScriptEnv &e) {
- if (e.arg(1) > _state.moves)
+int AdlEngine::o1_isMovesGT(ScriptEnv &e) {
+ if (e.arg(1) >= _state.moves)
return -1;
return 1;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9e29d1f..b6e8dfa 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -145,7 +145,7 @@ struct State {
uint16 moves;
bool isDark;
- State() : room(1), moves(0), isDark(false) { }
+ State() : room(1), moves(1), isDark(false) { }
};
typedef Common::List<Command> Commands;
@@ -178,7 +178,7 @@ protected:
// Opcodes
int o1_isItemInRoom(ScriptEnv &e);
- int o1_isMovesGrEq(ScriptEnv &e);
+ int o1_isMovesGT(ScriptEnv &e);
int o1_isVarEq(ScriptEnv &e);
int o1_isCurPicEq(ScriptEnv &e);
int o1_isItemPicEq(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 3a938b3..1e5553a 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -51,7 +51,7 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o2_isItemInRoom);
// 0x04
Opcode(o2_isNounNotInRoom);
- Opcode(o1_isMovesGrEq);
+ Opcode(o1_isMovesGT);
Opcode(o1_isVarEq);
OpcodeUnImpl();
// 0x08
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9527d4e..f7f16c0 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -210,7 +210,7 @@ void HiRes1Engine::initState() {
Common::File f;
_state.room = 1;
- _state.moves = 0;
+ _state.moves = 1;
_state.isDark = false;
_state.vars.clear();
Commit: d8035140e2a0d4210cd77e4b24fe3430aacc6ea2
https://github.com/scummvm/scummvm/commit/d8035140e2a0d4210cd77e4b24fe3430aacc6ea2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean up opcodes
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 036e8f1..e6ce0f6 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -295,12 +295,12 @@ void AdlEngine::setupOpcodeTables() {
// 0x04
OpcodeUnImpl();
Opcode(o1_isMovesGT);
- Opcode(o1_isVarEq);
+ Opcode(o1_isVarEQ);
OpcodeUnImpl();
// 0x08
OpcodeUnImpl();
- Opcode(o1_isCurPicEq);
- Opcode(o1_isItemPicEq);
+ Opcode(o1_isCurPicEQ);
+ Opcode(o1_isItemPicEQ);
SetOpcodeTable(_actOpcodes);
// 0x00
@@ -854,33 +854,33 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
- if (getItem(e.arg(1)).room != e.arg(2))
- return -1;
- return 2;
+ if (getItem(e.arg(1)).room == e.arg(2))
+ return 2;
+ return -1;
}
int AdlEngine::o1_isMovesGT(ScriptEnv &e) {
- if (e.arg(1) >= _state.moves)
- return -1;
- return 1;
+ if (_state.moves > e.arg(1))
+ return 1;
+ return -1;
}
-int AdlEngine::o1_isVarEq(ScriptEnv &e) {
- if (getVar(e.arg(1)) != e.arg(2))
- return -1;
- return 2;
+int AdlEngine::o1_isVarEQ(ScriptEnv &e) {
+ if (getVar(e.arg(1)) == e.arg(2))
+ return 2;
+ return -1;
}
-int AdlEngine::o1_isCurPicEq(ScriptEnv &e) {
- if (getCurRoom().curPicture != e.arg(1))
- return -1;
- return 1;
+int AdlEngine::o1_isCurPicEQ(ScriptEnv &e) {
+ if (getCurRoom().curPicture == e.arg(1))
+ return 1;
+ return -1;
}
-int AdlEngine::o1_isItemPicEq(ScriptEnv &e) {
- if (getItem(e.arg(1)).picture != e.arg(2))
- return -1;
- return 2;
+int AdlEngine::o1_isItemPicEQ(ScriptEnv &e) {
+ if (getItem(e.arg(1)).picture == e.arg(2))
+ return 2;
+ return -1;
}
int AdlEngine::o1_varAdd(ScriptEnv &e) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index b6e8dfa..d13e122 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -179,9 +179,9 @@ protected:
// Opcodes
int o1_isItemInRoom(ScriptEnv &e);
int o1_isMovesGT(ScriptEnv &e);
- int o1_isVarEq(ScriptEnv &e);
- int o1_isCurPicEq(ScriptEnv &e);
- int o1_isItemPicEq(ScriptEnv &e);
+ int o1_isVarEQ(ScriptEnv &e);
+ int o1_isCurPicEQ(ScriptEnv &e);
+ int o1_isItemPicEQ(ScriptEnv &e);
int o1_varAdd(ScriptEnv &e);
int o1_varSub(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 1e5553a..4ef2ae2 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -52,12 +52,12 @@ void AdlEngine_v2::setupOpcodeTables() {
// 0x04
Opcode(o2_isNounNotInRoom);
Opcode(o1_isMovesGT);
- Opcode(o1_isVarEq);
+ Opcode(o1_isVarEQ);
OpcodeUnImpl();
// 0x08
OpcodeUnImpl();
- Opcode(o1_isCurPicEq);
- Opcode(o1_isItemPicEq);
+ Opcode(o1_isCurPicEQ);
+ Opcode(o1_isItemPicEQ);
SetOpcodeTable(_actOpcodes);
// 0x00
@@ -114,10 +114,10 @@ int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
byte rnd = _random->getRandomNumber(255);
- if (e.arg(1) >= rnd)
- return -1;
+ if (rnd > e.arg(1))
+ return 1;
- return 1;
+ return -1;
}
int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
@@ -126,10 +126,10 @@ int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
if (room == IDI_CUR_ROOM)
room = _state.room;
- if (getItem(e.arg(1)).room != room)
- return -1;
+ if (getItem(e.arg(1)).room == room)
+ return 2;
- return 2;
+ return -1;
}
int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
Commit: 8a05a9cbca3c86868e148e09c392c2bd53bc4de0
https://github.com/scummvm/scummvm/commit/8a05a9cbca3c86868e148e09c392c2bd53bc4de0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement final hires2 conditional opcode
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 4ef2ae2..8af3fc9 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -53,7 +53,7 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o2_isNounNotInRoom);
Opcode(o1_isMovesGT);
Opcode(o1_isVarEQ);
- OpcodeUnImpl();
+ Opcode(o2_isCarryingSomething);
// 0x08
OpcodeUnImpl();
Opcode(o1_isCurPicEQ);
@@ -147,6 +147,15 @@ int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
return 1;
}
+int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
+ Common::Array<Item>::const_iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->room == IDI_NONE)
+ return 0;
+ return -1;
+}
+
int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
byte room = e.arg(2);
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 5513da3..585bd96 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -47,6 +47,7 @@ protected:
int o2_isRandomGT(ScriptEnv &e);
int o2_isItemInRoom(ScriptEnv &e);
int o2_isNounNotInRoom(ScriptEnv &e);
+ int o2_isCarryingSomething(ScriptEnv &e);
int o2_moveItem(ScriptEnv &e);
Commit: 3f7d5608a9b3cd967c4ceb6fd9bfb5d2e4c19643
https://github.com/scummvm/scummvm/commit/3f7d5608a9b3cd967c4ceb6fd9bfb5d2e4c19643
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement a few hires2 opcodes
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e6ce0f6..b3ac12d 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -343,6 +343,10 @@ void AdlEngine::setupOpcodeTables() {
Opcode(o1_setRoomPic);
}
+bool AdlEngine::matchesCurrentPic(byte pic) const {
+ return pic == getCurRoom().curPicture;
+}
+
void AdlEngine::clearScreen() const {
_display->setMode(DISPLAY_MODE_MIXED);
_display->clear(0x00);
@@ -369,8 +373,7 @@ void AdlEngine::drawItems() const {
Common::Array<byte>::const_iterator pic;
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- // IDI_NONE check was added in hires2
- if (*pic == getCurRoom().curPicture || *pic == IDI_NONE) {
+ if (matchesCurrentPic(*pic)) {
drawItem(*item, item->position);
continue;
}
@@ -451,7 +454,7 @@ void AdlEngine::takeItem(byte noun) {
Common::Array<byte>::const_iterator pic;
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (*pic == getCurRoom().curPicture) {
+ if (matchesCurrentPic(*pic)) {
item->room = IDI_NONE;
item->state = IDI_ITEM_DROPPED;
return;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d13e122..57036b9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -175,6 +175,7 @@ protected:
virtual void checkInput(byte verb, byte noun);
virtual void setupOpcodeTables();
+ virtual bool matchesCurrentPic(byte pic) const;
// Opcodes
int o1_isItemInRoom(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 8af3fc9..61077d5 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -76,14 +76,14 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o1_setLight);
Opcode(o1_setDark);
// 0x0c
- OpcodeUnImpl();
+ Opcode(o2_moveAllItems);
Opcode(o1_quit);
OpcodeUnImpl();
- Opcode(o1_save);
+ Opcode(o1_save); // TODO
// 0x10
- Opcode(o1_restore);
+ Opcode(o1_restore); // TODO
Opcode(o1_restart);
- Opcode(o1_placeItem);
+ Opcode(o2_placeItem);
Opcode(o1_setItemPic);
// 0x14
Opcode(o1_resetPic);
@@ -100,6 +100,10 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o1_setRoomPic);
}
+bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
+ return pic == getCurRoom().curPicture || pic == IDI_NONE;
+}
+
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
bool oldFlag = getCurRoom().isFirstTime;
@@ -164,8 +168,6 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
Item &item = getItem(e.arg(1));
- // Not implemented: set redraw flag if item room == displayed room
-
// Set items that move from inventory to a room to state "dropped"
if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
item.state = IDI_ITEM_DROPPED;
@@ -174,4 +176,43 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
return 2;
}
+int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
+ byte room1 = e.arg(1);
+
+ if (room1 == IDI_CUR_ROOM)
+ room1 = _state.room;
+
+ byte room2 = e.arg(2);
+
+ if (room2 == IDI_CUR_ROOM)
+ room2 = _state.room;
+
+ Common::Array<Item>::iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->room == room1) {
+ item->room = room2;
+ if (room1 == IDI_NONE)
+ item->state = IDI_ITEM_DROPPED;
+ }
+
+ return 2;
+}
+
+int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
+ byte room = e.arg(2);
+
+ if (room == IDI_CUR_ROOM)
+ room = _state.room;
+
+ Item &item = getItem(e.arg(1));
+
+ item.room = room;
+ item.position.x = e.arg(3);
+ item.position.y = e.arg(4);
+ item.state = IDI_ITEM_NOT_MOVED;
+
+ return 4;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 585bd96..d6c18e1 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -25,6 +25,9 @@
#include "adl/adl.h"
+// Note: this version of ADL redraws only when necessary, but
+// this is not currently implemented.
+
#define IDI_CUR_ROOM 0xfc
#define IDI_VOID_ROOM 0xfd
@@ -42,12 +45,15 @@ protected:
AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
virtual void setupOpcodeTables();
+ bool matchesCurrentPic(byte pic) const;
int o2_isFirstTime(ScriptEnv &e);
int o2_isRandomGT(ScriptEnv &e);
int o2_isItemInRoom(ScriptEnv &e);
int o2_isNounNotInRoom(ScriptEnv &e);
int o2_isCarryingSomething(ScriptEnv &e);
+ int o2_moveAllItems(ScriptEnv &e);
+ int o2_placeItem(ScriptEnv &e);
int o2_moveItem(ScriptEnv &e);
Commit: 4ce697e2c38dd96eee13a793402d2946f89d856b
https://github.com/scummvm/scummvm/commit/4ce697e2c38dd96eee13a793402d2946f89d856b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Rename IDI_NONE to IDI_ANY
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index b3ac12d..9bd22f8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -448,14 +448,14 @@ void AdlEngine::takeItem(byte noun) {
}
if (item->state == IDI_ITEM_DROPPED) {
- item->room = IDI_NONE;
+ item->room = IDI_ANY;
return;
}
Common::Array<byte>::const_iterator pic;
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
if (matchesCurrentPic(*pic)) {
- item->room = IDI_NONE;
+ item->room = IDI_ANY;
item->state = IDI_ITEM_DROPPED;
return;
}
@@ -469,7 +469,7 @@ void AdlEngine::dropItem(byte noun) {
Common::Array<Item>::iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item) {
- if (item->noun != noun || item->room != IDI_NONE)
+ if (item->noun != noun || item->room != IDI_ANY)
continue;
item->room = _state.room;
@@ -905,7 +905,7 @@ int AdlEngine::o1_listInv(ScriptEnv &e) {
Common::Array<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
- if (item->room == IDI_NONE)
+ if (item->room == IDI_ANY)
printMessage(item->description);
return 0;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 57036b9..ea6a51c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -54,7 +54,7 @@ struct ScriptEnv;
#define IDO_ACT_SAVE 0x0f
#define IDO_ACT_LOAD 0x10
-#define IDI_NONE 0xfe
+#define IDI_ANY 0xfe
#define IDI_WORD_SIZE 8
@@ -104,9 +104,9 @@ public:
void skip(uint i) { _ip += i; }
bool isMatch() const {
- return (_cmd.room == IDI_NONE || _cmd.room == _room) &&
- (_cmd.verb == IDI_NONE || _cmd.verb == _verb) &&
- (_cmd.noun == IDI_NONE || _cmd.noun == _noun);
+ return (_cmd.room == IDI_ANY || _cmd.room == _room) &&
+ (_cmd.verb == IDI_ANY || _cmd.verb == _verb) &&
+ (_cmd.noun == IDI_ANY || _cmd.noun == _noun);
}
byte getCondCount() const { return _cmd.numCond; }
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 61077d5..3383a63 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -101,7 +101,7 @@ void AdlEngine_v2::setupOpcodeTables() {
}
bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
- return pic == getCurRoom().curPicture || pic == IDI_NONE;
+ return pic == getCurRoom().curPicture || pic == IDI_ANY;
}
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
@@ -155,7 +155,7 @@ int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
Common::Array<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
- if (item->room == IDI_NONE)
+ if (item->room == IDI_ANY)
return 0;
return -1;
}
@@ -169,7 +169,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
Item &item = getItem(e.arg(1));
// Set items that move from inventory to a room to state "dropped"
- if (item.room == IDI_NONE && room != IDI_VOID_ROOM)
+ if (item.room == IDI_ANY && room != IDI_VOID_ROOM)
item.state = IDI_ITEM_DROPPED;
item.room = room;
@@ -192,7 +192,7 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
for (item = _state.items.begin(); item != _state.items.end(); ++item)
if (item->room == room1) {
item->room = room2;
- if (room1 == IDI_NONE)
+ if (room1 == IDI_ANY)
item->state = IDI_ITEM_DROPPED;
}
Commit: 3102ff4a1951ca0a3ca6446f8b5bc67849fe3d73
https://github.com/scummvm/scummvm/commit/3102ff4a1951ca0a3ca6446f8b5bc67849fe3d73
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean up handling of room value 0xfc
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 9bd22f8..1f4ebcd 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -347,6 +347,10 @@ bool AdlEngine::matchesCurrentPic(byte pic) const {
return pic == getCurRoom().curPicture;
}
+byte AdlEngine::roomArg(byte room) const {
+ return room;
+}
+
void AdlEngine::clearScreen() const {
_display->setMode(DISPLAY_MODE_MIXED);
_display->clear(0x00);
@@ -857,7 +861,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
- if (getItem(e.arg(1)).room == e.arg(2))
+ if (getItem(e.arg(1)).room == roomArg(e.arg(2)))
return 2;
return -1;
}
@@ -980,9 +984,11 @@ int AdlEngine::o1_quit(ScriptEnv &e) {
}
int AdlEngine::o1_placeItem(ScriptEnv &e) {
- getItem(e.arg(1)).room = e.arg(2);
- getItem(e.arg(1)).position.x = e.arg(3);
- getItem(e.arg(1)).position.y = e.arg(4);
+ Item &item = getItem(e.arg(1));
+
+ item.room = roomArg(e.arg(2));
+ item.position.x = e.arg(3);
+ item.position.y = e.arg(4);
return 4;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ea6a51c..595386c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -176,6 +176,7 @@ protected:
virtual void setupOpcodeTables();
virtual bool matchesCurrentPic(byte pic) const;
+ virtual byte roomArg(byte room) const;
// Opcodes
int o1_isItemInRoom(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 3383a63..1a07d0e 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -48,7 +48,7 @@ void AdlEngine_v2::setupOpcodeTables() {
OpcodeUnImpl();
Opcode(o2_isFirstTime);
Opcode(o2_isRandomGT);
- Opcode(o2_isItemInRoom);
+ Opcode(o1_isItemInRoom);
// 0x04
Opcode(o2_isNounNotInRoom);
Opcode(o1_isMovesGT);
@@ -104,6 +104,12 @@ bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
return pic == getCurRoom().curPicture || pic == IDI_ANY;
}
+byte AdlEngine_v2::roomArg(byte room) const {
+ if (room == IDI_CUR_ROOM)
+ return _state.room;
+ return room;
+}
+
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
bool oldFlag = getCurRoom().isFirstTime;
@@ -124,28 +130,11 @@ int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
return -1;
}
-int AdlEngine_v2::o2_isItemInRoom(ScriptEnv &e) {
- byte room = e.arg(2);
-
- if (room == IDI_CUR_ROOM)
- room = _state.room;
-
- if (getItem(e.arg(1)).room == room)
- return 2;
-
- return -1;
-}
-
int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
Common::Array<Item>::const_iterator item;
- byte room = e.arg(1);
-
- if (room == IDI_CUR_ROOM)
- room = _state.room;
-
for (item = _state.items.begin(); item != _state.items.end(); ++item)
- if (item->noun == e.getNoun() && (item->room == room))
+ if (item->noun == e.getNoun() && (item->room == roomArg(e.arg(1))))
return -1;
return 1;
@@ -161,10 +150,7 @@ int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
}
int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
- byte room = e.arg(2);
-
- if (room == IDI_CUR_ROOM)
- room = _state.room;
+ byte room = roomArg(e.arg(2));
Item &item = getItem(e.arg(1));
@@ -177,15 +163,8 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
}
int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
- byte room1 = e.arg(1);
-
- if (room1 == IDI_CUR_ROOM)
- room1 = _state.room;
-
- byte room2 = e.arg(2);
-
- if (room2 == IDI_CUR_ROOM)
- room2 = _state.room;
+ byte room1 = roomArg(e.arg(1));
+ byte room2 = roomArg(e.arg(2));
Common::Array<Item>::iterator item;
@@ -200,14 +179,9 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
}
int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
- byte room = e.arg(2);
-
- if (room == IDI_CUR_ROOM)
- room = _state.room;
-
Item &item = getItem(e.arg(1));
- item.room = room;
+ item.room = roomArg(e.arg(2));
item.position.x = e.arg(3);
item.position.y = e.arg(4);
item.state = IDI_ITEM_NOT_MOVED;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index d6c18e1..e21c43c 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -46,10 +46,10 @@ protected:
virtual void setupOpcodeTables();
bool matchesCurrentPic(byte pic) const;
+ byte roomArg(byte room) const;
int o2_isFirstTime(ScriptEnv &e);
int o2_isRandomGT(ScriptEnv &e);
- int o2_isItemInRoom(ScriptEnv &e);
int o2_isNounNotInRoom(ScriptEnv &e);
int o2_isCarryingSomething(ScriptEnv &e);
int o2_moveAllItems(ScriptEnv &e);
Commit: e7c93489e4f6055c988d048c9c479de3eff94ece
https://github.com/scummvm/scummvm/commit/e7c93489e4f6055c988d048c9c479de3eff94ece
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean up drawItems()
Changed paths:
engines/adl/adl.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1f4ebcd..715d7a8 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -362,24 +362,25 @@ void AdlEngine::drawItems() const {
uint dropped = 0;
for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ // Skip items not in this room
if (item->room != _state.room)
continue;
if (item->state == IDI_ITEM_DROPPED) {
+ // Draw dropped item if in normal view
if (getCurRoom().picture == getCurRoom().curPicture) {
- const Common::Point &p = _itemOffsets[dropped];
- drawItem(*item, p);
+ drawItem(*item, _itemOffsets[dropped]);
++dropped;
}
- continue;
- }
-
- Common::Array<byte>::const_iterator pic;
+ } else {
+ // Draw fixed item if current view is in the pic list
+ Common::Array<byte>::const_iterator pic;
- for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (matchesCurrentPic(*pic)) {
- drawItem(*item, item->position);
- continue;
+ for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+ if (matchesCurrentPic(*pic)) {
+ drawItem(*item, item->position);
+ break;
+ }
}
}
}
Commit: a7a371c63d1570714c7b5cb766f6acc3fd26f5fc
https://github.com/scummvm/scummvm/commit/a7a371c63d1570714c7b5cb766f6acc3fd26f5fc
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement time opcode
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 715d7a8..e2025b9 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -552,6 +552,7 @@ Common::Error AdlEngine::run() {
}
doAllCommands(_globalCommands, verb, noun);
+ advanceClock();
_state.moves++;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 595386c..5aba30e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -136,6 +136,12 @@ struct Item {
Common::Array<byte> roomPictures;
};
+struct Time {
+ byte hours, minutes;
+
+ Time() : hours(12), minutes(0) { }
+};
+
struct State {
Common::Array<Room> rooms;
Common::Array<Item> items;
@@ -144,6 +150,7 @@ struct State {
byte room;
uint16 moves;
bool isDark;
+ Time time;
State() : room(1), moves(1), isDark(false) { }
};
@@ -177,6 +184,7 @@ protected:
virtual void setupOpcodeTables();
virtual bool matchesCurrentPic(byte pic) const;
virtual byte roomArg(byte room) const;
+ virtual void advanceClock() { }
// Opcodes
int o1_isItemInRoom(ScriptEnv &e);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 1a07d0e..e5e02d2 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -23,6 +23,7 @@
#include "common/random.h"
#include "adl/adl_v2.h"
+#include "adl/display.h"
namespace Adl {
@@ -31,7 +32,8 @@ AdlEngine_v2::~AdlEngine_v2() {
}
AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine(syst, gd) {
+ AdlEngine(syst, gd),
+ _linesPrinted(0) {
_random = new Common::RandomSource("adl");
}
@@ -98,6 +100,7 @@ void AdlEngine_v2::setupOpcodeTables() {
// 0x1c
Opcode(o1_dropItem);
Opcode(o1_setRoomPic);
+ Opcode(o2_tellTime);
}
bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
@@ -110,6 +113,81 @@ byte AdlEngine_v2::roomArg(byte room) const {
return room;
}
+void AdlEngine_v2::advanceClock() {
+ Time &time = _state.time;
+
+ time.minutes += 5;
+
+ if (time.minutes == 60) {
+ time.minutes = 0;
+
+ ++time.hours;
+
+ if (time.hours == 13)
+ time.hours = 1;
+ }
+}
+
+void AdlEngine_v2::checkTextOverflow(char c) {
+ if (c != APPLECHAR('\r'))
+ return;
+
+ ++_linesPrinted;
+
+ if (_linesPrinted < 4)
+ return;
+
+ _linesPrinted = 0;
+ _display->updateTextScreen();
+ bell();
+
+ while (true) {
+ char key = inputKey(false);
+
+ if (shouldQuit())
+ return;
+
+ if (key == APPLECHAR('\r'))
+ break;
+
+ bell(3);
+ }
+}
+
+void AdlEngine_v2::printString(const Common::String &str) {
+ Common::String s(str);
+ byte endPos = TEXT_WIDTH - 1;
+ byte pos = 0;
+
+ while (true) {
+ while (pos != endPos && pos != s.size()) {
+ s.setChar(APPLECHAR(s[pos]), pos);
+ ++pos;
+ }
+
+ if (pos == s.size())
+ break;
+
+ while (s[pos] != APPLECHAR(' ') && s[pos] != APPLECHAR('\r'))
+ --pos;
+
+ s.setChar(APPLECHAR('\r'), pos);
+ endPos = pos + TEXT_WIDTH;
+ ++pos;
+ }
+
+ pos = 0;
+ while (pos != s.size()) {
+ checkTextOverflow(s[pos]);
+ _display->printChar(s[pos]);
+ ++pos;
+ }
+
+ checkTextOverflow(APPLECHAR('\r'));
+ _display->printChar(APPLECHAR('\r'));
+ _display->updateTextScreen();
+}
+
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
bool oldFlag = getCurRoom().isFirstTime;
@@ -189,4 +267,17 @@ int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
return 4;
}
+int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
+ Common::String time = _strings_v2.time;
+
+ time.setChar(APPLECHAR('0') + _state.time.hours / 10, 12);
+ time.setChar(APPLECHAR('0') + _state.time.hours % 10, 13);
+ time.setChar(APPLECHAR('0') + _state.time.minutes / 10, 15);
+ time.setChar(APPLECHAR('0') + _state.time.minutes % 10, 16);
+
+ printString(time);
+
+ return 0;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index e21c43c..d484719 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -44,18 +44,30 @@ public:
protected:
AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd);
+ // AdlEngine
virtual void setupOpcodeTables();
bool matchesCurrentPic(byte pic) const;
byte roomArg(byte room) const;
+ void advanceClock();
+
+ void checkTextOverflow(char c);
+ void printString(const Common::String &str);
int o2_isFirstTime(ScriptEnv &e);
int o2_isRandomGT(ScriptEnv &e);
int o2_isNounNotInRoom(ScriptEnv &e);
int o2_isCarryingSomething(ScriptEnv &e);
+
+ int o2_moveItem(ScriptEnv &e);
int o2_moveAllItems(ScriptEnv &e);
int o2_placeItem(ScriptEnv &e);
+ int o2_tellTime(ScriptEnv &e);
- int o2_moveItem(ScriptEnv &e);
+ struct {
+ Common::String time;
+ } _strings_v2;
+
+ uint _linesPrinted;
private:
Common::RandomSource *_random;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 6f517da..49e70a1 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -84,6 +84,7 @@ void HiRes2Engine::init() {
_strings.nounError = readStringAt(f, IDI_HR2_OFS_STR_NOUN_ERROR);
_strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
_strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
+ _strings_v2.time = readStringAt(f, IDI_HR2_OFS_STR_TIME, 0xff);
_messageIds.cantGoThere = IDI_HR2_MSG_CANT_GO_THERE;
_messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
@@ -248,66 +249,6 @@ void HiRes2Engine::checkInput(byte verb, byte noun) {
AdlEngine::checkInput(verb, noun);
}
-void HiRes2Engine::checkTextOverflow(char c) {
- if (c != APPLECHAR('\r'))
- return;
-
- ++_linesPrinted;
-
- if (_linesPrinted < 4)
- return;
-
- _linesPrinted = 0;
- _display->updateTextScreen();
- bell();
-
- while (true) {
- char key = inputKey(false);
-
- if (shouldQuit())
- return;
-
- if (key == APPLECHAR('\r'))
- break;
-
- bell(3);
- }
-}
-
-void HiRes2Engine::printString(const Common::String &str) {
- Common::String s(str);
- byte endPos = TEXT_WIDTH - 1;
- byte pos = 0;
-
- while (true) {
- while (pos != endPos && pos != s.size()) {
- s.setChar(APPLECHAR(s[pos]), pos);
- ++pos;
- }
-
- if (pos == s.size())
- break;
-
- while (s[pos] != APPLECHAR(' ') && s[pos] != APPLECHAR('\r'))
- --pos;
-
- s.setChar(APPLECHAR('\r'), pos);
- endPos = pos + TEXT_WIDTH;
- ++pos;
- }
-
- pos = 0;
- while (pos != s.size()) {
- checkTextOverflow(s[pos]);
- _display->printChar(s[pos]);
- ++pos;
- }
-
- checkTextOverflow(APPLECHAR('\r'));
- _display->printChar(APPLECHAR('\r'));
- _display->updateTextScreen();
-}
-
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes2Engine(syst, gd);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 8ed51b8..121a1f6 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -71,6 +71,7 @@ namespace Adl {
#define IDI_HR2_OFS_STR_NOUN_ERROR TSO(0x1a, 0x1, 0x8e)
#define IDI_HR2_OFS_STR_PLAY_AGAIN TSO(0x1a, 0x8, 0x25)
#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
+#define IDI_HR2_OFS_STR_TIME TSO(0x19, 0x7, 0xd7)
struct Picture2 {
byte nr;
@@ -87,7 +88,7 @@ struct RoomData {
class HiRes2Engine : public AdlEngine_v2 {
public:
- HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd), _linesPrinted(0) { }
+ HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
private:
// AdlEngine
@@ -102,12 +103,9 @@ private:
void checkInput(byte verb, byte noun);
void loadRoom(byte roomNr);
- void checkTextOverflow(char c);
- void printString(const Common::String &str);
RoomData _roomData;
Common::Array<Picture2> _itemPics;
- uint _linesPrinted;
};
} // End of namespace Adl
Commit: 905e2cd63f76271029133ac093647025f036176d
https://github.com/scummvm/scummvm/commit/905e2cd63f76271029133ac093647025f036176d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add hires2 opcode 0x20
Changed paths:
engines/adl/adl.cpp
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e2025b9..a09ec69 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -1040,7 +1040,7 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
for (uint i = 0; i < env.getCondCount(); ++i) {
byte op = env.op();
- if (!_condOpcodes[op] || !_condOpcodes[op]->isValid())
+ if (op >= _condOpcodes.size() || !_condOpcodes[op] || !_condOpcodes[op]->isValid())
error("Unimplemented condition opcode %02x", op);
int numArgs = (*_condOpcodes[op])(env);
@@ -1058,7 +1058,7 @@ void AdlEngine::doActions(ScriptEnv &env) {
for (uint i = 0; i < env.getActCount(); ++i) {
byte op = env.op();
- if (!_actOpcodes[op] || !_actOpcodes[op]->isValid())
+ if (op >= _actOpcodes.size() || !_actOpcodes[op] || !_actOpcodes[op]->isValid())
error("Unimplemented action opcode %02x", op);
int numArgs = (*_actOpcodes[op])(env);
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index e5e02d2..3db013d 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -101,6 +101,7 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o1_dropItem);
Opcode(o1_setRoomPic);
Opcode(o2_tellTime);
+ Opcode(o2_setRoomFromVar);
}
bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
@@ -280,4 +281,10 @@ int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
return 0;
}
+int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
+ getCurRoom().curPicture = getCurRoom().picture;
+ _state.room = getVar(e.arg(1));
+ return 1;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index d484719..01aa57c 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -62,6 +62,7 @@ protected:
int o2_moveAllItems(ScriptEnv &e);
int o2_placeItem(ScriptEnv &e);
int o2_tellTime(ScriptEnv &e);
+ int o2_setRoomFromVar(ScriptEnv &e);
struct {
Common::String time;
Commit: 3afcf67643873438b98529b71b244ed715e745f7
https://github.com/scummvm/scummvm/commit/3afcf67643873438b98529b71b244ed715e745f7
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Stub init disk opcode
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 3db013d..72d60ac 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -102,6 +102,8 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o1_setRoomPic);
Opcode(o2_tellTime);
Opcode(o2_setRoomFromVar);
+ // 0x20
+ Opcode(o2_initDisk);
}
bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
@@ -287,4 +289,9 @@ int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
return 1;
}
+int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
+ printString("NOT REQUIRED");
+ return 0;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 01aa57c..6da8caa 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -63,6 +63,7 @@ protected:
int o2_placeItem(ScriptEnv &e);
int o2_tellTime(ScriptEnv &e);
int o2_setRoomFromVar(ScriptEnv &e);
+ int o2_initDisk(ScriptEnv &e);
struct {
Common::String time;
Commit: a82ac8973d10dcdac885f686aa56ff4ecbc54643
https://github.com/scummvm/scummvm/commit/a82ac8973d10dcdac885f686aa56ff4ecbc54643
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires2 save/restore opcodes
Note: underlying save/restore/restart code still incomplete
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index a09ec69..d95cfd5 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -53,9 +53,9 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
Engine(syst),
_display(nullptr),
_graphics(nullptr),
- _gameDescription(gd),
_isRestarting(false),
_isRestoring(false),
+ _gameDescription(gd),
_saveVerb(0),
_saveNoun(0),
_restoreVerb(0),
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 5aba30e..2e413ac 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -167,6 +167,10 @@ public:
protected:
AdlEngine(OSystem *syst, const AdlGameDescription *gd);
+ // Engine
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const Common::String &desc);
+
Common::String readString(Common::ReadStream &stream, byte until = 0) const;
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
void openFile(Common::File &file, const Common::String &name) const;
@@ -279,6 +283,8 @@ protected:
// Game state
State _state;
+ bool _isRestarting, _isRestoring;
+
private:
virtual void runIntro() const { }
virtual void init() = 0;
@@ -290,9 +296,7 @@ private:
// Engine
Common::Error run();
bool hasFeature(EngineFeature f) const;
- Common::Error loadGameState(int slot);
bool canLoadGameStateCurrently();
- Common::Error saveGameState(int slot, const Common::String &desc);
bool canSaveGameStateCurrently();
// Text output
@@ -305,7 +309,6 @@ private:
void getInput(uint &verb, uint &noun);
const AdlGameDescription *_gameDescription;
- bool _isRestarting, _isRestoring;
byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
bool _canSaveNow, _canRestoreNow;
};
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 72d60ac..029c37a 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -21,6 +21,7 @@
*/
#include "common/random.h"
+#include "common/error.h"
#include "adl/adl_v2.h"
#include "adl/display.h"
@@ -81,9 +82,9 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o2_moveAllItems);
Opcode(o1_quit);
OpcodeUnImpl();
- Opcode(o1_save); // TODO
+ Opcode(o2_save);
// 0x10
- Opcode(o1_restore); // TODO
+ Opcode(o2_restore);
Opcode(o1_restart);
Opcode(o2_placeItem);
Opcode(o1_setItemPic);
@@ -259,6 +260,33 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
return 2;
}
+int AdlEngine_v2::o2_save(ScriptEnv &e) {
+ int slot = askForSlot(_strings_v2.saveInsert);
+
+ if (slot < 0)
+ return -1;
+
+ saveGameState(slot, "");
+
+ _display->printString(_strings_v2.saveReplace);
+ inputString();
+ return 0;
+}
+
+int AdlEngine_v2::o2_restore(ScriptEnv &e) {
+ int slot = askForSlot(_strings_v2.restoreInsert);
+
+ if (slot < 0)
+ return -1;
+
+ loadGameState(slot);
+ _isRestoring = false;
+
+ _display->printString(_strings_v2.restoreReplace);
+ inputString();
+ return 0;
+}
+
int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
Item &item = getItem(e.arg(1));
@@ -294,4 +322,18 @@ int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
return 0;
}
+int AdlEngine_v2::askForSlot(const Common::String &question) {
+ while (1) {
+ _display->printString(question);
+
+ Common::String input = inputString();
+
+ if (shouldQuit())
+ return -1;
+
+ if (input.size() > 0 && input[0] >= APPLECHAR('A') && input[0] <= APPLECHAR('O'))
+ return input[0] - APPLECHAR('A');
+ }
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 6da8caa..cea4a93 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -60,6 +60,8 @@ protected:
int o2_moveItem(ScriptEnv &e);
int o2_moveAllItems(ScriptEnv &e);
+ int o2_save(ScriptEnv &e);
+ int o2_restore(ScriptEnv &e);
int o2_placeItem(ScriptEnv &e);
int o2_tellTime(ScriptEnv &e);
int o2_setRoomFromVar(ScriptEnv &e);
@@ -67,11 +69,15 @@ protected:
struct {
Common::String time;
+ Common::String saveInsert, saveReplace;
+ Common::String restoreInsert, restoreReplace;
} _strings_v2;
uint _linesPrinted;
private:
+ int askForSlot(const Common::String &question);
+
Common::RandomSource *_random;
};
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 49e70a1..71aeeb5 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -85,6 +85,10 @@ void HiRes2Engine::init() {
_strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
_strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
_strings_v2.time = readStringAt(f, IDI_HR2_OFS_STR_TIME, 0xff);
+ _strings_v2.saveInsert = readStringAt(f, IDI_HR2_OFS_STR_SAVE_INSERT);
+ _strings_v2.saveReplace = readStringAt(f, IDI_HR2_OFS_STR_SAVE_REPLACE);
+ _strings_v2.restoreInsert = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_INSERT);
+ _strings_v2.restoreReplace = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_REPLACE);
_messageIds.cantGoThere = IDI_HR2_MSG_CANT_GO_THERE;
_messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 121a1f6..1578109 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -66,12 +66,16 @@ namespace Adl {
#define IDI_HR2_MSG_ITEM_NOT_HERE 4
#define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
-#define IDI_HR2_OFS_STR_ENTER_COMMAND TSO(0x1a, 0x1, 0xbc)
-#define IDI_HR2_OFS_STR_VERB_ERROR TSO(0x1a, 0x1, 0x4f)
-#define IDI_HR2_OFS_STR_NOUN_ERROR TSO(0x1a, 0x1, 0x8e)
-#define IDI_HR2_OFS_STR_PLAY_AGAIN TSO(0x1a, 0x8, 0x25)
-#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
-#define IDI_HR2_OFS_STR_TIME TSO(0x19, 0x7, 0xd7)
+#define IDI_HR2_OFS_STR_ENTER_COMMAND TSO(0x1a, 0x1, 0xbc)
+#define IDI_HR2_OFS_STR_VERB_ERROR TSO(0x1a, 0x1, 0x4f)
+#define IDI_HR2_OFS_STR_NOUN_ERROR TSO(0x1a, 0x1, 0x8e)
+#define IDI_HR2_OFS_STR_PLAY_AGAIN TSO(0x1a, 0x8, 0x25)
+#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
+#define IDI_HR2_OFS_STR_TIME TSO(0x19, 0x7, 0xd7)
+#define IDI_HR2_OFS_STR_SAVE_INSERT TSO(0x1a, 0x6, 0x5f)
+#define IDI_HR2_OFS_STR_SAVE_REPLACE TSO(0x1a, 0x6, 0xe5)
+#define IDI_HR2_OFS_STR_RESTORE_INSERT TSO(0x1a, 0x7, 0x32)
+#define IDI_HR2_OFS_STR_RESTORE_REPLACE TSO(0x1a, 0x7, 0xc2)
struct Picture2 {
byte nr;
Commit: ffbc4da0b0b2f26f88ad94f75d84fe6facbcfd52
https://github.com/scummvm/scummvm/commit/ffbc4da0b0b2f26f88ad94f75d84fe6facbcfd52
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use display class to print init disk message
Changed paths:
engines/adl/adl_v2.cpp
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 029c37a..8a826e5 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -318,7 +318,7 @@ int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
}
int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
- printString("NOT REQUIRED");
+ _display->printAsciiString("NOT REQUIRED\r");
return 0;
}
Commit: 4af9f32d3f12badb0573db203c2949ec5173aae6
https://github.com/scummvm/scummvm/commit/4af9f32d3f12badb0573db203c2949ec5173aae6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add disk format abstraction
Changed paths:
A engines/adl/disk.cpp
A engines/adl/disk.h
engines/adl/module.mk
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
new file mode 100644
index 0000000..b91efec
--- /dev/null
+++ b/engines/adl/disk.cpp
@@ -0,0 +1,90 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/stream.h"
+
+#include "adl/disk.h"
+
+namespace Adl {
+
+DiskImage::DiskImage() :
+ _tracks(0),
+ _sectorsPerTrack(0),
+ _bytesPerSector(0) {
+ _f = new Common::File();
+}
+
+DiskImage::~DiskImage() {
+ delete _f;
+}
+
+DiskImageDataBlock::DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size) :
+ _track(track),
+ _sector(sector),
+ _offset(offset),
+ _size(size),
+ _disk(disk) { }
+
+bool DiskImageDataBlock::isValid() const {
+ return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
+}
+
+Common::SeekableReadStream *DiskImageDataBlock::createReadStream() const {
+ return _disk->createReadStream(_track, _sector, _offset, _size);
+}
+
+// .DSK disk image - 35 tracks, 16 sectors per track, 256 bytes per sector, raw sector layout
+const DataBlockPtr DiskImage_DSK::getDataBlock(uint track, uint sector, uint offset, uint size) const {
+ return Common::SharedPtr<DiskImageDataBlock>(new DiskImageDataBlock(this, track, sector, offset, size));
+}
+
+Common::SeekableReadStream *DiskImage_DSK::createReadStream(uint track, uint sector, uint offset, uint size) const {
+ _f->seek((track * _sectorsPerTrack + sector) * _bytesPerSector + offset);
+ Common::SeekableReadStream *stream = _f->readStream(size * _bytesPerSector + _bytesPerSector - offset);
+
+ if (_f->eos() || _f->err())
+ error("Error reading disk image");
+
+ return stream;
+}
+
+bool DiskImage_DSK::open(const Common::String &filename) {
+ assert(!_f->isOpen());
+
+ if (!_f->open(filename))
+ return false;
+
+ uint filesize = _f->size();
+ switch (filesize) {
+ case 143360:
+ _tracks = 35;
+ _sectorsPerTrack = 16;
+ _bytesPerSector = 256;
+ break;
+ default:
+ warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
+ }
+
+ return true;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
new file mode 100644
index 0000000..0bf57c7
--- /dev/null
+++ b/engines/adl/disk.h
@@ -0,0 +1,81 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/ptr.h"
+#include "common/file.h"
+
+#ifndef ADL_DISK_H
+#define ADL_DISK_H
+
+namespace Common {
+class SeekableReadStream;
+class String;
+}
+
+namespace Adl {
+
+class DataBlock {
+public:
+ virtual ~DataBlock() { }
+
+ virtual bool isValid() const = 0;
+ virtual Common::SeekableReadStream *createReadStream() const = 0;
+};
+
+typedef Common::SharedPtr<DataBlock> DataBlockPtr;
+
+class DiskImage {
+public:
+ DiskImage();
+ virtual ~DiskImage();
+
+ virtual bool open(const Common::String &filename) = 0;
+ virtual const DataBlockPtr getDataBlock(uint track, uint sector, uint offset, uint size) const = 0;
+ virtual Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset, uint size) const = 0;
+
+protected:
+ Common::File *_f;
+ uint _tracks, _sectorsPerTrack, _bytesPerSector;
+};
+
+class DiskImageDataBlock : public DataBlock {
+public:
+ DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size);
+
+ bool isValid() const;
+ Common::SeekableReadStream *createReadStream() const;
+
+private:
+ uint _track, _sector, _offset, _size;
+ const DiskImage *_disk;
+};
+
+class DiskImage_DSK : public DiskImage {
+public:
+ bool open(const Common::String &filename);
+ const DataBlockPtr getDataBlock(uint track, uint sector, uint offset, uint size) const;
+ Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 7599957..661d1b1 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
adl.o \
adl_v2.o \
detection.o \
+ disk.o \
display.o \
graphics.o \
graphics_v1.o \
Commit: bfbacf9397f6baa03e5b79149fc357d6c8d74049
https://github.com/scummvm/scummvm/commit/bfbacf9397f6baa03e5b79149fc357d6c8d74049
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use DiskImage class in hires2
Changed paths:
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 2e413ac..dba6cc7 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -35,6 +35,8 @@
#include "audio/mixer.h"
#include "audio/softsynth/pcspk.h"
+#include "adl/disk.h"
+
namespace Common {
class ReadStream;
class SeekableReadStream;
@@ -69,11 +71,16 @@ enum Direction {
};
struct Room {
+ Room() :
+ description(0),
+ picture(0),
+ curPicture(0) {
+ memset(connections, 0, sizeof(connections));
+ }
+
byte description;
byte connections[IDI_DIR_TOTAL];
- byte track;
- byte sector;
- byte offset;
+ DataBlockPtr data;
byte picture;
byte curPicture;
bool isFirstTime;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index f7f16c0..8554b18 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -223,7 +223,7 @@ void HiRes1Engine::initState() {
_roomDesc.clear();
f.seek(IDI_HR1_OFS_ROOMS);
for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
- Room room = { };
+ Room room;
f.readByte();
_roomDesc.push_back(f.readByte());
for (uint j = 0; j < 6; ++j)
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 71aeeb5..5e3da00 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -29,27 +29,31 @@
#include "adl/hires2.h"
#include "adl/display.h"
#include "adl/graphics.h"
+#include "adl/disk.h"
namespace Adl {
-static void readPictureMeta(Common::ReadStream &f, Picture2 &pic) {
+DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
+ byte track = f.readByte();
+ byte sector = f.readByte();
+ byte offset = f.readByte();
+ byte size = f.readByte();
+ return _disk.getDataBlock(track, sector, offset, size);
+}
+
+void HiRes2Engine::readPictureMeta(Common::ReadStream &f, Picture2 &pic) const {
pic.nr = f.readByte();
- pic.track = f.readByte();
- pic.sector = f.readByte();
- pic.offset = f.readByte();
- f.readByte();
+ pic.data = readDataBlockPtr(f);
}
void HiRes2Engine::runIntro() const {
- Common::File f;
- openFile(f, IDS_HR2_DISK_IMAGE);
- f.seek(IDI_HR2_OFS_INTRO_TEXT);
+ StreamPtr stream(_disk.createReadStream(0x00, 0xd, 0x17, 1));
_display->setMode(DISPLAY_MODE_TEXT);
- Common::String str = readStringAt(f, IDI_HR2_OFS_INTRO_TEXT);
+ Common::String str = readString(*stream);
- if (f.eos() || f.err())
+ if (stream->eos() || stream->err())
error("Error reading disk image");
_display->printString(str);
@@ -59,36 +63,38 @@ void HiRes2Engine::runIntro() const {
void HiRes2Engine::init() {
_graphics = new Graphics_v2(*_display);
- Common::File f;
- openFile(f, IDS_HR2_DISK_IMAGE);
-
- for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
- f.seek(IDI_HR2_OFS_MESSAGES + i * 4);
- byte track = f.readByte();
- byte sector = f.readByte();
- byte offset = f.readByte();
- // One more byte follows, disk? or size maybe?
-
- uint diskOffset = TSO(track, sector, offset);
+ if (!_disk.open(IDS_HR2_DISK_IMAGE))
+ error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
- Common::String str;
+ StreamPtr stream(_disk.createReadStream(0x1f, 0x2, 0x04, 4));
- if (diskOffset != 0)
- str = readStringAt(f, TSO(track, sector, offset), 0xff);
+ for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
+ DataBlockPtr str(readDataBlockPtr(*stream));
- _messages.push_back(str);
+ if (str->isValid()) {
+ StreamPtr strStream(str->createReadStream());
+ _messages.push_back(readString(*strStream, 0xff));
+ }
}
- _strings.enterCommand = readStringAt(f, IDI_HR2_OFS_STR_ENTER_COMMAND);
- _strings.verbError = readStringAt(f, IDI_HR2_OFS_STR_VERB_ERROR);
- _strings.nounError = readStringAt(f, IDI_HR2_OFS_STR_NOUN_ERROR);
- _strings.playAgain = readStringAt(f, IDI_HR2_OFS_STR_PLAY_AGAIN);
- _strings.pressReturn = readStringAt(f, IDI_HR2_OFS_STR_PRESS_RETURN);
- _strings_v2.time = readStringAt(f, IDI_HR2_OFS_STR_TIME, 0xff);
- _strings_v2.saveInsert = readStringAt(f, IDI_HR2_OFS_STR_SAVE_INSERT);
- _strings_v2.saveReplace = readStringAt(f, IDI_HR2_OFS_STR_SAVE_REPLACE);
- _strings_v2.restoreInsert = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_INSERT);
- _strings_v2.restoreReplace = readStringAt(f, IDI_HR2_OFS_STR_RESTORE_REPLACE);
+ // Read parser messages
+ stream.reset(_disk.createReadStream(0x1a, 0x1));
+ _strings.verbError = readStringAt(*stream, 0x4f);
+ _strings.nounError = readStringAt(*stream, 0x8e);
+ _strings.enterCommand = readStringAt(*stream, 0xbc);
+
+ // Read time string
+ stream.reset(_disk.createReadStream(0x19, 0x7, 0xd7));
+ _strings_v2.time = readString(*stream, 0xff);
+
+ // Read opcode strings
+ stream.reset(_disk.createReadStream(0x1a, 0x6, 0x00, 2));
+ _strings_v2.saveInsert = readStringAt(*stream, 0x5f);
+ _strings_v2.saveReplace = readStringAt(*stream, 0xe5);
+ _strings_v2.restoreInsert = readStringAt(*stream, 0x132);
+ _strings_v2.restoreReplace = readStringAt(*stream, 0x1c2);
+ _strings.playAgain = readStringAt(*stream, 0x225);
+ _strings.pressReturn = readStringAt(*stream, 0x25f);
_messageIds.cantGoThere = IDI_HR2_MSG_CANT_GO_THERE;
_messageIds.dontUnderstand = IDI_HR2_MSG_DONT_UNDERSTAND;
@@ -97,95 +103,91 @@ void HiRes2Engine::init() {
_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
// Load item picture data
- f.seek(IDI_HR2_OFS_ITEM_PICS);
+ stream.reset(_disk.createReadStream(0x1e, 0x9, 0x05));
for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
Picture2 pic;
- readPictureMeta(f, pic);
+ readPictureMeta(*stream, pic);
_itemPics.push_back(pic);
}
// Load commands from executable
- f.seek(IDI_HR2_OFS_CMDS_1);
- readCommands(f, _roomCommands);
+ stream.reset(_disk.createReadStream(0x1d, 0x7, 0x00, 4));
+ readCommands(*stream, _roomCommands);
- f.seek(IDI_HR2_OFS_CMDS_0);
- readCommands(f, _globalCommands);
+ stream.reset(_disk.createReadStream(0x1f, 0x7, 0x00, 2));
+ readCommands(*stream, _globalCommands);
// Load dropped item offsets
- f.seek(IDI_HR2_OFS_ITEM_OFFSETS);
+ stream.reset(_disk.createReadStream(0x1b, 0x4, 0x15));
for (uint i = 0; i < IDI_HR2_NUM_ITEM_OFFSETS; ++i) {
Common::Point p;
- p.x = f.readByte();
- p.y = f.readByte();
+ p.x = stream->readByte();
+ p.y = stream->readByte();
_itemOffsets.push_back(p);
}
- f.seek(IDI_HR2_OFS_VERBS);
- loadWords(f, _verbs);
+ // Load verbs
+ stream.reset(_disk.createReadStream(0x19, 0x0, 0x00, 3));
+ loadWords(*stream, _verbs);
- f.seek(IDI_HR2_OFS_NOUNS);
- loadWords(f, _nouns);
+ // Load nouns
+ stream.reset(_disk.createReadStream(0x22, 0x2, 0x00, 7));
+ loadWords(*stream, _nouns);
}
void HiRes2Engine::initState() {
_state.vars.clear();
_state.vars.resize(IDI_HR2_NUM_VARS);
- Common::File f;
- openFile(f, IDS_HR2_DISK_IMAGE);
+ StreamPtr stream(_disk.createReadStream(0x21, 0x5, 0x0e, 7));
_state.rooms.clear();
- f.seek(IDI_HR2_OFS_ROOMS);
for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
- Room room = { };
- f.readByte(); // number
+ Room room;
+ stream->readByte(); // number
for (uint j = 0; j < 6; ++j)
- room.connections[j] = f.readByte();
- room.track = f.readByte();
- room.sector = f.readByte();
- room.offset = f.readByte();
- f.readByte(); // always 1, possibly disk?
- room.picture = f.readByte();
- room.curPicture = f.readByte();
- room.isFirstTime = f.readByte();
+ room.connections[j] = stream->readByte();
+ room.data = readDataBlockPtr(*stream);
+ room.picture = stream->readByte();
+ room.curPicture = stream->readByte();
+ room.isFirstTime = stream->readByte();
_state.rooms.push_back(room);
}
+ stream.reset(_disk.createReadStream(0x21, 0x0, 0x00, 2));
+
_state.items.clear();
- f.seek(IDI_HR2_OFS_ITEMS);
- while (f.readByte() != 0xff) {
+ while (stream->readByte() != 0xff) {
Item item = { };
- item.noun = f.readByte();
- item.room = f.readByte();
- item.picture = f.readByte();
- item.isLineArt = f.readByte(); // Is this still used in this way?
- item.position.x = f.readByte();
- item.position.y = f.readByte();
- item.state = f.readByte();
- item.description = f.readByte();
+ item.noun = stream->readByte();
+ item.room = stream->readByte();
+ item.picture = stream->readByte();
+ item.isLineArt = stream->readByte(); // Is this still used in this way?
+ item.position.x = stream->readByte();
+ item.position.y = stream->readByte();
+ item.state = stream->readByte();
+ item.description = stream->readByte();
- f.readByte(); // Struct size
+ stream->readByte(); // Struct size
- byte picListSize = f.readByte();
+ byte picListSize = stream->readByte();
// Flag to keep track of what has been drawn on the screen
- f.readByte();
+ stream->readByte();
for (uint i = 0; i < picListSize; ++i)
- item.roomPictures.push_back(f.readByte());
+ item.roomPictures.push_back(stream->readByte());
_state.items.push_back(item);
}
}
void HiRes2Engine::loadRoom(byte roomNr) {
- Common::File f;
- openFile(f, IDS_HR2_DISK_IMAGE);
Room &room = getRoom(roomNr);
- uint offset = TSO(room.track, room.sector, room.offset);
- f.seek(offset);
- uint16 descOffset = f.readUint16LE();
- uint16 commandOffset = f.readUint16LE();
+ StreamPtr stream(room.data->createReadStream());
+
+ uint16 descOffset = stream->readUint16LE();
+ uint16 commandOffset = stream->readUint16LE();
// There's no picture count. The original engine always checks at most
// five pictures. We use the description offset to bound our search.
@@ -193,15 +195,14 @@ void HiRes2Engine::loadRoom(byte roomNr) {
for (uint i = 0; i < picCount; ++i) {
Picture2 pic;
- readPictureMeta(f, pic);
+ readPictureMeta(*stream, pic);
_roomData.pictures.push_back(pic);
}
- _roomData.description = readStringAt(f, offset + descOffset, 0xff);
-
- f.seek(offset + commandOffset);
+ _roomData.description = readStringAt(*stream, descOffset, 0xff);
- readCommands(f, _roomData.commands);
+ stream->seek(commandOffset);
+ readCommands(*stream, _roomData.commands);
}
void HiRes2Engine::restartGame() {
@@ -213,10 +214,8 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
for (roomPic = _roomData.pictures.begin(); roomPic != _roomData.pictures.end(); ++roomPic) {
if (roomPic->nr == pic) {
- Common::File f;
- openFile(f, IDS_HR2_DISK_IMAGE);
- f.seek(TSO(roomPic->track, roomPic->sector, roomPic->offset));
- _graphics->drawPic(f, pos, 0);
+ StreamPtr stream(roomPic->data->createReadStream());
+ _graphics->drawPic(*stream, pos, 0);
return;
}
}
@@ -226,11 +225,9 @@ void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
const Picture2 &pic = _itemPics[item.picture - 1];
- Common::File f;
- openFile(f, IDS_HR2_DISK_IMAGE);
- f.seek(TSO(pic.track, pic.sector, pic.offset));
- f.readByte(); // Skip clear opcode
- _graphics->drawPic(f, pos, 0);
+ StreamPtr stream(pic.data->createReadStream());
+ stream->readByte(); // Skip clear opcode
+ _graphics->drawPic(*stream, pos, 0);
}
void HiRes2Engine::showRoom() {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 1578109..0d32330 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -26,6 +26,7 @@
#include "common/str.h"
#include "adl/adl_v2.h"
+#include "adl/disk.h"
namespace Common {
class ReadStream;
@@ -36,23 +37,6 @@ namespace Adl {
#define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
-// Track, sector, offset
-#define TSO(TRACK, SECTOR, OFFSET) (((TRACK) * 16 + (SECTOR)) * 256 + (OFFSET))
-#define TS(TRACK, SECTOR) TSO(TRACK, SECTOR, 0)
-#define T(TRACK) TS(TRACK, 0)
-
-#define IDI_HR2_OFS_INTRO_TEXT TSO(0x00, 0xd, 0x17)
-#define IDI_HR2_OFS_VERBS T(0x19)
-#define IDI_HR2_OFS_NOUNS TS(0x22, 0x2)
-#define IDI_HR2_OFS_ROOMS TSO(0x21, 0x5, 0x0e) // Skip bogus room 0
-#define IDI_HR2_OFS_MESSAGES TSO(0x1f, 0x2, 0x04) // Skip bogus message 0
-#define IDI_HR2_OFS_ITEM_PICS TSO(0x1e, 0x9, 0x05) // Skip bogus pic 0
-#define IDI_HR2_OFS_ITEMS T(0x21)
-#define IDI_HR2_OFS_ITEM_OFFSETS TSO(0x1b, 0x4, 0x15)
-
-#define IDI_HR2_OFS_CMDS_0 TS(0x1f, 0x7)
-#define IDI_HR2_OFS_CMDS_1 TS(0x1d, 0x7)
-
#define IDI_HR2_NUM_ROOMS 135
#define IDI_HR2_NUM_MESSAGES 254
#define IDI_HR2_NUM_VARS 40
@@ -66,22 +50,9 @@ namespace Adl {
#define IDI_HR2_MSG_ITEM_NOT_HERE 4
#define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
-#define IDI_HR2_OFS_STR_ENTER_COMMAND TSO(0x1a, 0x1, 0xbc)
-#define IDI_HR2_OFS_STR_VERB_ERROR TSO(0x1a, 0x1, 0x4f)
-#define IDI_HR2_OFS_STR_NOUN_ERROR TSO(0x1a, 0x1, 0x8e)
-#define IDI_HR2_OFS_STR_PLAY_AGAIN TSO(0x1a, 0x8, 0x25)
-#define IDI_HR2_OFS_STR_PRESS_RETURN TSO(0x1a, 0x8, 0x5f)
-#define IDI_HR2_OFS_STR_TIME TSO(0x19, 0x7, 0xd7)
-#define IDI_HR2_OFS_STR_SAVE_INSERT TSO(0x1a, 0x6, 0x5f)
-#define IDI_HR2_OFS_STR_SAVE_REPLACE TSO(0x1a, 0x6, 0xe5)
-#define IDI_HR2_OFS_STR_RESTORE_INSERT TSO(0x1a, 0x7, 0x32)
-#define IDI_HR2_OFS_STR_RESTORE_REPLACE TSO(0x1a, 0x7, 0xc2)
-
struct Picture2 {
byte nr;
- byte track;
- byte sector;
- byte offset;
+ DataBlockPtr data;
};
struct RoomData {
@@ -90,6 +61,8 @@ struct RoomData {
Commands commands;
};
+typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
+
class HiRes2Engine : public AdlEngine_v2 {
public:
HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
@@ -107,7 +80,10 @@ private:
void checkInput(byte verb, byte noun);
void loadRoom(byte roomNr);
+ DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+ void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
+ DiskImage_DSK _disk;
RoomData _roomData;
Common::Array<Picture2> _itemPics;
};
Commit: f2de96512a4e53fa2b81c9a1c20f82f283e271ea
https://github.com/scummvm/scummvm/commit/f2de96512a4e53fa2b81c9a1c20f82f283e271ea
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add file-based disk access class
Changed paths:
engines/adl/disk.cpp
engines/adl/disk.h
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index b91efec..e2c3da3 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -21,6 +21,7 @@
*/
#include "common/stream.h"
+#include "common/substream.h"
#include "adl/disk.h"
@@ -87,4 +88,24 @@ bool DiskImage_DSK::open(const Common::String &filename) {
return true;
}
+Common::SeekableReadStream *FilesDataBlock::createReadStream() const {
+ return _files->createReadStream(_filename, _offset);
+}
+
+const DataBlockPtr PlainFiles::getDataBlock(const Common::String &filename, uint offset) const {
+ return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+}
+
+Common::SeekableReadStream *PlainFiles::createReadStream(const Common::String &filename, uint offset) const {
+ Common::File *f(new Common::File());
+
+ if (!f->open(filename))
+ error("Failed to open '%s'", filename.c_str());
+
+ if (offset == 0)
+ return f;
+ else
+ return new Common::SeekableSubReadStream(f, offset, f->size(), DisposeAfterUse::YES);
+}
+
} // End of namespace Adl
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 0bf57c7..b6a5c60 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -43,6 +43,33 @@ public:
typedef Common::SharedPtr<DataBlock> DataBlockPtr;
+class Files {
+public:
+ virtual ~Files() { }
+
+ virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset) const = 0;
+ virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset) const = 0;
+};
+
+class FilesDataBlock : public DataBlock {
+public:
+ FilesDataBlock(const Files *files, const Common::String &filename, uint offset) : _files(files), _filename(filename), _offset(offset) { }
+
+ bool isValid() const { return true; }
+ Common::SeekableReadStream *createReadStream() const;
+
+private:
+ const Common::String _filename;
+ uint _offset;
+ const Files *_files;
+};
+
+class PlainFiles : public Files {
+public:
+ const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
+ Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
+};
+
class DiskImage {
public:
DiskImage();
Commit: 5451df3afe2d3857a6dd6d4d232f02d46cb27e03
https://github.com/scummvm/scummvm/commit/5451df3afe2d3857a6dd6d4d232f02d46cb27e03
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use new disk class in hires1
Changed paths:
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index dba6cc7..ba803e8 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -52,6 +52,8 @@ class Speaker;
struct AdlGameDescription;
struct ScriptEnv;
+typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
+
// Save and restore opcodes
#define IDO_ACT_SAVE 0x0f
#define IDO_ACT_LOAD 0x10
@@ -87,8 +89,7 @@ struct Room {
};
struct Picture {
- byte block;
- uint16 offset;
+ DataBlockPtr data;
};
typedef Common::Array<byte> Script;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 8554b18..109879e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -33,13 +33,11 @@
namespace Adl {
void HiRes1Engine::runIntro() const {
- Common::File file;
+ StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_0));
- openFile(file, IDS_HR1_EXE_0);
-
- file.seek(IDI_HR1_OFS_LOGO_0);
+ stream->seek(IDI_HR1_OFS_LOGO_0);
_display->setMode(DISPLAY_MODE_HIRES);
- _display->loadFrameBuffer(file);
+ _display->loadFrameBuffer(*stream);
_display->updateHiResScreen();
delay(4000);
@@ -48,21 +46,19 @@ void HiRes1Engine::runIntro() const {
_display->setMode(DISPLAY_MODE_TEXT);
- Common::File basic;
- openFile(basic, IDS_HR1_LOADER);
-
+ StreamPtr basic(_files.createReadStream(IDS_HR1_LOADER));
Common::String str;
- str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_0, '"');
+ str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_0, '"');
_display->printAsciiString(str + '\r');
- str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_1, '"');
+ str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_1, '"');
_display->printAsciiString(str + "\r\r");
- str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_2, '"');
+ str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_2, '"');
_display->printAsciiString(str + "\r\r");
- str = readStringAt(basic, IDI_HR1_OFS_PD_TEXT_3, '"');
+ str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_3, '"');
_display->printAsciiString(str + '\r');
inputKey();
@@ -71,7 +67,7 @@ void HiRes1Engine::runIntro() const {
_display->setMode(DISPLAY_MODE_MIXED);
- str = readStringAt(file, IDI_HR1_OFS_GAME_OR_HELP);
+ str = readStringAt(*stream, IDI_HR1_OFS_GAME_OR_HELP);
bool instructions = false;
@@ -95,7 +91,7 @@ void HiRes1Engine::runIntro() const {
if (instructions) {
_display->setMode(DISPLAY_MODE_TEXT);
- file.seek(IDI_HR1_OFS_INTRO_TEXT);
+ stream->seek(IDI_HR1_OFS_INTRO_TEXT);
const uint pages[] = { 6, 6, 4, 5, 8, 7, 0 };
@@ -105,9 +101,9 @@ void HiRes1Engine::runIntro() const {
uint count = pages[page++];
for (uint i = 0; i < count; ++i) {
- str = readString(file);
+ str = readString(*stream);
_display->printString(str);
- file.seek(3, SEEK_CUR);
+ stream->seek(3, SEEK_CUR);
}
inputString();
@@ -115,20 +111,18 @@ void HiRes1Engine::runIntro() const {
if (g_engine->shouldQuit())
return;
- file.seek(6, SEEK_CUR);
+ stream->seek(6, SEEK_CUR);
}
}
_display->printAsciiString("\r");
- file.close();
-
_display->setMode(DISPLAY_MODE_MIXED);
// Title screen shown during loading
- openFile(file, IDS_HR1_EXE_1);
- file.seek(IDI_HR1_OFS_LOGO_1);
- _display->loadFrameBuffer(file);
+ stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
+ stream->seek(IDI_HR1_OFS_LOGO_1);
+ _display->loadFrameBuffer(*stream);
_display->updateHiResScreen();
delay(2000);
}
@@ -136,27 +130,25 @@ void HiRes1Engine::runIntro() const {
void HiRes1Engine::init() {
_graphics = new Graphics_v1(*_display);
- Common::File f;
- openFile(f, IDS_HR1_MESSAGES);
+ StreamPtr stream(_files.createReadStream(IDS_HR1_MESSAGES));
for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
- _messages.push_back(readString(f, APPLECHAR('\r')) + APPLECHAR('\r'));
+ _messages.push_back(readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r'));
- f.close();
- openFile(f, IDS_HR1_EXE_1);
+ stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
// Some messages have overrides inside the executable
- _messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(f, IDI_HR1_OFS_STR_CANT_GO_THERE);
- _messages[IDI_HR1_MSG_DONT_HAVE_IT - 1] = readStringAt(f, IDI_HR1_OFS_STR_DONT_HAVE_IT);
- _messages[IDI_HR1_MSG_DONT_UNDERSTAND - 1] = readStringAt(f, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
- _messages[IDI_HR1_MSG_GETTING_DARK - 1] = readStringAt(f, IDI_HR1_OFS_STR_GETTING_DARK);
+ _messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
+ _messages[IDI_HR1_MSG_DONT_HAVE_IT - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_HAVE_IT);
+ _messages[IDI_HR1_MSG_DONT_UNDERSTAND - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
+ _messages[IDI_HR1_MSG_GETTING_DARK - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_GETTING_DARK);
// Load other strings from executable
- _strings.enterCommand = readStringAt(f, IDI_HR1_OFS_STR_ENTER_COMMAND);
- _strings.verbError = readStringAt(f, IDI_HR1_OFS_STR_VERB_ERROR);
- _strings.nounError = readStringAt(f, IDI_HR1_OFS_STR_NOUN_ERROR);
- _strings.playAgain = readStringAt(f, IDI_HR1_OFS_STR_PLAY_AGAIN);
- _strings.pressReturn = readStringAt(f, IDI_HR1_OFS_STR_PRESS_RETURN);
+ _strings.enterCommand = readStringAt(*stream, IDI_HR1_OFS_STR_ENTER_COMMAND);
+ _strings.verbError = readStringAt(*stream, IDI_HR1_OFS_STR_VERB_ERROR);
+ _strings.nounError = readStringAt(*stream, IDI_HR1_OFS_STR_NOUN_ERROR);
+ _strings.playAgain = readStringAt(*stream, IDI_HR1_OFS_STR_PLAY_AGAIN);
+ _strings.pressReturn = readStringAt(*stream, IDI_HR1_OFS_STR_PRESS_RETURN);
// Set message IDs
_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
@@ -166,49 +158,49 @@ void HiRes1Engine::init() {
_messageIds.thanksForPlaying = IDI_HR1_MSG_THANKS_FOR_PLAYING;
// Load picture data from executable
- f.seek(IDI_HR1_OFS_PICS);
+ stream->seek(IDI_HR1_OFS_PICS);
for (uint i = 0; i < IDI_HR1_NUM_PICS; ++i) {
struct Picture pic;
- pic.block = f.readByte();
- pic.offset = f.readUint16LE();
+ byte block = stream->readByte();
+ Common::String name = Common::String::format("BLOCK%i", block);
+ uint16 offset = stream->readUint16LE();
+ pic.data = _files.getDataBlock(name, offset);
_pictures.push_back(pic);
}
// Load commands from executable
- f.seek(IDI_HR1_OFS_CMDS_1);
- readCommands(f, _roomCommands);
+ stream->seek(IDI_HR1_OFS_CMDS_1);
+ readCommands(*stream, _roomCommands);
- f.seek(IDI_HR1_OFS_CMDS_0);
- readCommands(f, _globalCommands);
+ stream->seek(IDI_HR1_OFS_CMDS_0);
+ readCommands(*stream, _globalCommands);
// Load dropped item offsets
- f.seek(IDI_HR1_OFS_ITEM_OFFSETS);
+ stream->seek(IDI_HR1_OFS_ITEM_OFFSETS);
for (uint i = 0; i < IDI_HR1_NUM_ITEM_OFFSETS; ++i) {
Common::Point p;
- p.x = f.readByte();
- p.y = f.readByte();
+ p.x = stream->readByte();
+ p.y = stream->readByte();
_itemOffsets.push_back(p);
}
// Load right-angle line art
- f.seek(IDI_HR1_OFS_CORNERS);
- uint16 cornersCount = f.readUint16LE();
+ stream->seek(IDI_HR1_OFS_CORNERS);
+ uint16 cornersCount = stream->readUint16LE();
for (uint i = 0; i < cornersCount; ++i)
- _corners.push_back(IDI_HR1_OFS_CORNERS + f.readUint16LE());
+ _corners.push_back(_files.getDataBlock(IDS_HR1_EXE_1, IDI_HR1_OFS_CORNERS + stream->readUint16LE()));
- if (f.eos() || f.err())
+ if (stream->eos() || stream->err())
error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
- f.seek(IDI_HR1_OFS_VERBS);
- loadWords(f, _verbs);
+ stream->seek(IDI_HR1_OFS_VERBS);
+ loadWords(*stream, _verbs);
- f.seek(IDI_HR1_OFS_NOUNS);
- loadWords(f, _nouns);
+ stream->seek(IDI_HR1_OFS_NOUNS);
+ loadWords(*stream, _nouns);
}
void HiRes1Engine::initState() {
- Common::File f;
-
_state.room = 1;
_state.moves = 1;
_state.isDark = false;
@@ -216,43 +208,43 @@ void HiRes1Engine::initState() {
_state.vars.clear();
_state.vars.resize(IDI_HR1_NUM_VARS);
- openFile(f, IDS_HR1_EXE_1);
+ StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_1));
// Load room data from executable
_state.rooms.clear();
_roomDesc.clear();
- f.seek(IDI_HR1_OFS_ROOMS);
+ stream->seek(IDI_HR1_OFS_ROOMS);
for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
Room room;
- f.readByte();
- _roomDesc.push_back(f.readByte());
+ stream->readByte();
+ _roomDesc.push_back(stream->readByte());
for (uint j = 0; j < 6; ++j)
- room.connections[j] = f.readByte();
- room.picture = f.readByte();
- room.curPicture = f.readByte();
+ room.connections[j] = stream->readByte();
+ room.picture = stream->readByte();
+ room.curPicture = stream->readByte();
_state.rooms.push_back(room);
}
// Load item data from executable
_state.items.clear();
- f.seek(IDI_HR1_OFS_ITEMS);
- while (f.readByte() != 0xff) {
+ stream->seek(IDI_HR1_OFS_ITEMS);
+ while (stream->readByte() != 0xff) {
Item item = { };
- item.noun = f.readByte();
- item.room = f.readByte();
- item.picture = f.readByte();
- item.isLineArt = f.readByte();
- item.position.x = f.readByte();
- item.position.y = f.readByte();
- item.state = f.readByte();
- item.description = f.readByte();
+ item.noun = stream->readByte();
+ item.room = stream->readByte();
+ item.picture = stream->readByte();
+ item.isLineArt = stream->readByte();
+ item.position.x = stream->readByte();
+ item.position.y = stream->readByte();
+ item.state = stream->readByte();
+ item.description = stream->readByte();
- f.readByte();
+ stream->readByte();
- byte size = f.readByte();
+ byte size = stream->readByte();
for (uint i = 0; i < size; ++i)
- item.roomPictures.push_back(f.readByte());
+ item.roomPictures.push_back(stream->readByte());
_state.items.push_back(item);
}
@@ -266,12 +258,7 @@ void HiRes1Engine::restartGame() {
}
void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
- Common::File f;
- Common::String name = Common::String::format("BLOCK%i", _pictures[pic].block);
-
- openFile(f, name);
- f.seek(_pictures[pic].offset);
- _graphics->drawPic(f, pos, 0x7f);
+ _graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
}
void HiRes1Engine::printMessage(uint idx, bool wait) {
@@ -295,10 +282,8 @@ void HiRes1Engine::printMessage(uint idx, bool wait) {
void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
if (item.isLineArt) {
- Common::File f;
- openFile(f, IDS_HR1_EXE_1);
- f.seek(_corners[item.picture - 1]);
- static_cast<Graphics_v1 *>(_graphics)->drawCorners(f, pos);
+ StreamPtr stream(_corners[item.picture - 1]->createReadStream());
+ static_cast<Graphics_v1 *>(_graphics)->drawCorners(*stream, pos);
} else
drawPic(item.picture, pos);
}
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 9c31a39..985a18c 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -27,6 +27,7 @@
#include "adl/adl.h"
#include "adl/graphics.h"
+#include "adl/disk.h"
namespace Common {
class ReadStream;
@@ -103,8 +104,9 @@ private:
void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom();
+ PlainFiles _files;
Common::File _exe;
- Common::Array<uint> _corners;
+ Common::Array<DataBlockPtr> _corners;
Common::Array<byte> _roomDesc;
};
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 0d32330..a9a4caa 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -61,8 +61,6 @@ struct RoomData {
Commands commands;
};
-typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
-
class HiRes2Engine : public AdlEngine_v2 {
public:
HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
Commit: 3b67b07364616548e0fdc9809bdb503ba7faad88
https://github.com/scummvm/scummvm/commit/3b67b07364616548e0fdc9809bdb503ba7faad88
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Set ADGF_UNSTABLE
Changed paths:
engines/adl/detection.cpp
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 81050d7..3d29687 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -88,7 +88,7 @@ static const AdlGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformApple2GS, // FIXME
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES1
@@ -102,7 +102,7 @@ static const AdlGameDescription gameDescriptions[] = {
},
Common::EN_ANY,
Common::kPlatformApple2GS, // FIXME
- ADGF_NO_FLAGS,
+ ADGF_UNSTABLE,
GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
},
GAME_TYPE_HIRES2
Commit: 71ca8de7e65d535e97d87bb1d30cbc1d9098cc07
https://github.com/scummvm/scummvm/commit/71ca8de7e65d535e97d87bb1d30cbc1d9098cc07
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add support for Apple DOS 3.3 disk images
Changed paths:
engines/adl/disk.cpp
engines/adl/disk.h
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index e2c3da3..b7de55a 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -22,6 +22,7 @@
#include "common/stream.h"
#include "common/substream.h"
+#include "common/memstream.h"
#include "adl/disk.h"
@@ -80,12 +81,11 @@ bool DiskImage_DSK::open(const Common::String &filename) {
_tracks = 35;
_sectorsPerTrack = 16;
_bytesPerSector = 256;
- break;
- default:
- warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
+ return true;
}
- return true;
+ warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
+ return false;
}
Common::SeekableReadStream *FilesDataBlock::createReadStream() const {
@@ -108,4 +108,183 @@ Common::SeekableReadStream *PlainFiles::createReadStream(const Common::String &f
return new Common::SeekableSubReadStream(f, offset, f->size(), DisposeAfterUse::YES);
}
+Files_DOS33::~Files_DOS33() {
+ delete _disk;
+}
+
+Files_DOS33::Files_DOS33() :
+ _disk(nullptr) {
+}
+
+void Files_DOS33::readSectorList(TrackSector start, Common::Array<TrackSector> &list) {
+ TrackSector index = start;
+
+ while (index.track != 0) {
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(index.track, index.sector));
+
+ stream->readByte();
+ index.track = stream->readByte();
+ index.sector = stream->readByte();
+
+ stream->seek(9, SEEK_CUR);
+
+ // This only handles sequential files
+ TrackSector ts;
+ ts.track = stream->readByte();
+ ts.sector = stream->readByte();
+
+ while (ts.track != 0) {
+ list.push_back(ts);
+
+ ts.track = stream->readByte();
+ ts.sector = stream->readByte();
+
+ if (stream->err())
+ error("Error reading sector list");
+
+ if (stream->eos())
+ break;
+ }
+ }
+}
+
+void Files_DOS33::readVTOC() {
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(0x11, 0x00));
+ stream->readByte();
+ byte track = stream->readByte();
+ byte sector = stream->readByte();
+
+ while (track != 0) {
+ char name[kFilenameLen + 1] = { };
+
+ stream.reset(_disk->createReadStream(track, sector));
+ stream->readByte();
+ track = stream->readByte();
+ sector = stream->readByte();
+ stream->seek(8, SEEK_CUR);
+
+ for (uint i = 0; i < 7; ++i) {
+ TOCEntry entry;
+ TrackSector sectorList;
+ sectorList.track = stream->readByte();
+ sectorList.sector = stream->readByte();
+ entry.type = stream->readByte();
+ stream->read(name, kFilenameLen);
+
+ // Convert to ASCII
+ for (uint j = 0; j < kFilenameLen; j++)
+ name[j] &= 0x7f;
+
+ // Strip trailing spaces
+ for (int j = kFilenameLen - 1; j >= 0; --j) {
+ if (name[j] == ' ')
+ name[j] = 0;
+ else
+ break;
+ }
+
+ entry.totalSectors = stream->readUint16BE();
+
+ if (sectorList.track != 0) {
+ readSectorList(sectorList, entry.sectors);
+ _toc[name] = entry;
+ }
+ }
+ }
+}
+
+const DataBlockPtr Files_DOS33::getDataBlock(const Common::String &filename, uint offset) const {
+ return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+}
+
+Common::SeekableReadStream *Files_DOS33::createReadStreamText(const TOCEntry &entry) const {
+ byte *buf = (byte *)malloc(entry.sectors.size() * kSectorSize);
+ byte *p = buf;
+
+ for (uint i = 0; i < entry.sectors.size(); ++i) {
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(entry.sectors[i].track, entry.sectors[i].sector));
+
+ assert(stream->size() == kSectorSize);
+
+ while (true) {
+ byte textChar = stream->readByte();
+
+ if (stream->eos() || textChar == 0)
+ break;
+
+ if (stream->err())
+ error("Error reading text file");
+
+ *p++ = textChar;
+ }
+ }
+
+ return new Common::MemoryReadStream(buf, p - buf, DisposeAfterUse::YES);
+}
+
+Common::SeekableReadStream *Files_DOS33::createReadStreamBinary(const TOCEntry &entry) const {
+ byte *buf = (byte *)malloc(entry.sectors.size() * kSectorSize);
+
+ Common::ScopedPtr<Common::SeekableReadStream> stream(_disk->createReadStream(entry.sectors[0].track, entry.sectors[0].sector));
+
+ if (entry.type == kFileTypeBinary)
+ stream->readUint16LE(); // Skip start address
+
+ uint16 size = stream->readUint16LE();
+ uint16 offset = 0;
+ uint16 sectorIdx = 1;
+
+ while (true) {
+ offset += stream->read(buf + offset, size - offset);
+
+ if (offset == size)
+ break;
+
+ if (stream->err())
+ error("Error reading binary file");
+
+ assert(stream->eos());
+
+ if (sectorIdx == entry.sectors.size())
+ error("Not enough sectors for binary file size");
+
+ stream.reset(_disk->createReadStream(entry.sectors[sectorIdx].track, entry.sectors[sectorIdx].sector));
+ ++sectorIdx;
+ }
+
+ return new Common::MemoryReadStream(buf, size, DisposeAfterUse::YES);
+}
+
+Common::SeekableReadStream *Files_DOS33::createReadStream(const Common::String &filename, uint offset) const {
+ if (!_toc.contains(filename))
+ error("Failed to locate '%s'", filename.c_str());
+
+ const TOCEntry &entry = _toc[filename];
+
+ Common::SeekableReadStream *stream;
+
+ switch(entry.type) {
+ case kFileTypeText:
+ stream = createReadStreamText(entry);
+ break;
+ case kFileTypeAppleSoft:
+ case kFileTypeBinary:
+ stream = createReadStreamBinary(entry);
+ break;
+ default:
+ error("Unsupported file type %i", entry.type);
+ }
+
+ return new Common::SeekableSubReadStream(stream, offset, stream->size(), DisposeAfterUse::YES);
+}
+
+bool Files_DOS33::open(const Common::String &filename) {
+ _disk = new DiskImage_DSK();
+ if (!_disk->open(filename))
+ return false;
+
+ readVTOC();
+ return true;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index b6a5c60..799fa37 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -22,6 +22,7 @@
#include "common/ptr.h"
#include "common/file.h"
+#include "common/debug.h"
#ifndef ADL_DISK_H
#define ADL_DISK_H
@@ -47,8 +48,8 @@ class Files {
public:
virtual ~Files() { }
- virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset) const = 0;
- virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset) const = 0;
+ virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const = 0;
+ virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const = 0;
};
class FilesDataBlock : public DataBlock {
@@ -103,6 +104,47 @@ public:
Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
};
+class Files_DOS33 : public Files {
+public:
+ Files_DOS33();
+ ~Files_DOS33();
+
+ bool open(const Common::String &filename);
+ const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
+ Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
+
+private:
+ enum FileType {
+ kFileTypeText = 0,
+ kFileTypeAppleSoft = 2,
+ kFileTypeBinary = 4
+ };
+
+ enum {
+ kSectorSize = 256,
+ kFilenameLen = 30
+ };
+
+ struct TrackSector {
+ byte track;
+ byte sector;
+ };
+
+ struct TOCEntry {
+ byte type;
+ uint16 totalSectors;
+ Common::Array<TrackSector> sectors;
+ };
+
+ void readVTOC();
+ void readSectorList(TrackSector start, Common::Array<TrackSector> &list);
+ Common::SeekableReadStream *createReadStreamText(const TOCEntry &entry) const;
+ Common::SeekableReadStream *createReadStreamBinary(const TOCEntry &entry) const;
+
+ DiskImage_DSK *_disk;
+ Common::HashMap<Common::String, TOCEntry> _toc;
+};
+
} // End of namespace Adl
#endif
Commit: 02563df42218d103a80e9bc5463cc63909b2f495
https://github.com/scummvm/scummvm/commit/02563df42218d103a80e9bc5463cc63909b2f495
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add support for hires1 disk image
Changed paths:
engines/adl/detection.cpp
engines/adl/hires1.cpp
engines/adl/hires1.h
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 3d29687..457db2d 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -77,7 +77,7 @@ static const PlainGameDescriptor adlGames[] = {
};
static const AdlGameDescription gameDescriptions[] = {
- { // Hi-Res Adventure #1: Mystery House - Apple II - 1987 PD release
+ { // Hi-Res Adventure #1: Mystery House - Apple II - 1987 PD release - Plain files
{
"hires1", 0,
{
@@ -93,6 +93,20 @@ static const AdlGameDescription gameDescriptions[] = {
},
GAME_TYPE_HIRES1
},
+ { // Hi-Res Adventure #1: Mystery House - Apple II - 1987 PD release - .DSK format
+ {
+ "hires1", 0,
+ {
+ { "MYSTHOUS.DSK", 0, "34ba05e62bf51404c4475c349ca48921", 143360 },
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformApple2GS, // FIXME
+ ADGF_UNSTABLE,
+ GUIO2(GAMEOPTION_COLOR, GAMEOPTION_SCANLINES)
+ },
+ GAME_TYPE_HIRES1
+ },
{ // Hi-Res Adventure #2: Wizard and the Princess - Apple II - 1986 SierraVenture release
{
"hires2", 0,
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 109879e..1c46ba6 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -33,7 +33,7 @@
namespace Adl {
void HiRes1Engine::runIntro() const {
- StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_0));
+ StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_0));
stream->seek(IDI_HR1_OFS_LOGO_0);
_display->setMode(DISPLAY_MODE_HIRES);
@@ -46,7 +46,7 @@ void HiRes1Engine::runIntro() const {
_display->setMode(DISPLAY_MODE_TEXT);
- StreamPtr basic(_files.createReadStream(IDS_HR1_LOADER));
+ StreamPtr basic(_files->createReadStream(IDS_HR1_LOADER));
Common::String str;
str = readStringAt(*basic, IDI_HR1_OFS_PD_TEXT_0, '"');
@@ -120,7 +120,7 @@ void HiRes1Engine::runIntro() const {
_display->setMode(DISPLAY_MODE_MIXED);
// Title screen shown during loading
- stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
+ stream.reset(_files->createReadStream(IDS_HR1_EXE_1));
stream->seek(IDI_HR1_OFS_LOGO_1);
_display->loadFrameBuffer(*stream);
_display->updateHiResScreen();
@@ -128,14 +128,21 @@ void HiRes1Engine::runIntro() const {
}
void HiRes1Engine::init() {
+ if (Common::File::exists("MYSTHOUS.DSK")) {
+ _files = new Files_DOS33();
+ if (!static_cast<Files_DOS33 *>(_files)->open("MYSTHOUS.DSK"))
+ error("Failed to open MYSTHOUS.DSK");
+ } else
+ _files = new PlainFiles();
+
_graphics = new Graphics_v1(*_display);
- StreamPtr stream(_files.createReadStream(IDS_HR1_MESSAGES));
+ StreamPtr stream(_files->createReadStream(IDS_HR1_MESSAGES));
for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
_messages.push_back(readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r'));
- stream.reset(_files.createReadStream(IDS_HR1_EXE_1));
+ stream.reset(_files->createReadStream(IDS_HR1_EXE_1));
// Some messages have overrides inside the executable
_messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
@@ -164,7 +171,7 @@ void HiRes1Engine::init() {
byte block = stream->readByte();
Common::String name = Common::String::format("BLOCK%i", block);
uint16 offset = stream->readUint16LE();
- pic.data = _files.getDataBlock(name, offset);
+ pic.data = _files->getDataBlock(name, offset);
_pictures.push_back(pic);
}
@@ -188,7 +195,7 @@ void HiRes1Engine::init() {
stream->seek(IDI_HR1_OFS_CORNERS);
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_CORNERS + stream->readUint16LE()));
if (stream->eos() || stream->err())
error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
@@ -208,7 +215,7 @@ void HiRes1Engine::initState() {
_state.vars.clear();
_state.vars.resize(IDI_HR1_NUM_VARS);
- StreamPtr stream(_files.createReadStream(IDS_HR1_EXE_1));
+ StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
// Load room data from executable
_state.rooms.clear();
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 985a18c..cb1730a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -91,7 +91,8 @@ namespace Adl {
class HiRes1Engine : public AdlEngine {
public:
- HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd) { }
+ HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _files(nullptr) { }
+ ~HiRes1Engine() { delete _files; }
private:
// AdlEngine
@@ -104,7 +105,7 @@ private:
void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom();
- PlainFiles _files;
+ Files *_files;
Common::File _exe;
Common::Array<DataBlockPtr> _corners;
Common::Array<byte> _roomDesc;
Commit: 7ee183ca481c2729cb703ced3b6a3fa4ad7d73a3
https://github.com/scummvm/scummvm/commit/7ee183ca481c2729cb703ced3b6a3fa4ad7d73a3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Refactor disk classes
Changed paths:
engines/adl/adl.h
engines/adl/disk.cpp
engines/adl/disk.h
engines/adl/hires1.cpp
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ba803e8..731b7e3 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -52,8 +52,6 @@ class Speaker;
struct AdlGameDescription;
struct ScriptEnv;
-typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
-
// Save and restore opcodes
#define IDO_ACT_SAVE 0x0f
#define IDO_ACT_LOAD 0x10
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index b7de55a..22a7d7a 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -28,35 +28,8 @@
namespace Adl {
-DiskImage::DiskImage() :
- _tracks(0),
- _sectorsPerTrack(0),
- _bytesPerSector(0) {
- _f = new Common::File();
-}
-
-DiskImage::~DiskImage() {
- delete _f;
-}
-
-DiskImageDataBlock::DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size) :
- _track(track),
- _sector(sector),
- _offset(offset),
- _size(size),
- _disk(disk) { }
-
-bool DiskImageDataBlock::isValid() const {
- return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
-}
-
-Common::SeekableReadStream *DiskImageDataBlock::createReadStream() const {
- return _disk->createReadStream(_track, _sector, _offset, _size);
-}
-
-// .DSK disk image - 35 tracks, 16 sectors per track, 256 bytes per sector, raw sector layout
const DataBlockPtr DiskImage_DSK::getDataBlock(uint track, uint sector, uint offset, uint size) const {
- return Common::SharedPtr<DiskImageDataBlock>(new DiskImageDataBlock(this, track, sector, offset, size));
+ return Common::SharedPtr<DiskImage::DataBlock>(new DiskImage::DataBlock(this, track, sector, offset, size));
}
Common::SeekableReadStream *DiskImage_DSK::createReadStream(uint track, uint sector, uint offset, uint size) const {
@@ -81,22 +54,20 @@ bool DiskImage_DSK::open(const Common::String &filename) {
_tracks = 35;
_sectorsPerTrack = 16;
_bytesPerSector = 256;
- return true;
+ break;
+ default:
+ warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
+ return false;
}
- warning("Unrecognized disk image '%s' of size %d bytes", filename.c_str(), filesize);
- return false;
-}
-
-Common::SeekableReadStream *FilesDataBlock::createReadStream() const {
- return _files->createReadStream(_filename, _offset);
+ return true;
}
-const DataBlockPtr PlainFiles::getDataBlock(const Common::String &filename, uint offset) const {
- return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+const DataBlockPtr Files_Plain::getDataBlock(const Common::String &filename, uint offset) const {
+ return Common::SharedPtr<Files::DataBlock>(new Files::DataBlock(this, filename, offset));
}
-Common::SeekableReadStream *PlainFiles::createReadStream(const Common::String &filename, uint offset) const {
+Common::SeekableReadStream *Files_Plain::createReadStream(const Common::String &filename, uint offset) const {
Common::File *f(new Common::File());
if (!f->open(filename))
@@ -194,7 +165,7 @@ void Files_DOS33::readVTOC() {
}
const DataBlockPtr Files_DOS33::getDataBlock(const Common::String &filename, uint offset) const {
- return Common::SharedPtr<FilesDataBlock>(new FilesDataBlock(this, filename, offset));
+ return Common::SharedPtr<Files::DataBlock>(new Files::DataBlock(this, filename, offset));
}
Common::SeekableReadStream *Files_DOS33::createReadStreamText(const TOCEntry &entry) const {
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 799fa37..12801ec 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -43,6 +43,7 @@ public:
};
typedef Common::SharedPtr<DataBlock> DataBlockPtr;
+typedef Common::ScopedPtr<Common::SeekableReadStream> StreamPtr;
class Files {
public:
@@ -50,60 +51,90 @@ public:
virtual const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const = 0;
virtual Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const = 0;
-};
-
-class FilesDataBlock : public DataBlock {
-public:
- FilesDataBlock(const Files *files, const Common::String &filename, uint offset) : _files(files), _filename(filename), _offset(offset) { }
-
- bool isValid() const { return true; }
- Common::SeekableReadStream *createReadStream() const;
-
-private:
- const Common::String _filename;
- uint _offset;
- const Files *_files;
-};
-class PlainFiles : public Files {
-public:
- const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
- Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
+protected:
+ class DataBlock : public Adl::DataBlock {
+ public:
+ DataBlock(const Files *files, const Common::String &filename, uint offset) :
+ _files(files),
+ _filename(filename),
+ _offset(offset) { }
+
+ bool isValid() const {
+ return true;
+ }
+
+ Common::SeekableReadStream *createReadStream() const {
+ return _files->createReadStream(_filename, _offset);
+ }
+
+ private:
+ const Common::String _filename;
+ uint _offset;
+ const Files *_files;
+ };
};
class DiskImage {
public:
- DiskImage();
- virtual ~DiskImage();
+ DiskImage() :
+ _tracks(0),
+ _sectorsPerTrack(0),
+ _bytesPerSector(0) {
+ _f = new Common::File();
+ }
+
+ virtual ~DiskImage() {
+ delete _f;
+ }
virtual bool open(const Common::String &filename) = 0;
- virtual const DataBlockPtr getDataBlock(uint track, uint sector, uint offset, uint size) const = 0;
- virtual Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset, uint size) const = 0;
+ virtual const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const = 0;
+ virtual Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const = 0;
protected:
+ class DataBlock : public Adl::DataBlock {
+ public:
+ DataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size) :
+ _track(track),
+ _sector(sector),
+ _offset(offset),
+ _size(size),
+ _disk(disk) { }
+
+ bool isValid() const {
+ return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
+ }
+
+ Common::SeekableReadStream *createReadStream() const {
+ return _disk->createReadStream(_track, _sector, _offset, _size);
+ }
+
+ private:
+ uint _track, _sector, _offset, _size;
+ const DiskImage *_disk;
+ };
+
Common::File *_f;
uint _tracks, _sectorsPerTrack, _bytesPerSector;
};
-class DiskImageDataBlock : public DataBlock {
+// Data in plain files
+class Files_Plain : public Files {
public:
- DiskImageDataBlock(const DiskImage *disk, uint track, uint sector, uint offset, uint size);
-
- bool isValid() const;
- Common::SeekableReadStream *createReadStream() const;
-
-private:
- uint _track, _sector, _offset, _size;
- const DiskImage *_disk;
+ const DataBlockPtr getDataBlock(const Common::String &filename, uint offset = 0) const;
+ Common::SeekableReadStream *createReadStream(const Common::String &filename, uint offset = 0) const;
};
+// .DSK disk image - 35 tracks, 16 sectors per track, 256 bytes per sector
class DiskImage_DSK : public DiskImage {
public:
bool open(const Common::String &filename);
- const DataBlockPtr getDataBlock(uint track, uint sector, uint offset, uint size) const;
+ const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
};
+// Data in files contained in Apple DOS 3.3 disk image
class Files_DOS33 : public Files {
public:
Files_DOS33();
@@ -141,7 +172,7 @@ private:
Common::SeekableReadStream *createReadStreamText(const TOCEntry &entry) const;
Common::SeekableReadStream *createReadStreamBinary(const TOCEntry &entry) const;
- DiskImage_DSK *_disk;
+ DiskImage *_disk;
Common::HashMap<Common::String, TOCEntry> _toc;
};
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 1c46ba6..8590e84 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -133,7 +133,7 @@ void HiRes1Engine::init() {
if (!static_cast<Files_DOS33 *>(_files)->open("MYSTHOUS.DSK"))
error("Failed to open MYSTHOUS.DSK");
} else
- _files = new PlainFiles();
+ _files = new Files_Plain();
_graphics = new Graphics_v1(*_display);
Commit: 865bd06845e47897e50b79206cf54439dfef3f04
https://github.com/scummvm/scummvm/commit/865bd06845e47897e50b79206cf54439dfef3f04
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Move room-local commands into base class
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index d95cfd5..90606f7 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -274,6 +274,11 @@ void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
}
void AdlEngine::checkInput(byte verb, byte noun) {
+ // Try room-local command list first
+ if (doOneCommand(_roomData.commands, verb, noun))
+ return;
+
+ // If no match was found, try the global list
if (!doOneCommand(_roomCommands, verb, noun))
printMessage(_messageIds.dontUnderstand);
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 731b7e3..d21bd7b 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -164,6 +164,17 @@ struct State {
typedef Common::List<Command> Commands;
typedef Common::HashMap<Common::String, uint> WordMap;
+struct Picture2 {
+ byte nr;
+ DataBlockPtr data;
+};
+
+struct RoomData {
+ Common::String description;
+ Common::Array<Picture2> pictures;
+ Commands commands;
+};
+
class AdlEngine : public Engine {
public:
virtual ~AdlEngine();
@@ -189,7 +200,7 @@ protected:
void loadWords(Common::ReadStream &stream, WordMap &map) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
- virtual void checkInput(byte verb, byte noun);
+ void checkInput(byte verb, byte noun);
virtual void setupOpcodeTables();
virtual bool matchesCurrentPic(byte pic) const;
@@ -266,6 +277,8 @@ protected:
// <room, verb, noun, script> lists
Commands _roomCommands;
Commands _globalCommands;
+ // Data related to the current room
+ RoomData _roomData;
WordMap _verbs;
WordMap _nouns;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 5e3da00..3543c92 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -243,13 +243,6 @@ void HiRes2Engine::printMessage(uint idx, bool wait) {
printString(_messages[idx - 1]);
}
-void HiRes2Engine::checkInput(byte verb, byte noun) {
- if (doOneCommand(_roomData.commands, verb, noun))
- return;
-
- AdlEngine::checkInput(verb, noun);
-}
-
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes2Engine(syst, gd);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index a9a4caa..0281a79 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -50,17 +50,6 @@ namespace Adl {
#define IDI_HR2_MSG_ITEM_NOT_HERE 4
#define IDI_HR2_MSG_THANKS_FOR_PLAYING 239
-struct Picture2 {
- byte nr;
- DataBlockPtr data;
-};
-
-struct RoomData {
- Common::String description;
- Common::Array<Picture2> pictures;
- Commands commands;
-};
-
class HiRes2Engine : public AdlEngine_v2 {
public:
HiRes2Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
@@ -75,14 +64,12 @@ private:
void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom();
void printMessage(uint idx, bool wait);
- void checkInput(byte verb, byte noun);
void loadRoom(byte roomNr);
DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
DiskImage_DSK _disk;
- RoomData _roomData;
Common::Array<Picture2> _itemPics;
};
Commit: c9824921b4a5b2fa91751b03c24db91acbaac8c5
https://github.com/scummvm/scummvm/commit/c9824921b4a5b2fa91751b03c24db91acbaac8c5
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Move message delay code into hires1 class
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 90606f7..ce6ca03 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -110,15 +110,6 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
error("Error opening '%s'", name.c_str());
}
-void AdlEngine::printMessage(uint idx, bool wait) {
- Common::String msg = _messages[idx - 1];
- wordWrap(msg);
- _display->printString(msg);
-
- if (wait)
- delay(14 * 166018 / 1000);
-}
-
void AdlEngine::delay(uint32 ms) const {
uint32 start = g_system->getMillis();
@@ -746,21 +737,6 @@ bool AdlEngine::canSaveGameStateCurrently() {
return false;
}
-void AdlEngine::wordWrap(Common::String &str) const {
- uint end = 39;
-
- while (1) {
- if (str.size() <= end)
- return;
-
- while (str[end] != APPLECHAR(' '))
- --end;
-
- str.setChar(APPLECHAR('\r'), end);
- end += 40;
- }
-}
-
byte AdlEngine::convertKey(uint16 ascii) const {
ascii = toupper(ascii);
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d21bd7b..9121de4 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -192,7 +192,7 @@ protected:
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
void openFile(Common::File &file, const Common::String &name) const;
- virtual void printMessage(uint idx, bool wait = true);
+ virtual void printMessage(uint idx) = 0;
void delay(uint32 ms) const;
Common::String inputString(byte prompt = 0) const;
@@ -318,9 +318,6 @@ private:
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
- // Text output
- void wordWrap(Common::String &str) const;
-
// Text input
byte convertKey(uint16 ascii) const;
Common::String getLine() const;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 8590e84..804b122 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -268,7 +268,11 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
_graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
}
-void HiRes1Engine::printMessage(uint idx, bool wait) {
+void HiRes1Engine::printMessage(uint idx) {
+ Common::String msg = _messages[idx - 1];
+ wordWrap(msg);
+ _display->printString(msg);
+
// Messages with hardcoded overrides don't delay after printing.
// It's unclear if this is a bug or not. In some cases the result
// is that these strings will scroll past the four-line text window
@@ -281,10 +285,11 @@ void HiRes1Engine::printMessage(uint idx, bool wait) {
case IDI_HR1_MSG_DONT_HAVE_IT:
case IDI_HR1_MSG_DONT_UNDERSTAND:
case IDI_HR1_MSG_GETTING_DARK:
- wait = false;
+ return;
}
- AdlEngine::printMessage(idx, wait);
+ if (_messageDelay)
+ delay(14 * 166018 / 1000);
}
void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
@@ -302,7 +307,24 @@ void HiRes1Engine::showRoom() {
}
_display->updateHiResScreen();
- printMessage(_roomDesc[_state.room - 1], false);
+ _messageDelay = false;
+ printMessage(_roomDesc[_state.room - 1]);
+ _messageDelay = true;
+}
+
+void HiRes1Engine::wordWrap(Common::String &str) const {
+ uint end = 39;
+
+ while (1) {
+ if (str.size() <= end)
+ return;
+
+ while (str[end] != APPLECHAR(' '))
+ --end;
+
+ str.setChar(APPLECHAR('\r'), end);
+ end += 40;
+ }
}
Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index cb1730a..458b2f0 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -91,7 +91,10 @@ namespace Adl {
class HiRes1Engine : public AdlEngine {
public:
- HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine(syst, gd), _files(nullptr) { }
+ HiRes1Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine(syst, gd),
+ _files(nullptr),
+ _messageDelay(true) { }
~HiRes1Engine() { delete _files; }
private:
@@ -101,14 +104,17 @@ private:
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
- void printMessage(uint idx, bool wait = true);
+ void printMessage(uint idx);
void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom();
+ void wordWrap(Common::String &str) const;
+
Files *_files;
Common::File _exe;
Common::Array<DataBlockPtr> _corners;
Common::Array<byte> _roomDesc;
+ bool _messageDelay;
};
} // End of namespace Adl
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 3543c92..dffbd81 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -239,7 +239,7 @@ void HiRes2Engine::showRoom() {
_linesPrinted = 0;
}
-void HiRes2Engine::printMessage(uint idx, bool wait) {
+void HiRes2Engine::printMessage(uint idx) {
printString(_messages[idx - 1]);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 0281a79..35d5e1e 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -63,7 +63,7 @@ private:
void drawPic(byte pic, Common::Point pos) const;
void drawItem(const Item &item, const Common::Point &pos) const;
void showRoom();
- void printMessage(uint idx, bool wait);
+ void printMessage(uint idx);
void loadRoom(byte roomNr);
DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
Commit: 41e82276379f87c74675cc34b682bc69bced865e
https://github.com/scummvm/scummvm/commit/41e82276379f87c74675cc34b682bc69bced865e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Set room description in hires1
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index ce6ca03..e777559 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -110,6 +110,10 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
error("Error opening '%s'", name.c_str());
}
+void AdlEngine::printMessage(uint idx) {
+ printString(_messages[idx - 1]);
+}
+
void AdlEngine::delay(uint32 ms) const {
uint32 start = g_system->getMillis();
@@ -513,6 +517,8 @@ Common::Error AdlEngine::run() {
// (Also see comment below.)
if (!_isRestoring) {
clearScreen();
+ // FIXME: Should only be called when room changes
+ loadRoom(_state.room);
showRoom();
_canSaveNow = _canRestoreNow = true;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9121de4..ffa3579 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -192,7 +192,8 @@ protected:
Common::String readStringAt(Common::SeekableReadStream &stream, uint offset, byte until = 0) const;
void openFile(Common::File &file, const Common::String &name) const;
- virtual void printMessage(uint idx) = 0;
+ virtual void printString(const Common::String &str) = 0;
+ virtual void printMessage(uint idx);
void delay(uint32 ms) const;
Common::String inputString(byte prompt = 0) const;
@@ -310,6 +311,7 @@ private:
virtual void initState() = 0;
virtual void restartGame() = 0;
virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
+ virtual void loadRoom(byte roomNr) = 0;
virtual void showRoom() = 0;
// Engine
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index cea4a93..3a32f48 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -49,9 +49,9 @@ protected:
bool matchesCurrentPic(byte pic) const;
byte roomArg(byte room) const;
void advanceClock();
+ void printString(const Common::String &str);
void checkTextOverflow(char c);
- void printString(const Common::String &str);
int o2_isFirstTime(ScriptEnv &e);
int o2_isRandomGT(ScriptEnv &e);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 804b122..b191afd 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -268,10 +268,17 @@ void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
_graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
}
+void HiRes1Engine::printString(const Common::String &str) {
+ Common::String wrap = str;
+ wordWrap(wrap);
+ _display->printString(wrap);
+
+ if (_messageDelay)
+ delay(14 * 166018 / 1000);
+}
+
void HiRes1Engine::printMessage(uint idx) {
- Common::String msg = _messages[idx - 1];
- wordWrap(msg);
- _display->printString(msg);
+ const Common::String &msg = _messages[idx - 1];
// Messages with hardcoded overrides don't delay after printing.
// It's unclear if this is a bug or not. In some cases the result
@@ -285,11 +292,11 @@ void HiRes1Engine::printMessage(uint idx) {
case IDI_HR1_MSG_DONT_HAVE_IT:
case IDI_HR1_MSG_DONT_UNDERSTAND:
case IDI_HR1_MSG_GETTING_DARK:
+ _display->printString(msg);
return;
}
- if (_messageDelay)
- delay(14 * 166018 / 1000);
+ printString(msg);
}
void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
@@ -300,6 +307,10 @@ void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
drawPic(item.picture, pos);
}
+void HiRes1Engine::loadRoom(byte roomNr) {
+ _roomData.description = _messages[_roomDesc[_state.room - 1] - 1];
+}
+
void HiRes1Engine::showRoom() {
if (!_state.isDark) {
drawPic(getCurRoom().curPicture);
@@ -308,7 +319,7 @@ void HiRes1Engine::showRoom() {
_display->updateHiResScreen();
_messageDelay = false;
- printMessage(_roomDesc[_state.room - 1]);
+ printString(_roomData.description);
_messageDelay = true;
}
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 458b2f0..d601f7d 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -104,8 +104,10 @@ private:
void initState();
void restartGame();
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
+ void printString(const Common::String &str);
void printMessage(uint idx);
void drawItem(const Item &item, const Common::Point &pos) const;
+ void loadRoom(byte roomNr);
void showRoom();
void wordWrap(Common::String &str) const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index dffbd81..39f2199 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -182,29 +182,6 @@ void HiRes2Engine::initState() {
}
}
-void HiRes2Engine::loadRoom(byte roomNr) {
- Room &room = getRoom(roomNr);
- StreamPtr stream(room.data->createReadStream());
-
- uint16 descOffset = stream->readUint16LE();
- uint16 commandOffset = stream->readUint16LE();
-
- // There's no picture count. The original engine always checks at most
- // five pictures. We use the description offset to bound our search.
- uint16 picCount = (descOffset - 4) / 5;
-
- for (uint i = 0; i < picCount; ++i) {
- Picture2 pic;
- readPictureMeta(*stream, pic);
- _roomData.pictures.push_back(pic);
- }
-
- _roomData.description = readStringAt(*stream, descOffset, 0xff);
-
- stream->seek(commandOffset);
- readCommands(*stream, _roomData.commands);
-}
-
void HiRes2Engine::restartGame() {
initState();
}
@@ -230,8 +207,30 @@ void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
_graphics->drawPic(*stream, pos, 0);
}
+void HiRes2Engine::loadRoom(byte roomNr) {
+ Room &room = getRoom(roomNr);
+ StreamPtr stream(room.data->createReadStream());
+
+ uint16 descOffset = stream->readUint16LE();
+ uint16 commandOffset = stream->readUint16LE();
+
+ // There's no picture count. The original engine always checks at most
+ // five pictures. We use the description offset to bound our search.
+ uint16 picCount = (descOffset - 4) / 5;
+
+ for (uint i = 0; i < picCount; ++i) {
+ Picture2 pic;
+ readPictureMeta(*stream, pic);
+ _roomData.pictures.push_back(pic);
+ }
+
+ _roomData.description = readStringAt(*stream, descOffset, 0xff);
+
+ stream->seek(commandOffset);
+ readCommands(*stream, _roomData.commands);
+}
+
void HiRes2Engine::showRoom() {
- loadRoom(_state.room);
drawPic(getCurRoom().curPicture, Common::Point());
drawItems();
_display->updateHiResScreen();
@@ -239,10 +238,6 @@ void HiRes2Engine::showRoom() {
_linesPrinted = 0;
}
-void HiRes2Engine::printMessage(uint idx) {
- printString(_messages[idx - 1]);
-}
-
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes2Engine(syst, gd);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 35d5e1e..a4bc0b6 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -62,10 +62,9 @@ private:
void restartGame();
void drawPic(byte pic, Common::Point pos) const;
void drawItem(const Item &item, const Common::Point &pos) const;
+ void loadRoom(byte roomNr);
void showRoom();
- void printMessage(uint idx);
- void loadRoom(byte roomNr);
DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
Commit: aa661fae5c3a6be2d09a0a6632770131ff02c550
https://github.com/scummvm/scummvm/commit/aa661fae5c3a6be2d09a0a6632770131ff02c550
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix room loading in hires2
Changed paths:
engines/adl/hires2.cpp
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 39f2199..d4f1c09 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -214,6 +214,7 @@ void HiRes2Engine::loadRoom(byte roomNr) {
uint16 descOffset = stream->readUint16LE();
uint16 commandOffset = stream->readUint16LE();
+ _roomData.pictures.clear();
// There's no picture count. The original engine always checks at most
// five pictures. We use the description offset to bound our search.
uint16 picCount = (descOffset - 4) / 5;
@@ -226,8 +227,11 @@ void HiRes2Engine::loadRoom(byte roomNr) {
_roomData.description = readStringAt(*stream, descOffset, 0xff);
- stream->seek(commandOffset);
- readCommands(*stream, _roomData.commands);
+ _roomData.commands.clear();
+ if (commandOffset != 0) {
+ stream->seek(commandOffset);
+ readCommands(*stream, _roomData.commands);
+ }
}
void HiRes2Engine::showRoom() {
Commit: bd588d96155d2b8626d8f760d4bb41fba60efc8e
https://github.com/scummvm/scummvm/commit/bd588d96155d2b8626d8f760d4bb41fba60efc8e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use HashMaps for room/global pics
Changed paths:
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ffa3579..d8ee5d9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -86,9 +86,7 @@ struct Room {
bool isFirstTime;
};
-struct Picture {
- DataBlockPtr data;
-};
+typedef Common::HashMap<byte, DataBlockPtr> PictureMap;
typedef Common::Array<byte> Script;
@@ -164,14 +162,9 @@ struct State {
typedef Common::List<Command> Commands;
typedef Common::HashMap<Common::String, uint> WordMap;
-struct Picture2 {
- byte nr;
- DataBlockPtr data;
-};
-
struct RoomData {
Common::String description;
- Common::Array<Picture2> pictures;
+ PictureMap pictures;
Commands commands;
};
@@ -272,7 +265,7 @@ protected:
// Message strings in data file
Common::Array<Common::String> _messages;
// Picture data
- Common::Array<Picture> _pictures;
+ PictureMap _pictures;
// Dropped item screen offsets
Common::Array<Common::Point> _itemOffsets;
// <room, verb, noun, script> lists
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index b191afd..4161bfe 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -166,13 +166,11 @@ void HiRes1Engine::init() {
// Load picture data from executable
stream->seek(IDI_HR1_OFS_PICS);
- for (uint i = 0; i < IDI_HR1_NUM_PICS; ++i) {
- struct Picture pic;
+ for (uint i = 1; i <= IDI_HR1_NUM_PICS; ++i) {
byte block = stream->readByte();
Common::String name = Common::String::format("BLOCK%i", block);
uint16 offset = stream->readUint16LE();
- pic.data = _files->getDataBlock(name, offset);
- _pictures.push_back(pic);
+ _pictures[i] = _files->getDataBlock(name, offset);
}
// Load commands from executable
@@ -265,7 +263,7 @@ void HiRes1Engine::restartGame() {
}
void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
- _graphics->drawPic(*_pictures[pic].data->createReadStream(), pos, 0x7f);
+ _graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0x7f);
}
void HiRes1Engine::printString(const Common::String &str) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index d601f7d..29cdd5a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -42,7 +42,7 @@ namespace Adl {
#define IDS_HR1_MESSAGES "MESSAGES"
#define IDI_HR1_NUM_ROOMS 41
-#define IDI_HR1_NUM_PICS 98
+#define IDI_HR1_NUM_PICS 97
#define IDI_HR1_NUM_VARS 20
#define IDI_HR1_NUM_ITEM_OFFSETS 21
#define IDI_HR1_NUM_MESSAGES 167
@@ -79,7 +79,7 @@ namespace Adl {
#define IDI_HR1_OFS_ITEMS 0x0100
#define IDI_HR1_OFS_ROOMS 0x050a
-#define IDI_HR1_OFS_PICS 0x4b00
+#define IDI_HR1_OFS_PICS 0x4b03
#define IDI_HR1_OFS_CMDS_0 0x3c00
#define IDI_HR1_OFS_CMDS_1 0x3d00
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index d4f1c09..f6818a6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -41,11 +41,6 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
return _disk.getDataBlock(track, sector, offset, size);
}
-void HiRes2Engine::readPictureMeta(Common::ReadStream &f, Picture2 &pic) const {
- pic.nr = f.readByte();
- pic.data = readDataBlockPtr(f);
-}
-
void HiRes2Engine::runIntro() const {
StreamPtr stream(_disk.createReadStream(0x00, 0xd, 0x17, 1));
@@ -105,9 +100,8 @@ void HiRes2Engine::init() {
// Load item picture data
stream.reset(_disk.createReadStream(0x1e, 0x9, 0x05));
for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
- Picture2 pic;
- readPictureMeta(*stream, pic);
- _itemPics.push_back(pic);
+ stream->readByte(); // number
+ _itemPics.push_back(readDataBlockPtr(*stream));
}
// Load commands from executable
@@ -187,22 +181,14 @@ void HiRes2Engine::restartGame() {
}
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
- Common::Array<Picture2>::const_iterator roomPic;
-
- for (roomPic = _roomData.pictures.begin(); roomPic != _roomData.pictures.end(); ++roomPic) {
- if (roomPic->nr == pic) {
- StreamPtr stream(roomPic->data->createReadStream());
- _graphics->drawPic(*stream, pos, 0);
- return;
- }
- }
-
- // Check global pic list here
+ if (_roomData.pictures.contains(pic))
+ _graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos, 0);
+ else
+ _graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0);
}
void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
- const Picture2 &pic = _itemPics[item.picture - 1];
- StreamPtr stream(pic.data->createReadStream());
+ StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
stream->readByte(); // Skip clear opcode
_graphics->drawPic(*stream, pos, 0);
}
@@ -220,9 +206,8 @@ void HiRes2Engine::loadRoom(byte roomNr) {
uint16 picCount = (descOffset - 4) / 5;
for (uint i = 0; i < picCount; ++i) {
- Picture2 pic;
- readPictureMeta(*stream, pic);
- _roomData.pictures.push_back(pic);
+ byte nr = stream->readByte();
+ _roomData.pictures[nr] = readDataBlockPtr(*stream);
}
_roomData.description = readStringAt(*stream, descOffset, 0xff);
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index a4bc0b6..17687b5 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -66,10 +66,9 @@ private:
void showRoom();
DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
- void readPictureMeta(Common::ReadStream &f, Picture2 &pic) const;
DiskImage_DSK _disk;
- Common::Array<Picture2> _itemPics;
+ Common::Array<DataBlockPtr> _itemPics;
};
} // End of namespace Adl
Commit: 42c41b449587f388796fe6a95a1a68027da629f9
https://github.com/scummvm/scummvm/commit/42c41b449587f388796fe6a95a1a68027da629f9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load hires2 global pics
Changed paths:
engines/adl/hires2.cpp
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index f6818a6..1e06135 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -38,6 +38,10 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
byte sector = f.readByte();
byte offset = f.readByte();
byte size = f.readByte();
+
+ if (f.eos() || f.err())
+ error("Error reading DataBlockPtr");
+
return _disk.getDataBlock(track, sector, offset, size);
}
@@ -97,6 +101,16 @@ void HiRes2Engine::init() {
_messageIds.itemNotHere = IDI_HR2_MSG_ITEM_NOT_HERE;
_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
+ // Load global picture data
+ stream.reset(_disk.createReadStream(0x19, 0xa, 0x80, 0));
+ byte picNr;
+ while ((picNr = stream->readByte()) != 0xff) {
+ if (stream->eos() || stream->err())
+ error("Error reading global pic list");
+
+ _pictures[picNr] = readDataBlockPtr(*stream);
+ }
+
// Load item picture data
stream.reset(_disk.createReadStream(0x1e, 0x9, 0x05));
for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
Commit: 53e7ecb79c8926481bf916b16af6b6e0a88f7b7b
https://github.com/scummvm/scummvm/commit/53e7ecb79c8926481bf916b16af6b6e0a88f7b7b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Remove unused DrawPic color parameter
Changed paths:
engines/adl/graphics.h
engines/adl/graphics_v1.cpp
engines/adl/graphics_v2.cpp
engines/adl/hires1.cpp
engines/adl/hires2.cpp
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index 95f4159..b422959 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -35,7 +35,7 @@ class Display;
class GraphicsMan {
public:
virtual ~GraphicsMan() { }
- virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) = 0;
+ virtual void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) = 0;
protected:
GraphicsMan(Display &display) : _display(display) { }
@@ -47,7 +47,7 @@ protected:
class Graphics_v1 : public GraphicsMan {
public:
Graphics_v1(Display &display) : GraphicsMan(display) { }
- void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
+ 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:
@@ -57,7 +57,7 @@ private:
class Graphics_v2 : public GraphicsMan {
public:
Graphics_v2(Display &display) : GraphicsMan(display), _color(0) { }
- void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color);
+ void drawPic(Common::SeekableReadStream &pic, const Common::Point &pos);
private:
void clear();
diff --git a/engines/adl/graphics_v1.cpp b/engines/adl/graphics_v1.cpp
index edf16b8..29c5ef4 100644
--- a/engines/adl/graphics_v1.cpp
+++ b/engines/adl/graphics_v1.cpp
@@ -29,7 +29,7 @@
namespace Adl {
-void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
+void Graphics_v1::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
byte x, y;
bool bNewLine = false;
byte oldX = 0, oldY = 0;
diff --git a/engines/adl/graphics_v2.cpp b/engines/adl/graphics_v2.cpp
index 7da4eed..40936f5 100644
--- a/engines/adl/graphics_v2.cpp
+++ b/engines/adl/graphics_v2.cpp
@@ -240,8 +240,8 @@ void Graphics_v2::fill(Common::SeekableReadStream &pic) {
}
}
-void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos, byte color) {
- _color = color;
+void Graphics_v2::drawPic(Common::SeekableReadStream &pic, const Common::Point &pos) {
+ _color = 0;
_offset = pos;
while (true) {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 4161bfe..c1a43b8 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -263,7 +263,7 @@ void HiRes1Engine::restartGame() {
}
void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
- _graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0x7f);
+ _graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
}
void HiRes1Engine::printString(const Common::String &str) {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 1e06135..c33857a 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -196,15 +196,15 @@ void HiRes2Engine::restartGame() {
void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
if (_roomData.pictures.contains(pic))
- _graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos, 0);
+ _graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos);
else
- _graphics->drawPic(*_pictures[pic]->createReadStream(), pos, 0);
+ _graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
}
void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
stream->readByte(); // Skip clear opcode
- _graphics->drawPic(*stream, pos, 0);
+ _graphics->drawPic(*stream, pos);
}
void HiRes2Engine::loadRoom(byte roomNr) {
Commit: d0f33851bc7d6256aed051eb5a3287d24969f681
https://github.com/scummvm/scummvm/commit/d0f33851bc7d6256aed051eb5a3287d24969f681
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix regression in message loading
Changed paths:
engines/adl/hires2.cpp
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index c33857a..30114d6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -73,6 +73,8 @@ void HiRes2Engine::init() {
if (str->isValid()) {
StreamPtr strStream(str->createReadStream());
_messages.push_back(readString(*strStream, 0xff));
+ } else {
+ _messages.push_back(Common::String());
}
}
Commit: 760d5ac733ce41a5d4a3f861234850dcc4e96c38
https://github.com/scummvm/scummvm/commit/760d5ac733ce41a5d4a3f861234850dcc4e96c38
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Move drawPic() into base class
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index e777559..db2d9d6 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -356,6 +356,13 @@ void AdlEngine::clearScreen() const {
_display->clear(0x00);
}
+void AdlEngine::drawPic(byte pic, Common::Point pos) const {
+ if (_roomData.pictures.contains(pic))
+ _graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos);
+ else
+ _graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
+}
+
void AdlEngine::drawItems() const {
Common::Array<Item>::const_iterator item;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d8ee5d9..4751ed6 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,6 +234,7 @@ protected:
// Graphics
void clearScreen() const;
+ void drawPic(byte pic, Common::Point pos = Common::Point()) const;
void drawItems() const;
// Sound
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c1a43b8..9e24d4f 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -262,10 +262,6 @@ void HiRes1Engine::restartGame() {
_display->printAsciiString("\r\r\r\r\r");
}
-void HiRes1Engine::drawPic(byte pic, Common::Point pos) const {
- _graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
-}
-
void HiRes1Engine::printString(const Common::String &str) {
Common::String wrap = str;
wordWrap(wrap);
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 29cdd5a..02eb75a 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -103,7 +103,6 @@ private:
void init();
void initState();
void restartGame();
- void drawPic(byte pic, Common::Point pos = Common::Point()) const;
void printString(const Common::String &str);
void printMessage(uint idx);
void drawItem(const Item &item, const Common::Point &pos) const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 30114d6..8be8681 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -196,13 +196,6 @@ void HiRes2Engine::restartGame() {
initState();
}
-void HiRes2Engine::drawPic(byte pic, Common::Point pos) const {
- if (_roomData.pictures.contains(pic))
- _graphics->drawPic(*_roomData.pictures[pic]->createReadStream(), pos);
- else
- _graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
-}
-
void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
stream->readByte(); // Skip clear opcode
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 17687b5..c99c0b0 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -60,7 +60,6 @@ private:
void init();
void initState();
void restartGame();
- void drawPic(byte pic, Common::Point pos) const;
void drawItem(const Item &item, const Common::Point &pos) const;
void loadRoom(byte roomNr);
void showRoom();
Commit: 367cb511d153c6d4733a65b153506b7f0e8b01b3
https://github.com/scummvm/scummvm/commit/367cb511d153c6d4733a65b153506b7f0e8b01b3
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add Console
Changed paths:
A engines/adl/console.cpp
A engines/adl/console.h
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/module.mk
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index db2d9d6..c9673bd 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -47,6 +47,7 @@ AdlEngine::~AdlEngine() {
delete _display;
delete _graphics;
delete _speaker;
+ delete _console;
}
AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
@@ -64,7 +65,9 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
_canRestoreNow(false) {
}
-bool AdlEngine::pollEvent(Common::Event &event) {
+bool AdlEngine::pollEvent(Common::Event &event) const {
+ _console->onFrame();
+
if (g_system->getEventManager()->pollEvent(event)) {
if (event.type != Common::EVENT_KEYDOWN)
return false;
@@ -74,6 +77,11 @@ bool AdlEngine::pollEvent(Common::Event &event) {
quitGame();
return false;
}
+
+ if (event.kbd.keycode == Common::KEYCODE_d) {
+ _console->attach();
+ return false;
+ }
}
return true;
@@ -493,6 +501,7 @@ void AdlEngine::dropItem(byte noun) {
}
Common::Error AdlEngine::run() {
+ _console = new Console(this);
_speaker = new Speaker();
_display = new Display();
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4751ed6..d9fc590 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -35,6 +35,7 @@
#include "audio/mixer.h"
#include "audio/softsynth/pcspk.h"
+#include "adl/console.h"
#include "adl/disk.h"
namespace Common {
@@ -46,6 +47,7 @@ struct Event;
namespace Adl {
+class Console;
class Display;
class GraphicsMan;
class Speaker;
@@ -172,7 +174,7 @@ class AdlEngine : public Engine {
public:
virtual ~AdlEngine();
- static bool pollEvent(Common::Event &event);
+ bool pollEvent(Common::Event &event) const;
protected:
AdlEngine(OSystem *syst, const AdlGameDescription *gd);
@@ -320,6 +322,8 @@ private:
Common::String getWord(const Common::String &line, uint &index) const;
void getInput(uint &verb, uint &noun);
+ Console *_console;
+ GUI::Debugger *getDebugger() { return _console; }
const AdlGameDescription *_gameDescription;
byte _saveVerb, _saveNoun, _restoreVerb, _restoreNoun;
bool _canSaveNow, _canRestoreNow;
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
new file mode 100644
index 0000000..e051716
--- /dev/null
+++ b/engines/adl/console.cpp
@@ -0,0 +1,31 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "adl/console.h"
+
+namespace Adl {
+
+Console::Console(AdlEngine *engine) : GUI::Debugger() {
+ _engine = engine;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/console.h b/engines/adl/console.h
new file mode 100644
index 0000000..56c84f0
--- /dev/null
+++ b/engines/adl/console.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_CONSOLE_H
+#define ADL_CONSOLE_H
+
+#include "gui/debugger.h"
+
+namespace Adl {
+
+class AdlEngine;
+
+class Console : public GUI::Debugger {
+public:
+ Console(AdlEngine *engine);
+
+private:
+ AdlEngine *_engine;
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 661d1b1..7f097a4 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/adl
MODULE_OBJS := \
adl.o \
adl_v2.o \
+ console.o \
detection.o \
disk.o \
display.o \
Commit: 73dfe71b1beaca362463104ed90cdab8a04ea968
https://github.com/scummvm/scummvm/commit/73dfe71b1beaca362463104ed90cdab8a04ea968
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add verbs and nouns debug commands
Changed paths:
engines/adl/adl.h
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d9fc590..4367e8b 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -171,6 +171,7 @@ struct RoomData {
};
class AdlEngine : public Engine {
+friend class Console;
public:
virtual ~AdlEngine();
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index e051716..5fe7f08 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -21,11 +21,68 @@
*/
#include "adl/console.h"
+#include "adl/adl.h"
namespace Adl {
Console::Console(AdlEngine *engine) : GUI::Debugger() {
_engine = engine;
+
+ registerCmd("help", WRAP_METHOD(Console, Cmd_Help));
+ registerCmd("nouns", WRAP_METHOD(Console, Cmd_Nouns));
+ registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
+}
+
+static Common::String toAscii(const Common::String &str) {
+ Common::String ascii(str);
+
+ for (uint i = 0; i < ascii.size(); ++i)
+ ascii.setChar(ascii[i] & 0x7f, i);
+
+ return ascii;
+}
+
+bool Console::Cmd_Help(int argc, const char **argv) {
+ debugPrintf("Parser:\n");
+ debugPrintf(" verbs - Lists the vocabulary verbs\n");
+ debugPrintf(" nouns - Lists the vocabulary nouns\n");
+ return true;
+}
+
+bool Console::Cmd_Verbs(int argc, const char **argv) {
+ if (argc != 1) {
+ debugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ debugPrintf("Verbs in alphabetical order:\n");
+ printWordMap(_engine->_verbs);
+ return true;
+}
+
+bool Console::Cmd_Nouns(int argc, const char **argv) {
+ if (argc != 1) {
+ debugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ debugPrintf("Nouns in alphabetical order:\n");
+ printWordMap(_engine->_nouns);
+ return true;
+}
+
+void Console::printWordMap(const WordMap &wordMap) {
+ Common::StringArray words;
+ WordMap::const_iterator verb;
+
+ for (verb = wordMap.begin(); verb != wordMap.end(); ++verb)
+ words.push_back(verb->_key);
+
+ Common::sort(words.begin(), words.end());
+
+ Common::StringArray::const_iterator word;
+ for (word = words.begin(); word != words.end(); ++word)
+ debugPrintf("%s: %d\n", toAscii(*word).c_str(), wordMap[*word]);
}
} // End of namespace Adl
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 56c84f0..d8a6525 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -25,6 +25,12 @@
#include "gui/debugger.h"
+#include "common/hashmap.h"
+
+namespace Common {
+class String;
+}
+
namespace Adl {
class AdlEngine;
@@ -34,6 +40,12 @@ public:
Console(AdlEngine *engine);
private:
+ bool Cmd_Help(int argc, const char **argv);
+ bool Cmd_Nouns(int argc, const char **argv);
+ bool Cmd_Verbs(int argc, const char **argv);
+
+ void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
+
AdlEngine *_engine;
};
Commit: b24f30527b4ff79e5341e76a7fd3dc21d75e2ed2
https://github.com/scummvm/scummvm/commit/b24f30527b4ff79e5341e76a7fd3dc21d75e2ed2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add script dump and trace for hires1
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.h
engines/adl/console.cpp
engines/adl/console.h
engines/adl/hires1.cpp
engines/adl/hires2.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c9673bd..5bcf1bc 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -22,6 +22,7 @@
#include "common/scummsys.h"
#include "common/config-manager.h"
+#include "common/debug-channels.h"
#include "common/debug.h"
#include "common/error.h"
#include "common/file.h"
@@ -48,10 +49,12 @@ AdlEngine::~AdlEngine() {
delete _graphics;
delete _speaker;
delete _console;
+ delete _dumpFile;
}
AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
Engine(syst),
+ _dumpFile(nullptr),
_display(nullptr),
_graphics(nullptr),
_isRestarting(false),
@@ -63,6 +66,8 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
_restoreNoun(0),
_canSaveNow(false),
_canRestoreNow(false) {
+
+ DebugMan.addDebugChannel(kDebugChannelScript, "Script", "Trace script execution");
}
bool AdlEngine::pollEvent(Common::Event &event) const {
@@ -204,7 +209,7 @@ byte AdlEngine::inputKey(bool showCursor) const {
return key;
}
-void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) const {
+void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const {
uint index = 0;
while (1) {
@@ -220,6 +225,8 @@ void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map) const {
if (!map.contains(word))
map[word] = index;
+ pri.push_back(Console::toAscii(word));
+
byte synonyms = stream.readByte();
if (stream.err() || stream.eos())
@@ -863,54 +870,118 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
}
}
-typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
+bool AdlEngine::op_debug(const char *fmt, ...) const {
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) {
+ va_list va;
+ va_start(va, fmt);
+ Common::String output = Common::String::vformat(fmt, va);
+ va_end(va);
+
+ output += '\n';
+ if (_dumpFile) {
+ _dumpFile->write(output.c_str(), output.size());
+ return true;
+ } else
+ debugN("%s", output.c_str());
+ }
+
+ return false;
+}
+
+#define OP_DEBUG_0(F) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F)) \
+ return 0; \
+} while (0)
+
+#define OP_DEBUG_1(F, P1) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1)) \
+ return 1; \
+} while (0)
+
+#define OP_DEBUG_2(F, P1, P2) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2)) \
+ return 2; \
+} while (0)
+
+#define OP_DEBUG_3(F, P1, P2, P3) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3)) \
+ return 3; \
+} while (0)
+
+#define OP_DEBUG_4(F, P1, P2, P3, P4) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3, P4)) \
+ return 4; \
+} while (0)
int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
if (getItem(e.arg(1)).room == roomArg(e.arg(2)))
return 2;
+
return -1;
}
int AdlEngine::o1_isMovesGT(ScriptEnv &e) {
+ OP_DEBUG_1("\t&& MOVES > %d", e.arg(1));
+
if (_state.moves > e.arg(1))
return 1;
+
return -1;
}
int AdlEngine::o1_isVarEQ(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& VARS[%d] == %d", e.arg(1), e.arg(2));
+
if (getVar(e.arg(1)) == e.arg(2))
return 2;
+
return -1;
}
int AdlEngine::o1_isCurPicEQ(ScriptEnv &e) {
+ OP_DEBUG_1("\t&& GET_CURPIC() == %d", e.arg(1));
+
if (getCurRoom().curPicture == e.arg(1))
return 1;
+
return -1;
}
int AdlEngine::o1_isItemPicEQ(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& GET_ITEM_PIC(%s) == %d", itemStr(e.arg(1)).c_str(), e.arg(2));
+
if (getItem(e.arg(1)).picture == e.arg(2))
return 2;
+
return -1;
}
int AdlEngine::o1_varAdd(ScriptEnv &e) {
+ OP_DEBUG_2("\tVARS[%d] += %d", e.arg(2), e.arg(1));
+
setVar(e.arg(2), getVar(e.arg(2) + e.arg(1)));
return 2;
}
int AdlEngine::o1_varSub(ScriptEnv &e) {
+ OP_DEBUG_2("\tVARS[%d] -= %d", e.arg(2), e.arg(1));
+
setVar(e.arg(2), getVar(e.arg(2)) - e.arg(1));
return 2;
}
int AdlEngine::o1_varSet(ScriptEnv &e) {
+ OP_DEBUG_2("\tVARS[%d] = %d", e.arg(1), e.arg(2));
+
setVar(e.arg(1), e.arg(2));
return 2;
}
int AdlEngine::o1_listInv(ScriptEnv &e) {
+ OP_DEBUG_0("\tLIST_INVENTORY()");
+
Common::Array<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
@@ -921,53 +992,73 @@ int AdlEngine::o1_listInv(ScriptEnv &e) {
}
int AdlEngine::o1_moveItem(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
getItem(e.arg(1)).room = e.arg(2);
return 2;
}
int AdlEngine::o1_setRoom(ScriptEnv &e) {
+ OP_DEBUG_1("\tROOM = %d", e.arg(1));
+
getCurRoom().curPicture = getCurRoom().picture;
_state.room = e.arg(1);
return 1;
}
int AdlEngine::o1_setCurPic(ScriptEnv &e) {
+ OP_DEBUG_1("\tSET_CURPIC(%d)", e.arg(1));
+
getCurRoom().curPicture = e.arg(1);
return 1;
}
int AdlEngine::o1_setPic(ScriptEnv &e) {
+ OP_DEBUG_1("\tSET_PIC(%d)", e.arg(1));
+
getCurRoom().picture = getCurRoom().curPicture = e.arg(1);
return 1;
}
int AdlEngine::o1_printMsg(ScriptEnv &e) {
+ OP_DEBUG_1("\tPRINT(%s)", msgStr(e.arg(1)).c_str());
+
printMessage(e.arg(1));
return 1;
}
int AdlEngine::o1_setLight(ScriptEnv &e) {
+ OP_DEBUG_0("\tLIGHT()");
+
_state.isDark = false;
return 0;
}
int AdlEngine::o1_setDark(ScriptEnv &e) {
+ OP_DEBUG_0("\tDARK()");
+
_state.isDark = true;
return 0;
}
int AdlEngine::o1_save(ScriptEnv &e) {
+ OP_DEBUG_0("\tSAVE_GAME()");
+
saveGameState(0, "");
return 0;
}
int AdlEngine::o1_restore(ScriptEnv &e) {
+ OP_DEBUG_0("\tRESTORE_GAME()");
+
loadGameState(0);
_isRestoring = false;
return 0;
}
int AdlEngine::o1_restart(ScriptEnv &e) {
+ OP_DEBUG_0("\tRESTART_GAME()");
+
_display->printString(_strings.playAgain);
Common::String input = inputString();
@@ -983,12 +1074,16 @@ int AdlEngine::o1_restart(ScriptEnv &e) {
}
int AdlEngine::o1_quit(ScriptEnv &e) {
+ OP_DEBUG_0("\tQUIT_GAME()");
+
printMessage(_messageIds.thanksForPlaying);
quitGame();
return -1;
}
int AdlEngine::o1_placeItem(ScriptEnv &e) {
+ OP_DEBUG_4("\tPLACE_ITEM(%s, %s, (%d, %d))", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str(), e.arg(3), e.arg(4));
+
Item &item = getItem(e.arg(1));
item.room = roomArg(e.arg(2));
@@ -998,17 +1093,23 @@ int AdlEngine::o1_placeItem(ScriptEnv &e) {
}
int AdlEngine::o1_setItemPic(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_ITEM_PIC(%s, %d)", itemStr(e.arg(2)).c_str(), e.arg(1));
+
getItem(e.arg(2)).picture = e.arg(1);
return 2;
}
int AdlEngine::o1_resetPic(ScriptEnv &e) {
+ OP_DEBUG_0("\tRESET_PIC()");
+
getCurRoom().curPicture = getCurRoom().picture;
return 0;
}
template <Direction D>
int AdlEngine::o1_goDirection(ScriptEnv &e) {
+ OP_DEBUG_0((Common::String("\tGO_") + dirStr(D) + "()").c_str());
+
byte room = getCurRoom().connections[D];
if (room == 0) {
@@ -1022,24 +1123,35 @@ int AdlEngine::o1_goDirection(ScriptEnv &e) {
}
int AdlEngine::o1_takeItem(ScriptEnv &e) {
+ OP_DEBUG_0("\tTAKE_ITEM()");
+
takeItem(e.getNoun());
return 0;
}
int AdlEngine::o1_dropItem(ScriptEnv &e) {
+ OP_DEBUG_0("\tDROP_ITEM()");
+
dropItem(e.getNoun());
return 0;
}
int AdlEngine::o1_setRoomPic(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_ROOM_PIC(%d, %d)", e.arg(1), e.arg(2));
+
getRoom(e.arg(1)).picture = getRoom(e.arg(1)).curPicture = e.arg(2);
return 2;
}
bool AdlEngine::matchCommand(ScriptEnv &env) const {
- if (!env.isMatch())
+ if (!env.isMatch() && !_dumpFile)
return false;
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript)) {
+ op_debug("IF\n\tROOM == %s", roomStr(env.getCommand().room).c_str());
+ op_debug("\t&& SAID(%s, %s)", verbStr(env.getCommand().verb).c_str(), nounStr(env.getCommand().noun).c_str());
+ }
+
for (uint i = 0; i < env.getCondCount(); ++i) {
byte op = env.op();
@@ -1048,8 +1160,11 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
int numArgs = (*_condOpcodes[op])(env);
- if (numArgs < 0)
+ if (numArgs < 0) {
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+ op_debug("FAIL\n");
return false;
+ }
env.skip(numArgs + 1);
}
@@ -1058,6 +1173,9 @@ bool AdlEngine::matchCommand(ScriptEnv &env) const {
}
void AdlEngine::doActions(ScriptEnv &env) {
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+ op_debug("THEN");
+
for (uint i = 0; i < env.getActCount(); ++i) {
byte op = env.op();
@@ -1066,11 +1184,17 @@ void AdlEngine::doActions(ScriptEnv &env) {
int numArgs = (*_actOpcodes[op])(env);
- if (numArgs < 0)
+ if (numArgs < 0) {
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+ op_debug("ABORT\n");
return;
+ }
env.skip(numArgs + 1);
}
+
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript))
+ op_debug("END\n");
}
bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
@@ -1097,4 +1221,68 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
}
}
+Common::String AdlEngine::toAscii(const Common::String &str) {
+ Common::String ascii = Console::toAscii(str);
+ if (ascii.lastChar() == '\r')
+ ascii.deleteLastChar();
+ // FIXME: remove '\r's inside string?
+ return ascii;
+}
+
+Common::String AdlEngine::itemStr(uint i) const {
+ byte desc = getItem(i).description;
+ byte noun = getItem(i).noun;
+ Common::String name = Common::String::format("%d", i);
+ if (noun > 0) {
+ name += "/";
+ name += _priNouns[noun - 1];
+ }
+ if (desc > 0) {
+ name += "/";
+ name += toAscii(_messages[desc - 1]);
+ }
+ return name;
+}
+
+Common::String AdlEngine::itemRoomStr(uint i) const {
+ switch (i) {
+ case IDI_ANY:
+ return "CARRYING";
+ case IDI_VOID_ROOM:
+ return "GONE";
+ default:
+ return Common::String::format("%d", i);
+ }
+}
+
+Common::String AdlEngine::roomStr(uint i) const {
+ if (i == IDI_ANY)
+ return "*";
+ else
+ return Common::String::format("%d", i);
+}
+
+Common::String AdlEngine::verbStr(uint i) const {
+ if (i == IDI_ANY)
+ return "*";
+ else
+ return Common::String::format("%d/%s", i, _priVerbs[i - 1].c_str());
+}
+
+Common::String AdlEngine::nounStr(uint i) const {
+ if (i == IDI_ANY)
+ return "*";
+ else
+ return Common::String::format("%d/%s", i, _priNouns[i - 1].c_str());
+}
+
+Common::String AdlEngine::msgStr(uint i) const {
+ return Common::String::format("%d/%s", i, toAscii(_messages[i - 1]).c_str());
+}
+
+Common::String AdlEngine::dirStr(Direction dir) const {
+ static const char *dirs[] = { "NORTH", "SOUTH", "EAST", "WEST", "UP", "DOWN" };
+ return dirs[dir];
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4367e8b..43d3187 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -29,6 +29,7 @@
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "common/func.h"
+#include "common/scummsys.h"
#include "engines/engine.h"
@@ -54,10 +55,15 @@ class Speaker;
struct AdlGameDescription;
struct ScriptEnv;
+enum kDebugChannels {
+ kDebugChannelScript = 1 << 0
+};
+
// Save and restore opcodes
#define IDO_ACT_SAVE 0x0f
#define IDO_ACT_LOAD 0x10
+#define IDI_VOID_ROOM 0xfd
#define IDI_ANY 0xfe
#define IDI_WORD_SIZE 8
@@ -118,6 +124,7 @@ public:
byte getCondCount() const { return _cmd.numCond; }
byte getActCount() const { return _cmd.numAct; }
byte getNoun() const { return _noun; }
+ const Command &getCommand() const { return _cmd; }
private:
const Command &_cmd;
@@ -195,7 +202,7 @@ protected:
Common::String inputString(byte prompt = 0) const;
byte inputKey(bool showCursor = true) const;
- void loadWords(Common::ReadStream &stream, WordMap &map) const;
+ void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
void checkInput(byte verb, byte noun);
@@ -259,6 +266,18 @@ protected:
bool doOneCommand(const Commands &commands, byte verb, byte noun);
void doAllCommands(const Commands &commands, byte verb, byte noun);
+ // Debug functions
+ static Common::String toAscii(const Common::String &str);
+ Common::String itemStr(uint i) const;
+ Common::String roomStr(uint i) const;
+ Common::String itemRoomStr(uint i) const;
+ Common::String verbStr(uint i) const;
+ Common::String nounStr(uint i) const;
+ Common::String msgStr(uint i) const;
+ Common::String dirStr(Direction dir) const;
+ bool op_debug(const char *fmt, ...) const;
+ Common::DumpFile *_dumpFile;
+
Display *_display;
GraphicsMan *_graphics;
Speaker *_speaker;
@@ -280,6 +299,8 @@ protected:
WordMap _verbs;
WordMap _nouns;
+ Common::StringArray _priVerbs;
+ Common::StringArray _priNouns;
struct {
Common::String enterCommand;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 3a32f48..3906021 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -29,7 +29,6 @@
// this is not currently implemented.
#define IDI_CUR_ROOM 0xfc
-#define IDI_VOID_ROOM 0xfd
namespace Common{
class RandomSource;
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 5fe7f08..53e452a 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -20,6 +20,8 @@
*
*/
+#include "common/debug-channels.h"
+
#include "adl/console.h"
#include "adl/adl.h"
@@ -28,12 +30,12 @@ namespace Adl {
Console::Console(AdlEngine *engine) : GUI::Debugger() {
_engine = engine;
- registerCmd("help", WRAP_METHOD(Console, Cmd_Help));
registerCmd("nouns", WRAP_METHOD(Console, Cmd_Nouns));
registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
+ registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
}
-static Common::String toAscii(const Common::String &str) {
+Common::String Console::toAscii(const Common::String &str) {
Common::String ascii(str);
for (uint i = 0; i < ascii.size(); ++i)
@@ -42,13 +44,6 @@ static Common::String toAscii(const Common::String &str) {
return ascii;
}
-bool Console::Cmd_Help(int argc, const char **argv) {
- debugPrintf("Parser:\n");
- debugPrintf(" verbs - Lists the vocabulary verbs\n");
- debugPrintf(" nouns - Lists the vocabulary nouns\n");
- return true;
-}
-
bool Console::Cmd_Verbs(int argc, const char **argv) {
if (argc != 1) {
debugPrintf("Usage: %s\n", argv[0]);
@@ -71,6 +66,35 @@ bool Console::Cmd_Nouns(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_DumpScripts(int argc, const char **argv) {
+ if (argc != 1) {
+ debugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ bool oldFlag = DebugMan.isDebugChannelEnabled(kDebugChannelScript);
+
+ DebugMan.enableDebugChannel("Script");
+
+ _engine->_dumpFile = new Common::DumpFile();
+
+ _engine->_dumpFile->open("GLOBAL.ADL");
+ _engine->doAllCommands(_engine->_globalCommands, IDI_ANY, IDI_ANY);
+ _engine->_dumpFile->close();
+
+ _engine->_dumpFile->open("RESPONSE.ADL");
+ _engine->doAllCommands(_engine->_roomCommands, IDI_ANY, IDI_ANY);
+ _engine->_dumpFile->close();
+
+ delete _engine->_dumpFile;
+ _engine->_dumpFile = nullptr;
+
+ if (!oldFlag)
+ DebugMan.disableDebugChannel("Script");
+
+ return true;
+}
+
void Console::printWordMap(const WordMap &wordMap) {
Common::StringArray words;
WordMap::const_iterator verb;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index d8a6525..86538de 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -39,10 +39,13 @@ class Console : public GUI::Debugger {
public:
Console(AdlEngine *engine);
+ static Common::String toAscii(const Common::String &str);
+
private:
bool Cmd_Help(int argc, const char **argv);
bool Cmd_Nouns(int argc, const char **argv);
bool Cmd_Verbs(int argc, const char **argv);
+ bool Cmd_DumpScripts(int argc, const char **argv);
void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9e24d4f..005e56e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -199,10 +199,10 @@ void HiRes1Engine::init() {
error("Failed to read game data from '" IDS_HR1_EXE_1 "'");
stream->seek(IDI_HR1_OFS_VERBS);
- loadWords(*stream, _verbs);
+ loadWords(*stream, _verbs, _priVerbs);
stream->seek(IDI_HR1_OFS_NOUNS);
- loadWords(*stream, _nouns);
+ loadWords(*stream, _nouns, _priNouns);
}
void HiRes1Engine::initState() {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 8be8681..6e6692b 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -138,11 +138,11 @@ void HiRes2Engine::init() {
// Load verbs
stream.reset(_disk.createReadStream(0x19, 0x0, 0x00, 3));
- loadWords(*stream, _verbs);
+ loadWords(*stream, _verbs, _priVerbs);
// Load nouns
stream.reset(_disk.createReadStream(0x22, 0x2, 0x00, 7));
- loadWords(*stream, _nouns);
+ loadWords(*stream, _nouns, _priNouns);
}
void HiRes2Engine::initState() {
Commit: 2c8e0cefb15205c61a10a650e63d7fb53fad00a6
https://github.com/scummvm/scummvm/commit/2c8e0cefb15205c61a10a650e63d7fb53fad00a6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Store items in a List instead of an Array
Item IDs are not necessarily sequential
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/hires1.cpp
engines/adl/hires2.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 5bcf1bc..038d4ec 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -379,7 +379,7 @@ void AdlEngine::drawPic(byte pic, Common::Point pos) const {
}
void AdlEngine::drawItems() const {
- Common::Array<Item>::const_iterator item;
+ Common::List<Item>::const_iterator item;
uint dropped = 0;
@@ -435,17 +435,23 @@ Room &AdlEngine::getCurRoom() {
}
const Item &AdlEngine::getItem(uint i) const {
- if (i < 1 || i > _state.items.size())
- error("Item %i out of range [1, %i]", i, _state.items.size());
+ Common::List<Item>::const_iterator item;
- return _state.items[i - 1];
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->id == i)
+ return *item;
+
+ error("Item %i not found", i);
}
Item &AdlEngine::getItem(uint i) {
- if (i < 1 || i > _state.items.size())
- error("Item %i out of range [1, %i]", i, _state.items.size());
+ Common::List<Item>::iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->id == i)
+ return *item;
- return _state.items[i - 1];
+ error("Item %i not found", i);
}
byte AdlEngine::getVar(uint i) const {
@@ -463,7 +469,7 @@ void AdlEngine::setVar(uint i, byte value) {
}
void AdlEngine::takeItem(byte noun) {
- Common::Array<Item>::iterator item;
+ Common::List<Item>::iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item) {
if (item->noun != noun || item->room != _state.room)
@@ -493,7 +499,7 @@ void AdlEngine::takeItem(byte noun) {
}
void AdlEngine::dropItem(byte noun) {
- Common::Array<Item>::iterator item;
+ Common::List<Item>::iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item) {
if (item->noun != noun || item->room != IDI_ANY)
@@ -645,12 +651,13 @@ Common::Error AdlEngine::loadGameState(int slot) {
if (size != _state.items.size())
error("Item count mismatch (expected %i; found %i)", _state.items.size(), size);
- for (uint i = 0; i < size; ++i) {
- _state.items[i].room = inFile->readByte();
- _state.items[i].picture = inFile->readByte();
- _state.items[i].position.x = inFile->readByte();
- _state.items[i].position.y = inFile->readByte();
- _state.items[i].state = inFile->readByte();
+ Common::List<Item>::iterator item;
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ item->room = inFile->readByte();
+ item->picture = inFile->readByte();
+ item->position.x = inFile->readByte();
+ item->position.y = inFile->readByte();
+ item->state = inFile->readByte();
}
size = inFile->readUint32BE();
@@ -724,12 +731,13 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
}
outFile->writeUint32BE(_state.items.size());
- for (uint i = 0; i < _state.items.size(); ++i) {
- outFile->writeByte(_state.items[i].room);
- outFile->writeByte(_state.items[i].picture);
- outFile->writeByte(_state.items[i].position.x);
- outFile->writeByte(_state.items[i].position.y);
- outFile->writeByte(_state.items[i].state);
+ Common::List<Item>::const_iterator item;
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ outFile->writeByte(item->room);
+ outFile->writeByte(item->picture);
+ outFile->writeByte(item->position.x);
+ outFile->writeByte(item->position.y);
+ outFile->writeByte(item->state);
}
outFile->writeUint32BE(_state.vars.size());
@@ -982,7 +990,7 @@ int AdlEngine::o1_varSet(ScriptEnv &e) {
int AdlEngine::o1_listInv(ScriptEnv &e) {
OP_DEBUG_0("\tLIST_INVENTORY()");
- Common::Array<Item>::const_iterator item;
+ Common::List<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
if (item->room == IDI_ANY)
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 43d3187..42d6667 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -139,6 +139,7 @@ enum {
};
struct Item {
+ byte id;
byte noun;
byte room;
byte picture;
@@ -157,7 +158,7 @@ struct Time {
struct State {
Common::Array<Room> rooms;
- Common::Array<Item> items;
+ Common::List<Item> items;
Common::Array<byte> vars;
byte room;
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 8a826e5..cc38beb 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -213,7 +213,7 @@ int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
}
int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
- Common::Array<Item>::const_iterator item;
+ Common::List<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
if (item->noun == e.getNoun() && (item->room == roomArg(e.arg(1))))
@@ -223,7 +223,7 @@ int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
}
int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
- Common::Array<Item>::const_iterator item;
+ Common::List<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
if (item->room == IDI_ANY)
@@ -248,7 +248,7 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
byte room1 = roomArg(e.arg(1));
byte room2 = roomArg(e.arg(2));
- Common::Array<Item>::iterator item;
+ Common::List<Item>::iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
if (item->room == room1) {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 005e56e..e0f7574 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -233,8 +233,10 @@ void HiRes1Engine::initState() {
// Load item data from executable
_state.items.clear();
stream->seek(IDI_HR1_OFS_ITEMS);
- while (stream->readByte() != 0xff) {
+ byte id;
+ while ((id = stream->readByte()) != 0xff) {
Item item = { };
+ item.id = id;
item.noun = stream->readByte();
item.room = stream->readByte();
item.picture = stream->readByte();
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 6e6692b..4ac8e88 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -167,8 +167,10 @@ void HiRes2Engine::initState() {
stream.reset(_disk.createReadStream(0x21, 0x0, 0x00, 2));
_state.items.clear();
- while (stream->readByte() != 0xff) {
+ byte id;
+ while ((id = stream->readByte()) != 0xff) {
Item item = { };
+ item.id = id;
item.noun = stream->readByte();
item.room = stream->readByte();
item.picture = stream->readByte();
Commit: cf6bc0e438e5a21fb053c4ccd562d6bed8c4b68d
https://github.com/scummvm/scummvm/commit/cf6bc0e438e5a21fb053c4ccd562d6bed8c4b68d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add script dump and trace for hires2
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 038d4ec..0c27f8b 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -22,7 +22,6 @@
#include "common/scummsys.h"
#include "common/config-manager.h"
-#include "common/debug-channels.h"
#include "common/debug.h"
#include "common/error.h"
#include "common/file.h"
@@ -896,31 +895,6 @@ bool AdlEngine::op_debug(const char *fmt, ...) const {
return false;
}
-#define OP_DEBUG_0(F) do { \
- if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F)) \
- return 0; \
-} while (0)
-
-#define OP_DEBUG_1(F, P1) do { \
- if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1)) \
- return 1; \
-} while (0)
-
-#define OP_DEBUG_2(F, P1, P2) do { \
- if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2)) \
- return 2; \
-} while (0)
-
-#define OP_DEBUG_3(F, P1, P2, P3) do { \
- if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3)) \
- return 3; \
-} while (0)
-
-#define OP_DEBUG_4(F, P1, P2, P3, P4) do { \
- if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3, P4)) \
- return 4; \
-} while (0)
-
int AdlEngine::o1_isItemInRoom(ScriptEnv &e) {
OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
@@ -1258,6 +1232,8 @@ Common::String AdlEngine::itemRoomStr(uint i) const {
return "CARRYING";
case IDI_VOID_ROOM:
return "GONE";
+ case IDI_CUR_ROOM:
+ return "HERE";
default:
return Common::String::format("%d", i);
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 42d6667..ac5e22c 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -23,6 +23,7 @@
#ifndef ADL_ADL_H
#define ADL_ADL_H
+#include "common/debug-channels.h"
#include "common/array.h"
#include "common/rect.h"
#include "common/str.h"
@@ -63,6 +64,7 @@ enum kDebugChannels {
#define IDO_ACT_SAVE 0x0f
#define IDO_ACT_LOAD 0x10
+#define IDI_CUR_ROOM 0xfc
#define IDI_VOID_ROOM 0xfd
#define IDI_ANY 0xfe
@@ -178,6 +180,32 @@ struct RoomData {
Commands commands;
};
+// Opcode debugging macros
+#define OP_DEBUG_0(F) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F)) \
+ return 0; \
+} while (0)
+
+#define OP_DEBUG_1(F, P1) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1)) \
+ return 1; \
+} while (0)
+
+#define OP_DEBUG_2(F, P1, P2) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2)) \
+ return 2; \
+} while (0)
+
+#define OP_DEBUG_3(F, P1, P2, P3) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3)) \
+ return 3; \
+} while (0)
+
+#define OP_DEBUG_4(F, P1, P2, P3, P4) do { \
+ if (DebugMan.isDebugChannelEnabled(kDebugChannelScript) && op_debug(F, P1, P2, P3, P4)) \
+ return 4; \
+} while (0)
+
class AdlEngine : public Engine {
friend class Console;
public:
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index cc38beb..a682c29 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -193,6 +193,8 @@ void AdlEngine_v2::printString(const Common::String &str) {
}
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
+ OP_DEBUG_0("\t&& IS_FIRST_TIME()");
+
bool oldFlag = getCurRoom().isFirstTime;
getCurRoom().isFirstTime = false;
@@ -204,6 +206,8 @@ int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
}
int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
+ OP_DEBUG_1("\t&& RAND() > %d", e.arg(1));
+
byte rnd = _random->getRandomNumber(255);
if (rnd > e.arg(1))
@@ -213,6 +217,8 @@ int AdlEngine_v2::o2_isRandomGT(ScriptEnv &e) {
}
int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
+ OP_DEBUG_1("\t&& NO_SUCH_ITEMS_IN_ROOM(%s)", itemRoomStr(e.arg(1)).c_str());
+
Common::List<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
@@ -223,6 +229,8 @@ int AdlEngine_v2::o2_isNounNotInRoom(ScriptEnv &e) {
}
int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
+ OP_DEBUG_0("\t&& IS_CARRYING_SOMETHING()");
+
Common::List<Item>::const_iterator item;
for (item = _state.items.begin(); item != _state.items.end(); ++item)
@@ -232,6 +240,8 @@ int AdlEngine_v2::o2_isCarryingSomething(ScriptEnv &e) {
}
int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
byte room = roomArg(e.arg(2));
Item &item = getItem(e.arg(1));
@@ -245,6 +255,8 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
}
int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
+ OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)), roomStr(e.arg(2)));
+
byte room1 = roomArg(e.arg(1));
byte room2 = roomArg(e.arg(2));
@@ -261,6 +273,8 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
}
int AdlEngine_v2::o2_save(ScriptEnv &e) {
+ OP_DEBUG_0("\tSAVE_GAME()");
+
int slot = askForSlot(_strings_v2.saveInsert);
if (slot < 0)
@@ -274,6 +288,8 @@ int AdlEngine_v2::o2_save(ScriptEnv &e) {
}
int AdlEngine_v2::o2_restore(ScriptEnv &e) {
+ OP_DEBUG_0("\tRESTORE_GAME()");
+
int slot = askForSlot(_strings_v2.restoreInsert);
if (slot < 0)
@@ -288,6 +304,8 @@ int AdlEngine_v2::o2_restore(ScriptEnv &e) {
}
int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
+ OP_DEBUG_4("\tPLACE_ITEM(%s, %s, (%d, %d))", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str(), e.arg(3), e.arg(4));
+
Item &item = getItem(e.arg(1));
item.room = roomArg(e.arg(2));
@@ -299,6 +317,8 @@ int AdlEngine_v2::o2_placeItem(ScriptEnv &e) {
}
int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
+ OP_DEBUG_0("\tTELL_TIME()");
+
Common::String time = _strings_v2.time;
time.setChar(APPLECHAR('0') + _state.time.hours / 10, 12);
@@ -312,12 +332,15 @@ int AdlEngine_v2::o2_tellTime(ScriptEnv &e) {
}
int AdlEngine_v2::o2_setRoomFromVar(ScriptEnv &e) {
+ OP_DEBUG_1("\tROOM = VAR[%d]", e.arg(1));
getCurRoom().curPicture = getCurRoom().picture;
_state.room = getVar(e.arg(1));
return 1;
}
int AdlEngine_v2::o2_initDisk(ScriptEnv &e) {
+ OP_DEBUG_0("\tINIT_DISK()");
+
_display->printAsciiString("NOT REQUIRED\r");
return 0;
}
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 3906021..40bd40a 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -28,8 +28,6 @@
// Note: this version of ADL redraws only when necessary, but
// this is not currently implemented.
-#define IDI_CUR_ROOM 0xfc
-
namespace Common{
class RandomSource;
}
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 53e452a..d690524 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -78,6 +78,19 @@ bool Console::Cmd_DumpScripts(int argc, const char **argv) {
_engine->_dumpFile = new Common::DumpFile();
+ Common::Array<Room>::const_iterator room;
+ byte roomNr = 1;
+ for (room = _engine->_state.rooms.begin(); room != _engine->_state.rooms.end(); ++room) {
+ _engine->loadRoom(roomNr);
+ if (_engine->_roomData.commands.size() != 0) {
+ _engine->_dumpFile->open(Common::String::format("%03d.ADL", roomNr).c_str());
+ _engine->doAllCommands(_engine->_roomData.commands, IDI_ANY, IDI_ANY);
+ _engine->_dumpFile->close();
+ }
+ ++roomNr;
+ }
+ _engine->loadRoom(_engine->_state.room);
+
_engine->_dumpFile->open("GLOBAL.ADL");
_engine->doAllCommands(_engine->_globalCommands, IDI_ANY, IDI_ANY);
_engine->_dumpFile->close();
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 86538de..e007e09 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -42,7 +42,6 @@ public:
static Common::String toAscii(const Common::String &str);
private:
- bool Cmd_Help(int argc, const char **argv);
bool Cmd_Nouns(int argc, const char **argv);
bool Cmd_Verbs(int argc, const char **argv);
bool Cmd_DumpScripts(int argc, const char **argv);
Commit: 3b72a30c0f32e5b7342f04be086826354525cb24
https://github.com/scummvm/scummvm/commit/3b72a30c0f32e5b7342f04be086826354525cb24
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean up script dump debug command
Changed paths:
engines/adl/console.cpp
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index d690524..185fb42 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -78,16 +78,13 @@ bool Console::Cmd_DumpScripts(int argc, const char **argv) {
_engine->_dumpFile = new Common::DumpFile();
- Common::Array<Room>::const_iterator room;
- byte roomNr = 1;
- for (room = _engine->_state.rooms.begin(); room != _engine->_state.rooms.end(); ++room) {
+ for (byte roomNr = 1; roomNr <= _engine->_state.rooms.size(); ++roomNr) {
_engine->loadRoom(roomNr);
if (_engine->_roomData.commands.size() != 0) {
_engine->_dumpFile->open(Common::String::format("%03d.ADL", roomNr).c_str());
_engine->doAllCommands(_engine->_roomData.commands, IDI_ANY, IDI_ANY);
_engine->_dumpFile->close();
}
- ++roomNr;
}
_engine->loadRoom(_engine->_state.room);
Commit: dd5ce7ebbbc5dd9814a7b1078856f86de1c457cf
https://github.com/scummvm/scummvm/commit/dd5ce7ebbbc5dd9814a7b1078856f86de1c457cf
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add valid_cmds debug command
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 0c27f8b..1b6bf6a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -292,6 +292,28 @@ void AdlEngine::checkInput(byte verb, byte noun) {
printMessage(_messageIds.dontUnderstand);
}
+bool AdlEngine::isInputValid(byte verb, byte noun, bool &is_any) {
+ if (isInputValid(_roomData.commands, verb, noun, is_any))
+ return true;
+ return isInputValid(_roomCommands, verb, noun, is_any);
+}
+
+bool AdlEngine::isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any) {
+ Commands::const_iterator cmd;
+
+ is_any = false;
+ for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+ ScriptEnv env(*cmd, _state.room, verb, noun);
+ if (matchCommand(env)) {
+ if (cmd->verb == IDI_ANY || cmd->noun == IDI_ANY)
+ is_any = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine> OpcodeV1;
#define SetOpcodeTable(x) table = &x;
#define Opcode(x) table->push_back(new OpcodeV1(this, &AdlEngine::x))
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index ac5e22c..18b57ed 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,6 +234,8 @@ protected:
void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
void checkInput(byte verb, byte noun);
+ virtual bool isInputValid(byte verb, byte noun, bool &is_any);
+ virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
virtual void setupOpcodeTables();
virtual bool matchesCurrentPic(byte pic) const;
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 185fb42..003f689 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -33,6 +33,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
registerCmd("nouns", WRAP_METHOD(Console, Cmd_Nouns));
registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
+ registerCmd("valid_cmds", WRAP_METHOD(Console, Cmd_ValidCommands));
}
Common::String Console::toAscii(const Common::String &str) {
@@ -66,6 +67,29 @@ bool Console::Cmd_Nouns(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_ValidCommands(int argc, const char **argv) {
+ if (argc != 1) {
+ debugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ WordMap::const_iterator verb, noun;
+ bool is_any;
+
+ for (verb = _engine->_verbs.begin(); verb != _engine->_verbs.end(); ++verb) {
+ for (noun = _engine->_nouns.begin(); noun != _engine->_nouns.end(); ++noun) {
+ if (_engine->isInputValid(verb->_value, noun->_value, is_any) && !is_any)
+ debugPrintf("%s %s\n", toAscii(verb->_key).c_str(), toAscii(noun->_key).c_str());
+ }
+ if (_engine->isInputValid(verb->_value, IDI_ANY, is_any))
+ debugPrintf("%s *\n", toAscii(verb->_key).c_str());
+ }
+ if (_engine->isInputValid(IDI_ANY, IDI_ANY, is_any))
+ debugPrintf("* *\n");
+
+ return true;
+}
+
bool Console::Cmd_DumpScripts(int argc, const char **argv) {
if (argc != 1) {
debugPrintf("Usage: %s\n", argv[0]);
diff --git a/engines/adl/console.h b/engines/adl/console.h
index e007e09..bfe09a1 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -45,6 +45,7 @@ private:
bool Cmd_Nouns(int argc, const char **argv);
bool Cmd_Verbs(int argc, const char **argv);
bool Cmd_DumpScripts(int argc, const char **argv);
+ bool Cmd_ValidCommands(int argc, const char **argv);
void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
Commit: 3b7813d971feb8ac8292ffb7ddf014ead6f5bf36
https://github.com/scummvm/scummvm/commit/3b7813d971feb8ac8292ffb7ddf014ead6f5bf36
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix debug print for MOVE_ALL_ITEMS
Changed paths:
engines/adl/adl_v2.cpp
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index a682c29..51ea4ec 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -255,7 +255,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
}
int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
- OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)), roomStr(e.arg(2)));
+ OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)).c_str(), roomStr(e.arg(2)).c_str());
byte room1 = roomArg(e.arg(1));
byte room2 = roomArg(e.arg(2));
Commit: 26b8e8d66a0039281ec3b8fe8d2f29efed37fda2
https://github.com/scummvm/scummvm/commit/26b8e8d66a0039281ec3b8fe8d2f29efed37fda2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use columns when printing verb/noun lists
Changed paths:
engines/adl/console.cpp
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 003f689..9653466 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -134,13 +134,11 @@ void Console::printWordMap(const WordMap &wordMap) {
WordMap::const_iterator verb;
for (verb = wordMap.begin(); verb != wordMap.end(); ++verb)
- words.push_back(verb->_key);
+ words.push_back(Common::String::format("%s: %3d", toAscii(verb->_key).c_str(), wordMap[verb->_key]));
Common::sort(words.begin(), words.end());
- Common::StringArray::const_iterator word;
- for (word = words.begin(); word != words.end(); ++word)
- debugPrintf("%s: %d\n", toAscii(*word).c_str(), wordMap[*word]);
+ debugPrintColumns(words);
}
} // End of namespace Adl
Commit: 9eb7af0f671d6b172c838666f423a3be5eaeae09
https://github.com/scummvm/scummvm/commit/9eb7af0f671d6b172c838666f423a3be5eaeae09
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add 'room' debugger command
Changed paths:
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 9653466..e162597 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -23,6 +23,7 @@
#include "common/debug-channels.h"
#include "adl/console.h"
+#include "adl/display.h"
#include "adl/adl.h"
namespace Adl {
@@ -34,6 +35,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
registerCmd("verbs", WRAP_METHOD(Console, Cmd_Verbs));
registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
registerCmd("valid_cmds", WRAP_METHOD(Console, Cmd_ValidCommands));
+ registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
}
Common::String Console::toAscii(const Common::String &str) {
@@ -129,6 +131,38 @@ bool Console::Cmd_DumpScripts(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_Room(int argc, const char **argv) {
+ if (argc > 2) {
+ debugPrintf("Usage: %s [<new_room>]\n", argv[0]);
+ return true;
+ }
+
+ if (argc == 2) {
+ if (!_engine->_canRestoreNow) {
+ debugPrintf("Cannot change rooms right now\n");
+ return true;
+ }
+
+ int roomCount = _engine->_state.rooms.size();
+ int room = strtoul(argv[1], NULL, 0);
+ if (room < 1 || room > roomCount) {
+ debugPrintf("Room %i out of valid range [1, %d]\n", room, roomCount);
+ return true;
+ }
+
+ _engine->_state.room = room;
+ _engine->clearScreen();
+ _engine->loadRoom(_engine->_state.room);
+ _engine->showRoom();
+ _engine->_display->updateTextScreen();
+ _engine->_display->updateHiResScreen();
+ }
+
+ debugPrintf("Current room: %d\n", _engine->_state.room);
+
+ return true;
+}
+
void Console::printWordMap(const WordMap &wordMap) {
Common::StringArray words;
WordMap::const_iterator verb;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index bfe09a1..8af23b9 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -46,6 +46,7 @@ private:
bool Cmd_Verbs(int argc, const char **argv);
bool Cmd_DumpScripts(int argc, const char **argv);
bool Cmd_ValidCommands(int argc, const char **argv);
+ bool Cmd_Room(int argc, const char **argv);
void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
Commit: fde2db9d4c09d4318d9dbc409044838d456693a6
https://github.com/scummvm/scummvm/commit/fde2db9d4c09d4318d9dbc409044838d456693a6
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add items and give_item debug commands
Changed paths:
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index e162597..377909c 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -36,6 +36,8 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
registerCmd("dump_scripts", WRAP_METHOD(Console, Cmd_DumpScripts));
registerCmd("valid_cmds", WRAP_METHOD(Console, Cmd_ValidCommands));
registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
+ registerCmd("items", WRAP_METHOD(Console, Cmd_Items));
+ registerCmd("give_item", WRAP_METHOD(Console, Cmd_GiveItem));
}
Common::String Console::toAscii(const Common::String &str) {
@@ -163,6 +165,103 @@ bool Console::Cmd_Room(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_Items(int argc, const char **argv) {
+ if (argc != 1) {
+ debugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ Common::List<Item>::const_iterator item;
+
+ for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item)
+ printItem(*item);
+
+ return true;
+}
+
+bool Console::Cmd_GiveItem(int argc, const char **argv) {
+ if (argc != 2) {
+ debugPrintf("Usage: %s <ID | name>\n", argv[0]);
+ return true;
+ }
+
+ Common::List<Item>::iterator item;
+
+ char *end;
+ int id = strtoul(argv[1], &end, 0);
+
+ if (*end != 0) {
+ Common::Array<Item *> matches;
+
+ Common::String searchName(argv[1]);
+ searchName.toUppercase();
+ while (searchName.size() < IDI_WORD_SIZE)
+ searchName += ' ';
+
+ for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item) {
+ Common::String itemName;
+
+ if (item->noun > 0)
+ itemName = _engine->_priNouns[item->noun - 1];
+
+ if (itemName == searchName)
+ matches.push_back(&*item);
+ }
+
+ if (matches.size() == 0) {
+ debugPrintf("Item '%s' not found\n", argv[1]);
+ return true;
+ }
+
+ if (matches.size() > 1) {
+ debugPrintf("Multiple matches found, please use item ID:\n");
+ for (uint i = 0; i < matches.size(); ++i)
+ printItem(*matches[i]);
+ return true;
+ }
+
+ matches[0]->room = IDI_ANY;
+ debugPrintf("OK\n");
+ return true;
+ }
+
+ for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item)
+ if (item->id == id) {
+ item->room = IDI_ANY;
+ debugPrintf("OK\n");
+ return true;
+ }
+
+ debugPrintf("Item %i not found\n", id);
+ return true;
+}
+
+void Console::printItem(const Item &item) {
+ Common::String name, desc, state;
+
+ if (item.noun > 0)
+ name = _engine->_priNouns[item.noun - 1];
+
+ if (item.description > 0) {
+ desc = toAscii(_engine->_messages[item.description - 1]);
+ desc.deleteLastChar();
+ }
+
+ switch (item.state) {
+ case IDI_ITEM_NOT_MOVED:
+ state = "PLACED";
+ break;
+ case IDI_ITEM_DROPPED:
+ state = "DROPPED";
+ break;
+ case IDI_ITEM_DOESNT_MOVE:
+ state = "FIXED";
+ break;
+ }
+
+ debugPrintf("%3d %s %-30s %-10s %-8s (%3d, %3d)\n", item.id, name.c_str(), desc.c_str(), _engine->itemRoomStr(item.room).c_str(), state.c_str(), item.position.x, item.position.y);
+}
+
void Console::printWordMap(const WordMap &wordMap) {
Common::StringArray words;
WordMap::const_iterator verb;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 8af23b9..a1b692d 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -34,6 +34,7 @@ class String;
namespace Adl {
class AdlEngine;
+struct Item;
class Console : public GUI::Debugger {
public:
@@ -47,7 +48,10 @@ private:
bool Cmd_DumpScripts(int argc, const char **argv);
bool Cmd_ValidCommands(int argc, const char **argv);
bool Cmd_Room(int argc, const char **argv);
+ bool Cmd_Items(int argc, const char **argv);
+ bool Cmd_GiveItem(int argc, const char **argv);
+ void printItem(const Item &item);
void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
AdlEngine *_engine;
Commit: 23d4e61260f96cf3aa5104649a3a4f7b72c7df78
https://github.com/scummvm/scummvm/commit/23d4e61260f96cf3aa5104649a3a4f7b72c7df78
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix hires2 item description debug printing
Changed paths:
engines/adl/console.cpp
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 377909c..1a670b7 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -244,7 +244,8 @@ void Console::printItem(const Item &item) {
if (item.description > 0) {
desc = toAscii(_engine->_messages[item.description - 1]);
- desc.deleteLastChar();
+ if (desc.lastChar() == '\r')
+ desc.deleteLastChar();
}
switch (item.state) {
Commit: 1d314b20841d78ebbce2652ec874fb131cf9cf36
https://github.com/scummvm/scummvm/commit/1d314b20841d78ebbce2652ec874fb131cf9cf36
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Allow synonyms in give_item debug command
Changed paths:
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 1a670b7..af16330 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -49,6 +49,22 @@ Common::String Console::toAscii(const Common::String &str) {
return ascii;
}
+Common::String Console::toAppleWord(const Common::String &str) {
+ Common::String apple(str);
+
+ if (apple.size() > IDI_WORD_SIZE)
+ apple.erase(IDI_WORD_SIZE);
+ apple.toUppercase();
+
+ for (uint i = 0; i < apple.size(); ++i)
+ apple.setChar(APPLECHAR(apple[i]), i);
+
+ while (apple.size() < IDI_WORD_SIZE)
+ apple += APPLECHAR(' ');
+
+ return apple;
+}
+
bool Console::Cmd_Verbs(int argc, const char **argv) {
if (argc != 1) {
debugPrintf("Usage: %s\n", argv[0]);
@@ -193,18 +209,17 @@ bool Console::Cmd_GiveItem(int argc, const char **argv) {
if (*end != 0) {
Common::Array<Item *> matches;
- Common::String searchName(argv[1]);
- searchName.toUppercase();
- while (searchName.size() < IDI_WORD_SIZE)
- searchName += ' ';
+ Common::String name = toAppleWord(argv[1]);
- for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item) {
- Common::String itemName;
+ if (!_engine->_nouns.contains(name)) {
+ debugPrintf("Item '%s' not found\n", argv[1]);
+ return true;
+ }
- if (item->noun > 0)
- itemName = _engine->_priNouns[item->noun - 1];
+ byte noun = _engine->_nouns[name];
- if (itemName == searchName)
+ for (item = _engine->_state.items.begin(); item != _engine->_state.items.end(); ++item) {
+ if (item->noun == noun)
matches.push_back(&*item);
}
diff --git a/engines/adl/console.h b/engines/adl/console.h
index a1b692d..ece9cd0 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -41,6 +41,7 @@ public:
Console(AdlEngine *engine);
static Common::String toAscii(const Common::String &str);
+ static Common::String toAppleWord(const Common::String &str);
private:
bool Cmd_Nouns(int argc, const char **argv);
Commit: ff4b9fcd9c50204cf31703d56ec55164f5646ba4
https://github.com/scummvm/scummvm/commit/ff4b9fcd9c50204cf31703d56ec55164f5646ba4
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add 'vars' debug command
Changed paths:
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index af16330..94d0a73 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -38,6 +38,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
registerCmd("room", WRAP_METHOD(Console, Cmd_Room));
registerCmd("items", WRAP_METHOD(Console, Cmd_Items));
registerCmd("give_item", WRAP_METHOD(Console, Cmd_GiveItem));
+ registerCmd("vars", WRAP_METHOD(Console, Cmd_Vars));
}
Common::String Console::toAscii(const Common::String &str) {
@@ -251,6 +252,22 @@ bool Console::Cmd_GiveItem(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_Vars(int argc, const char **argv) {
+ if (argc != 1) {
+ debugPrintf("Usage: %s\n", argv[0]);
+ return true;
+ }
+
+ Common::StringArray vars;
+ for (uint i = 0; i < _engine->_state.vars.size(); ++i)
+ vars.push_back(Common::String::format("%3d: %3d", i, _engine->_state.vars[i]));
+
+ debugPrintf("Variables:\n");
+ debugPrintColumns(vars);
+
+ return true;
+}
+
void Console::printItem(const Item &item) {
Common::String name, desc, state;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index ece9cd0..13f55fc 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -51,6 +51,7 @@ private:
bool Cmd_Room(int argc, const char **argv);
bool Cmd_Items(int argc, const char **argv);
bool Cmd_GiveItem(int argc, const char **argv);
+ bool Cmd_Vars(int argc, const char **argv);
void printItem(const Item &item);
void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
Commit: 1b9d712a8b68f75dcd7c22021b50fff1eeaec155
https://github.com/scummvm/scummvm/commit/1b9d712a8b68f75dcd7c22021b50fff1eeaec155
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add 'var' debug command
Changed paths:
engines/adl/console.cpp
engines/adl/console.h
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 94d0a73..c62d21c 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -39,6 +39,7 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() {
registerCmd("items", WRAP_METHOD(Console, Cmd_Items));
registerCmd("give_item", WRAP_METHOD(Console, Cmd_GiveItem));
registerCmd("vars", WRAP_METHOD(Console, Cmd_Vars));
+ registerCmd("var", WRAP_METHOD(Console, Cmd_Var));
}
Common::String Console::toAscii(const Common::String &str) {
@@ -162,10 +163,10 @@ bool Console::Cmd_Room(int argc, const char **argv) {
return true;
}
- int roomCount = _engine->_state.rooms.size();
- int room = strtoul(argv[1], NULL, 0);
+ uint roomCount = _engine->_state.rooms.size();
+ uint room = strtoul(argv[1], NULL, 0);
if (room < 1 || room > roomCount) {
- debugPrintf("Room %i out of valid range [1, %d]\n", room, roomCount);
+ debugPrintf("Room %u out of valid range [1, %u]\n", room, roomCount);
return true;
}
@@ -177,7 +178,7 @@ bool Console::Cmd_Room(int argc, const char **argv) {
_engine->_display->updateHiResScreen();
}
- debugPrintf("Current room: %d\n", _engine->_state.room);
+ debugPrintf("Current room: %u\n", _engine->_state.room);
return true;
}
@@ -205,7 +206,7 @@ bool Console::Cmd_GiveItem(int argc, const char **argv) {
Common::List<Item>::iterator item;
char *end;
- int id = strtoul(argv[1], &end, 0);
+ uint id = strtoul(argv[1], &end, 0);
if (*end != 0) {
Common::Array<Item *> matches;
@@ -268,6 +269,30 @@ bool Console::Cmd_Vars(int argc, const char **argv) {
return true;
}
+bool Console::Cmd_Var(int argc, const char **argv) {
+ if (argc < 2 || argc > 3) {
+ debugPrintf("Usage: %s <index> [<value>]\n", argv[0]);
+ return true;
+ }
+
+ uint varCount = _engine->_state.vars.size();
+ uint var = strtoul(argv[1], NULL, 0);
+
+ if (var >= varCount) {
+ debugPrintf("Variable %u out of valid range [0, %u]\n", var, varCount - 1);
+ return true;
+ }
+
+ if (argc == 3) {
+ uint value = strtoul(argv[2], NULL, 0);
+ _engine->_state.vars[var] = value;
+ }
+
+ debugPrintf("%3d: %3d\n", var, _engine->_state.vars[var]);
+
+ return true;
+}
+
void Console::printItem(const Item &item) {
Common::String name, desc, state;
diff --git a/engines/adl/console.h b/engines/adl/console.h
index 13f55fc..a8c6adc 100644
--- a/engines/adl/console.h
+++ b/engines/adl/console.h
@@ -52,6 +52,7 @@ private:
bool Cmd_Items(int argc, const char **argv);
bool Cmd_GiveItem(int argc, const char **argv);
bool Cmd_Vars(int argc, const char **argv);
+ bool Cmd_Var(int argc, const char **argv);
void printItem(const Item &item);
void printWordMap(const Common::HashMap<Common::String, uint> &wordMap);
Commit: d6f34eda997ef5ace7078ac6d944ac505bb2a35d
https://github.com/scummvm/scummvm/commit/d6f34eda997ef5ace7078ac6d944ac505bb2a35d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Remove DataBlockPtr::isValid()
Changed paths:
engines/adl/disk.h
engines/adl/hires2.cpp
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 12801ec..4cab81d 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -38,7 +38,6 @@ class DataBlock {
public:
virtual ~DataBlock() { }
- virtual bool isValid() const = 0;
virtual Common::SeekableReadStream *createReadStream() const = 0;
};
@@ -60,10 +59,6 @@ protected:
_filename(filename),
_offset(offset) { }
- bool isValid() const {
- return true;
- }
-
Common::SeekableReadStream *createReadStream() const {
return _files->createReadStream(_filename, _offset);
}
@@ -102,10 +97,6 @@ protected:
_size(size),
_disk(disk) { }
- bool isValid() const {
- return _track != 0 || _sector != 0 || _offset != 0 || _size != 0;
- }
-
Common::SeekableReadStream *createReadStream() const {
return _disk->createReadStream(_track, _sector, _offset, _size);
}
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 4ac8e88..70b98b9 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -42,6 +42,9 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
if (f.eos() || f.err())
error("Error reading DataBlockPtr");
+ if (track == 0 && sector == 0 && offset == 0 && size == 0)
+ return DataBlockPtr();
+
return _disk.getDataBlock(track, sector, offset, size);
}
@@ -70,7 +73,7 @@ void HiRes2Engine::init() {
for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
DataBlockPtr str(readDataBlockPtr(*stream));
- if (str->isValid()) {
+ if (str) {
StreamPtr strStream(str->createReadStream());
_messages.push_back(readString(*strStream, 0xff));
} else {
Commit: f275add1e53dbbc19de8c0fd6f181456a07bfa92
https://github.com/scummvm/scummvm/commit/f275add1e53dbbc19de8c0fd6f181456a07bfa92
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Use pointer for hires2 disk image
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 51ea4ec..8fcb45a 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -30,11 +30,13 @@ namespace Adl {
AdlEngine_v2::~AdlEngine_v2() {
delete _random;
+ delete _disk;
}
AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
AdlEngine(syst, gd),
- _linesPrinted(0) {
+ _linesPrinted(0),
+ _disk(nullptr) {
_random = new Common::RandomSource("adl");
}
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 40bd40a..66dbcf3 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -71,6 +71,7 @@ protected:
} _strings_v2;
uint _linesPrinted;
+ DiskImage *_disk;
private:
int askForSlot(const Common::String &question);
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 70b98b9..4d18b2e 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -45,11 +45,11 @@ DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
if (track == 0 && sector == 0 && offset == 0 && size == 0)
return DataBlockPtr();
- return _disk.getDataBlock(track, sector, offset, size);
+ return _disk->getDataBlock(track, sector, offset, size);
}
void HiRes2Engine::runIntro() const {
- StreamPtr stream(_disk.createReadStream(0x00, 0xd, 0x17, 1));
+ StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
_display->setMode(DISPLAY_MODE_TEXT);
@@ -65,10 +65,11 @@ void HiRes2Engine::runIntro() const {
void HiRes2Engine::init() {
_graphics = new Graphics_v2(*_display);
- if (!_disk.open(IDS_HR2_DISK_IMAGE))
+ _disk = new DiskImage_DSK();
+ if (!_disk->open(IDS_HR2_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
- StreamPtr stream(_disk.createReadStream(0x1f, 0x2, 0x04, 4));
+ StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x04, 4));
for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
DataBlockPtr str(readDataBlockPtr(*stream));
@@ -82,17 +83,17 @@ void HiRes2Engine::init() {
}
// Read parser messages
- stream.reset(_disk.createReadStream(0x1a, 0x1));
+ stream.reset(_disk->createReadStream(0x1a, 0x1));
_strings.verbError = readStringAt(*stream, 0x4f);
_strings.nounError = readStringAt(*stream, 0x8e);
_strings.enterCommand = readStringAt(*stream, 0xbc);
// Read time string
- stream.reset(_disk.createReadStream(0x19, 0x7, 0xd7));
+ stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
_strings_v2.time = readString(*stream, 0xff);
// Read opcode strings
- stream.reset(_disk.createReadStream(0x1a, 0x6, 0x00, 2));
+ stream.reset(_disk->createReadStream(0x1a, 0x6, 0x00, 2));
_strings_v2.saveInsert = readStringAt(*stream, 0x5f);
_strings_v2.saveReplace = readStringAt(*stream, 0xe5);
_strings_v2.restoreInsert = readStringAt(*stream, 0x132);
@@ -107,7 +108,7 @@ void HiRes2Engine::init() {
_messageIds.thanksForPlaying = IDI_HR2_MSG_THANKS_FOR_PLAYING;
// Load global picture data
- stream.reset(_disk.createReadStream(0x19, 0xa, 0x80, 0));
+ stream.reset(_disk->createReadStream(0x19, 0xa, 0x80, 0));
byte picNr;
while ((picNr = stream->readByte()) != 0xff) {
if (stream->eos() || stream->err())
@@ -117,21 +118,21 @@ void HiRes2Engine::init() {
}
// Load item picture data
- stream.reset(_disk.createReadStream(0x1e, 0x9, 0x05));
+ stream.reset(_disk->createReadStream(0x1e, 0x9, 0x05));
for (uint i = 0; i < IDI_HR2_NUM_ITEM_PICS; ++i) {
stream->readByte(); // number
_itemPics.push_back(readDataBlockPtr(*stream));
}
// Load commands from executable
- stream.reset(_disk.createReadStream(0x1d, 0x7, 0x00, 4));
+ stream.reset(_disk->createReadStream(0x1d, 0x7, 0x00, 4));
readCommands(*stream, _roomCommands);
- stream.reset(_disk.createReadStream(0x1f, 0x7, 0x00, 2));
+ stream.reset(_disk->createReadStream(0x1f, 0x7, 0x00, 2));
readCommands(*stream, _globalCommands);
// Load dropped item offsets
- stream.reset(_disk.createReadStream(0x1b, 0x4, 0x15));
+ stream.reset(_disk->createReadStream(0x1b, 0x4, 0x15));
for (uint i = 0; i < IDI_HR2_NUM_ITEM_OFFSETS; ++i) {
Common::Point p;
p.x = stream->readByte();
@@ -140,11 +141,11 @@ void HiRes2Engine::init() {
}
// Load verbs
- stream.reset(_disk.createReadStream(0x19, 0x0, 0x00, 3));
+ stream.reset(_disk->createReadStream(0x19, 0x0, 0x00, 3));
loadWords(*stream, _verbs, _priVerbs);
// Load nouns
- stream.reset(_disk.createReadStream(0x22, 0x2, 0x00, 7));
+ stream.reset(_disk->createReadStream(0x22, 0x2, 0x00, 7));
loadWords(*stream, _nouns, _priNouns);
}
@@ -152,7 +153,7 @@ void HiRes2Engine::initState() {
_state.vars.clear();
_state.vars.resize(IDI_HR2_NUM_VARS);
- StreamPtr stream(_disk.createReadStream(0x21, 0x5, 0x0e, 7));
+ StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
_state.rooms.clear();
for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
@@ -167,7 +168,7 @@ void HiRes2Engine::initState() {
_state.rooms.push_back(room);
}
- stream.reset(_disk.createReadStream(0x21, 0x0, 0x00, 2));
+ stream.reset(_disk->createReadStream(0x21, 0x0, 0x00, 2));
_state.items.clear();
byte id;
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index c99c0b0..b8212e0 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -66,7 +66,6 @@ private:
DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
- DiskImage_DSK _disk;
Common::Array<DataBlockPtr> _itemPics;
};
Commit: 4ee8cf4f9ea79c9bfcab00b39f26675fc0db2588
https://github.com/scummvm/scummvm/commit/4ee8cf4f9ea79c9bfcab00b39f26675fc0db2588
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Move some hires2 functionality into ADL_v2
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 8fcb45a..8b7a623 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -25,6 +25,7 @@
#include "adl/adl_v2.h"
#include "adl/display.h"
+#include "adl/graphics.h"
namespace Adl {
@@ -194,6 +195,61 @@ void AdlEngine_v2::printString(const Common::String &str) {
_display->updateTextScreen();
}
+void AdlEngine_v2::drawItem(const Item &item, const Common::Point &pos) const {
+ StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
+ stream->readByte(); // Skip clear opcode
+ _graphics->drawPic(*stream, pos);
+}
+
+void AdlEngine_v2::loadRoom(byte roomNr) {
+ Room &room = getRoom(roomNr);
+ StreamPtr stream(room.data->createReadStream());
+
+ uint16 descOffset = stream->readUint16LE();
+ uint16 commandOffset = stream->readUint16LE();
+
+ _roomData.pictures.clear();
+ // There's no picture count. The original engine always checks at most
+ // five pictures. We use the description offset to bound our search.
+ uint16 picCount = (descOffset - 4) / 5;
+
+ for (uint i = 0; i < picCount; ++i) {
+ byte nr = stream->readByte();
+ _roomData.pictures[nr] = readDataBlockPtr(*stream);
+ }
+
+ _roomData.description = readStringAt(*stream, descOffset, 0xff);
+
+ _roomData.commands.clear();
+ if (commandOffset != 0) {
+ stream->seek(commandOffset);
+ readCommands(*stream, _roomData.commands);
+ }
+}
+
+void AdlEngine_v2::showRoom() {
+ drawPic(getCurRoom().curPicture, Common::Point());
+ drawItems();
+ _display->updateHiResScreen();
+ printString(_roomData.description);
+ _linesPrinted = 0;
+}
+
+DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
+ byte track = f.readByte();
+ byte sector = f.readByte();
+ byte offset = f.readByte();
+ byte size = f.readByte();
+
+ if (f.eos() || f.err())
+ error("Error reading DataBlockPtr");
+
+ if (track == 0 && sector == 0 && offset == 0 && size == 0)
+ return DataBlockPtr();
+
+ return _disk->getDataBlock(track, sector, offset, size);
+}
+
int AdlEngine_v2::o2_isFirstTime(ScriptEnv &e) {
OP_DEBUG_0("\t&& IS_FIRST_TIME()");
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 66dbcf3..c8dc189 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -47,6 +47,11 @@ protected:
byte roomArg(byte room) const;
void advanceClock();
void printString(const Common::String &str);
+ void drawItem(const Item &item, const Common::Point &pos) const;
+ void loadRoom(byte roomNr);
+ void showRoom();
+
+ DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
void checkTextOverflow(char c);
@@ -72,6 +77,7 @@ protected:
uint _linesPrinted;
DiskImage *_disk;
+ Common::Array<DataBlockPtr> _itemPics;
private:
int askForSlot(const Common::String &question);
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 4d18b2e..a1303b6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -33,21 +33,6 @@
namespace Adl {
-DataBlockPtr HiRes2Engine::readDataBlockPtr(Common::ReadStream &f) const {
- byte track = f.readByte();
- byte sector = f.readByte();
- byte offset = f.readByte();
- byte size = f.readByte();
-
- if (f.eos() || f.err())
- error("Error reading DataBlockPtr");
-
- if (track == 0 && sector == 0 && offset == 0 && size == 0)
- return DataBlockPtr();
-
- return _disk->getDataBlock(track, sector, offset, size);
-}
-
void HiRes2Engine::runIntro() const {
StreamPtr stream(_disk->createReadStream(0x00, 0xd, 0x17, 1));
@@ -202,46 +187,6 @@ void HiRes2Engine::restartGame() {
initState();
}
-void HiRes2Engine::drawItem(const Item &item, const Common::Point &pos) const {
- StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
- stream->readByte(); // Skip clear opcode
- _graphics->drawPic(*stream, pos);
-}
-
-void HiRes2Engine::loadRoom(byte roomNr) {
- Room &room = getRoom(roomNr);
- StreamPtr stream(room.data->createReadStream());
-
- uint16 descOffset = stream->readUint16LE();
- uint16 commandOffset = stream->readUint16LE();
-
- _roomData.pictures.clear();
- // There's no picture count. The original engine always checks at most
- // five pictures. We use the description offset to bound our search.
- uint16 picCount = (descOffset - 4) / 5;
-
- for (uint i = 0; i < picCount; ++i) {
- byte nr = stream->readByte();
- _roomData.pictures[nr] = readDataBlockPtr(*stream);
- }
-
- _roomData.description = readStringAt(*stream, descOffset, 0xff);
-
- _roomData.commands.clear();
- if (commandOffset != 0) {
- stream->seek(commandOffset);
- readCommands(*stream, _roomData.commands);
- }
-}
-
-void HiRes2Engine::showRoom() {
- drawPic(getCurRoom().curPicture, Common::Point());
- drawItems();
- _display->updateHiResScreen();
- printString(_roomData.description);
- _linesPrinted = 0;
-}
-
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes2Engine(syst, gd);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index b8212e0..f2ffbf8 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -60,13 +60,6 @@ private:
void init();
void initState();
void restartGame();
- void drawItem(const Item &item, const Common::Point &pos) const;
- void loadRoom(byte roomNr);
- void showRoom();
-
- DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
-
- Common::Array<DataBlockPtr> _itemPics;
};
} // End of namespace Adl
Commit: 97168fa200e6e7a437b9e68e6ebc1438c520a4f5
https://github.com/scummvm/scummvm/commit/97168fa200e6e7a437b9e68e6ebc1438c520a4f5
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load line feeds string
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 1b6bf6a..64e625d 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -552,10 +552,10 @@ Common::Error AdlEngine::run() {
} else {
runIntro();
initState();
+ _display->printAsciiString(_strings.lineFeeds);
}
_display->setMode(DISPLAY_MODE_MIXED);
- _display->printAsciiString("\r\r\r\r\r");
while (1) {
uint verb = 0, noun = 0;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 18b57ed..831bf38 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -339,6 +339,7 @@ protected:
Common::String nounError;
Common::String playAgain;
Common::String pressReturn;
+ Common::String lineFeeds;
} _strings;
struct {
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index e0f7574..0765625 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -156,6 +156,7 @@ void HiRes1Engine::init() {
_strings.nounError = readStringAt(*stream, IDI_HR1_OFS_STR_NOUN_ERROR);
_strings.playAgain = readStringAt(*stream, IDI_HR1_OFS_STR_PLAY_AGAIN);
_strings.pressReturn = readStringAt(*stream, IDI_HR1_OFS_STR_PRESS_RETURN);
+ _strings.lineFeeds = readStringAt(*stream, IDI_HR1_OFS_STR_LINE_FEEDS);
// Set message IDs
_messageIds.cantGoThere = IDI_HR1_MSG_CANT_GO_THERE;
@@ -258,10 +259,9 @@ void HiRes1Engine::initState() {
}
void HiRes1Engine::restartGame() {
- initState();
_display->printString(_strings.pressReturn);
- inputString(); // Missing in the original
- _display->printAsciiString("\r\r\r\r\r");
+ initState();
+ _display->printAsciiString(_strings.lineFeeds);
}
void HiRes1Engine::printString(const Common::String &str) {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 02eb75a..251d079 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -65,6 +65,7 @@ namespace Adl {
#define IDI_HR1_OFS_STR_DONT_UNDERSTAND 0x6c51
#define IDI_HR1_OFS_STR_GETTING_DARK 0x6c7c
#define IDI_HR1_OFS_STR_PRESS_RETURN 0x5f68
+#define IDI_HR1_OFS_STR_LINE_FEEDS 0x59d4
#define IDI_HR1_OFS_PD_TEXT_0 0x005d
#define IDI_HR1_OFS_PD_TEXT_1 0x012b
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index a1303b6..5a4e0e5 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -77,6 +77,10 @@ void HiRes2Engine::init() {
stream.reset(_disk->createReadStream(0x19, 0x7, 0xd7));
_strings_v2.time = readString(*stream, 0xff);
+ // Read line feeds
+ stream.reset(_disk->createReadStream(0x19, 0xb, 0xf8, 1));
+ _strings.lineFeeds = readString(*stream);
+
// Read opcode strings
stream.reset(_disk->createReadStream(0x1a, 0x6, 0x00, 2));
_strings_v2.saveInsert = readStringAt(*stream, 0x5f);
@@ -184,7 +188,9 @@ void HiRes2Engine::initState() {
}
void HiRes2Engine::restartGame() {
+ _display->printString(_strings.pressReturn);
initState();
+ _display->printAsciiString(_strings.lineFeeds);
}
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
Commit: 09146fba6eaad18a221990fd4362c93da34aaafb
https://github.com/scummvm/scummvm/commit/09146fba6eaad18a221990fd4362c93da34aaafb
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Move restartGame() into opcode
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires2.cpp
engines/adl/hires2.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 64e625d..ba51b45 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -1070,7 +1070,9 @@ int AdlEngine::o1_restart(ScriptEnv &e) {
_isRestarting = true;
_display->clear(0x00);
_display->updateHiResScreen();
- restartGame();
+ _display->printString(_strings.pressReturn);
+ initState();
+ _display->printAsciiString(_strings.lineFeeds);
return -1;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 831bf38..72353e4 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -359,7 +359,6 @@ private:
virtual void runIntro() const { }
virtual void init() = 0;
virtual void initState() = 0;
- virtual void restartGame() = 0;
virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
virtual void loadRoom(byte roomNr) = 0;
virtual void showRoom() = 0;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 5a4e0e5..943d7a6 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -187,12 +187,6 @@ void HiRes2Engine::initState() {
}
}
-void HiRes2Engine::restartGame() {
- _display->printString(_strings.pressReturn);
- initState();
- _display->printAsciiString(_strings.lineFeeds);
-}
-
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes2Engine(syst, gd);
}
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index f2ffbf8..a882b68 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -59,7 +59,6 @@ private:
void runIntro() const;
void init();
void initState();
- void restartGame();
};
} // End of namespace Adl
Commit: b4a82370cd21a0ed14c8bd6a44e22c47de39aeea
https://github.com/scummvm/scummvm/commit/b4a82370cd21a0ed14c8bd6a44e22c47de39aeea
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Partially fix hires2 restarting
Changed paths:
engines/adl/hires1.cpp
engines/adl/hires2.cpp
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 0765625..1d7e50e 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -207,17 +207,12 @@ void HiRes1Engine::init() {
}
void HiRes1Engine::initState() {
- _state.room = 1;
- _state.moves = 1;
- _state.isDark = false;
-
- _state.vars.clear();
+ _state = State();
_state.vars.resize(IDI_HR1_NUM_VARS);
StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
// Load room data from executable
- _state.rooms.clear();
_roomDesc.clear();
stream->seek(IDI_HR1_OFS_ROOMS);
for (uint i = 0; i < IDI_HR1_NUM_ROOMS; ++i) {
@@ -232,7 +227,6 @@ void HiRes1Engine::initState() {
}
// Load item data from executable
- _state.items.clear();
stream->seek(IDI_HR1_OFS_ITEMS);
byte id;
while ((id = stream->readByte()) != 0xff) {
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 943d7a6..9a928ff 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -139,12 +139,11 @@ void HiRes2Engine::init() {
}
void HiRes2Engine::initState() {
- _state.vars.clear();
+ _state = State();
_state.vars.resize(IDI_HR2_NUM_VARS);
StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
- _state.rooms.clear();
for (uint i = 0; i < IDI_HR2_NUM_ROOMS; ++i) {
Room room;
stream->readByte(); // number
@@ -159,7 +158,6 @@ void HiRes2Engine::initState() {
stream.reset(_disk->createReadStream(0x21, 0x0, 0x00, 2));
- _state.items.clear();
byte id;
while ((id = stream->readByte()) != 0xff) {
Item item = { };
Commit: adecc106742baed4fbe5752c4319fa8e855c60e1
https://github.com/scummvm/scummvm/commit/adecc106742baed4fbe5752c4319fa8e855c60e1
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Reset "lines printed" counter on restart
Changed paths:
engines/adl/hires2.cpp
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 9a928ff..a0fa5a0 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -139,6 +139,8 @@ void HiRes2Engine::init() {
}
void HiRes2Engine::initState() {
+ _linesPrinted = 0;
+
_state = State();
_state.vars.resize(IDI_HR2_NUM_VARS);
Commit: 83d75c2f4c74e8e62b1cacc08a54678394daf22b
https://github.com/scummvm/scummvm/commit/83d75c2f4c74e8e62b1cacc08a54678394daf22b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Clean-up
Changed paths:
engines/adl/adl.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 72353e4..d81afe2 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -382,8 +382,6 @@ private:
bool _canSaveNow, _canRestoreNow;
};
-AdlEngine *HiRes1Engine__create(OSystem *syst, const AdlGameDescription *gd);
-
} // End of namespace Adl
#endif
Commit: ed0653e3939a8a9dbfac873a23c40da2c00ab81b
https://github.com/scummvm/scummvm/commit/ed0653e3939a8a9dbfac873a23c40da2c00ab81b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Update save game format for hires2
Note: this breaks loading earlier savegames
Changed paths:
engines/adl/adl.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index ba51b45..c059258 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -658,6 +658,8 @@ Common::Error AdlEngine::loadGameState(int slot) {
_state.room = inFile->readByte();
_state.moves = inFile->readByte();
_state.isDark = inFile->readByte();
+ _state.time.hours = inFile->readByte();
+ _state.time.minutes = inFile->readByte();
uint32 size = inFile->readUint32BE();
if (size != _state.rooms.size())
@@ -666,6 +668,7 @@ Common::Error AdlEngine::loadGameState(int slot) {
for (uint i = 0; i < size; ++i) {
_state.rooms[i].picture = inFile->readByte();
_state.rooms[i].curPicture = inFile->readByte();
+ _state.rooms[i].isFirstTime = inFile->readByte();
}
size = inFile->readUint32BE();
@@ -744,11 +747,14 @@ Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
outFile->writeByte(_state.room);
outFile->writeByte(_state.moves);
outFile->writeByte(_state.isDark);
+ outFile->writeByte(_state.time.hours);
+ outFile->writeByte(_state.time.minutes);
outFile->writeUint32BE(_state.rooms.size());
for (uint i = 0; i < _state.rooms.size(); ++i) {
outFile->writeByte(_state.rooms[i].picture);
outFile->writeByte(_state.rooms[i].curPicture);
+ outFile->writeByte(_state.rooms[i].isFirstTime);
}
outFile->writeUint32BE(_state.items.size());
Commit: bc0fc246f047415837d7c7bccf82918303fcccaf
https://github.com/scummvm/scummvm/commit/bc0fc246f047415837d7c7bccf82918303fcccaf
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires2 screen update routine
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires1.cpp
engines/adl/hires1.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c059258..50e7af4 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -379,10 +379,6 @@ void AdlEngine::setupOpcodeTables() {
Opcode(o1_setRoomPic);
}
-bool AdlEngine::matchesCurrentPic(byte pic) const {
- return pic == getCurRoom().curPicture;
-}
-
byte AdlEngine::roomArg(byte room) const {
return room;
}
@@ -399,36 +395,6 @@ void AdlEngine::drawPic(byte pic, Common::Point pos) const {
_graphics->drawPic(*_pictures[pic]->createReadStream(), pos);
}
-void AdlEngine::drawItems() const {
- Common::List<Item>::const_iterator item;
-
- uint dropped = 0;
-
- for (item = _state.items.begin(); item != _state.items.end(); ++item) {
- // Skip items not in this room
- if (item->room != _state.room)
- continue;
-
- if (item->state == IDI_ITEM_DROPPED) {
- // Draw dropped item if in normal view
- if (getCurRoom().picture == getCurRoom().curPicture) {
- drawItem(*item, _itemOffsets[dropped]);
- ++dropped;
- }
- } else {
- // Draw fixed item if current view is in the pic list
- Common::Array<byte>::const_iterator pic;
-
- for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (matchesCurrentPic(*pic)) {
- drawItem(*item, item->position);
- break;
- }
- }
- }
- }
-}
-
void AdlEngine::bell(uint count) const {
_speaker->bell(count);
}
@@ -508,7 +474,7 @@ void AdlEngine::takeItem(byte noun) {
Common::Array<byte>::const_iterator pic;
for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
- if (matchesCurrentPic(*pic)) {
+ if (*pic == getCurRoom().curPicture) {
item->room = IDI_ANY;
item->state = IDI_ITEM_DROPPED;
return;
@@ -566,9 +532,6 @@ Common::Error AdlEngine::run() {
// restoring in-game brings us to the same game state.
// (Also see comment below.)
if (!_isRestoring) {
- clearScreen();
- // FIXME: Should only be called when room changes
- loadRoom(_state.room);
showRoom();
_canSaveNow = _canRestoreNow = true;
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index d81afe2..1b6d02b 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -150,6 +150,7 @@ struct Item {
int state;
byte description;
Common::Array<byte> roomPictures;
+ bool isOnScreen;
};
struct Time {
@@ -238,7 +239,6 @@ protected:
virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
virtual void setupOpcodeTables();
- virtual bool matchesCurrentPic(byte pic) const;
virtual byte roomArg(byte room) const;
virtual void advanceClock() { }
@@ -276,7 +276,6 @@ protected:
// Graphics
void clearScreen() const;
void drawPic(byte pic, Common::Point pos = Common::Point()) const;
- void drawItems() const;
// Sound
void bell(uint count = 1) const;
@@ -290,7 +289,7 @@ protected:
Item &getItem(uint i);
byte getVar(uint i) const;
void setVar(uint i, byte value);
- void takeItem(byte noun);
+ virtual void takeItem(byte noun);
void dropItem(byte noun);
bool matchCommand(ScriptEnv &env) const;
void doActions(ScriptEnv &env);
@@ -359,7 +358,8 @@ private:
virtual void runIntro() const { }
virtual void init() = 0;
virtual void initState() = 0;
- virtual void drawItem(const Item &item, const Common::Point &pos) const = 0;
+ virtual void drawItems() = 0;
+ virtual void drawItem(Item &item, const Common::Point &pos) = 0;
virtual void loadRoom(byte roomNr) = 0;
virtual void showRoom() = 0;
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 8b7a623..fd316c0 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -37,7 +37,11 @@ AdlEngine_v2::~AdlEngine_v2() {
AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) :
AdlEngine(syst, gd),
_linesPrinted(0),
- _disk(nullptr) {
+ _disk(nullptr),
+ _itemRemoved(false),
+ _roomOnScreen(0),
+ _picOnScreen(0),
+ _itemsOnScreen(0) {
_random = new Common::RandomSource("adl");
}
@@ -110,10 +114,6 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o2_initDisk);
}
-bool AdlEngine_v2::matchesCurrentPic(byte pic) const {
- return pic == getCurRoom().curPicture || pic == IDI_ANY;
-}
-
byte AdlEngine_v2::roomArg(byte room) const {
if (room == IDI_CUR_ROOM)
return _state.room;
@@ -195,7 +195,8 @@ void AdlEngine_v2::printString(const Common::String &str) {
_display->updateTextScreen();
}
-void AdlEngine_v2::drawItem(const Item &item, const Common::Point &pos) const {
+void AdlEngine_v2::drawItem(Item &item, const Common::Point &pos) {
+ item.isOnScreen = true;
StreamPtr stream(_itemPics[item.picture - 1]->createReadStream());
stream->readByte(); // Skip clear opcode
_graphics->drawPic(*stream, pos);
@@ -228,13 +229,103 @@ void AdlEngine_v2::loadRoom(byte roomNr) {
}
void AdlEngine_v2::showRoom() {
- drawPic(getCurRoom().curPicture, Common::Point());
- drawItems();
+ bool redrawPic = false;
+
+ if (_state.room != _roomOnScreen) {
+ loadRoom(_state.room);
+ clearScreen();
+
+ if (!_state.isDark)
+ redrawPic = true;
+ } else {
+ if (getCurRoom().curPicture != _picOnScreen || _itemRemoved)
+ redrawPic = true;
+ }
+
+ if (redrawPic) {
+ _roomOnScreen = _state.room;
+ _picOnScreen = getCurRoom().curPicture;
+
+ drawPic(getCurRoom().curPicture);
+ _itemRemoved = false;
+ _itemsOnScreen = 0;
+
+ Common::List<Item>::iterator item;
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ item->isOnScreen = false;
+ }
+
+ if (!_state.isDark)
+ drawItems();
+
_display->updateHiResScreen();
printString(_roomData.description);
+
+ // FIXME: move to main loop?
_linesPrinted = 0;
}
+void AdlEngine_v2::takeItem(byte noun) {
+ Common::List<Item>::iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ if (item->noun != noun || item->room != _state.room)
+ continue;
+
+ if (item->state == IDI_ITEM_DOESNT_MOVE) {
+ printMessage(_messageIds.itemDoesntMove);
+ return;
+ }
+
+ if (item->state == IDI_ITEM_DROPPED) {
+ item->room = IDI_ANY;
+ _itemRemoved = true;
+ return;
+ }
+
+ Common::Array<byte>::const_iterator pic;
+ for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+ if (*pic == getCurRoom().curPicture || *pic == IDI_ANY) {
+ item->room = IDI_ANY;
+ _itemRemoved = true;
+ item->state = IDI_ITEM_DROPPED;
+ return;
+ }
+ }
+ }
+
+ printMessage(_messageIds.itemNotHere);
+}
+
+void AdlEngine_v2::drawItems() {
+ Common::List<Item>::iterator item;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ // Skip items not in this room
+ if (item->room != _state.room)
+ continue;
+
+ if (item->isOnScreen)
+ continue;
+
+ if (item->state == IDI_ITEM_DROPPED) {
+ // Draw dropped item if in normal view
+ if (getCurRoom().picture == getCurRoom().curPicture)
+ drawItem(*item, _itemOffsets[_itemsOnScreen++]);
+ } else {
+ // Draw fixed item if current view is in the pic list
+ Common::Array<byte>::const_iterator pic;
+
+ for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+ if (*pic == getCurRoom().curPicture || *pic == IDI_ANY) {
+ drawItem(*item, item->position);
+ break;
+ }
+ }
+ }
+ }
+}
+
DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
byte track = f.readByte();
byte sector = f.readByte();
@@ -304,6 +395,9 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
Item &item = getItem(e.arg(1));
+ if (item.room == _roomOnScreen)
+ _picOnScreen = 0;
+
// Set items that move from inventory to a room to state "dropped"
if (item.room == IDI_ANY && room != IDI_VOID_ROOM)
item.state = IDI_ITEM_DROPPED;
@@ -316,6 +410,10 @@ int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)).c_str(), roomStr(e.arg(2)).c_str());
byte room1 = roomArg(e.arg(1));
+
+ if (room1 == _state.room)
+ _picOnScreen = 0;
+
byte room2 = roomArg(e.arg(2));
Common::List<Item>::iterator item;
@@ -358,6 +456,8 @@ int AdlEngine_v2::o2_restore(ScriptEnv &e) {
_display->printString(_strings_v2.restoreReplace);
inputString();
+ _picOnScreen = 0;
+ _roomOnScreen = 0;
return 0;
}
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index c8dc189..46a8813 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -43,13 +43,14 @@ protected:
// AdlEngine
virtual void setupOpcodeTables();
- bool matchesCurrentPic(byte pic) const;
byte roomArg(byte room) const;
void advanceClock();
void printString(const Common::String &str);
- void drawItem(const Item &item, const Common::Point &pos) const;
+ void drawItems();
+ void drawItem(Item &item, const Common::Point &pos);
void loadRoom(byte roomNr);
void showRoom();
+ void takeItem(byte noun);
DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
@@ -78,6 +79,8 @@ protected:
uint _linesPrinted;
DiskImage *_disk;
Common::Array<DataBlockPtr> _itemPics;
+ bool _itemRemoved;
+ byte _roomOnScreen, _picOnScreen, _itemsOnScreen;
private:
int askForSlot(const Common::String &question);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 1d7e50e..cca2fe4 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -289,7 +289,35 @@ void HiRes1Engine::printMessage(uint idx) {
printString(msg);
}
-void HiRes1Engine::drawItem(const Item &item, const Common::Point &pos) const {
+void HiRes1Engine::drawItems() {
+ Common::List<Item>::iterator item;
+
+ uint dropped = 0;
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item) {
+ // Skip items not in this room
+ if (item->room != _state.room)
+ continue;
+
+ if (item->state == IDI_ITEM_DROPPED) {
+ // Draw dropped item if in normal view
+ if (getCurRoom().picture == getCurRoom().curPicture)
+ drawItem(*item, _itemOffsets[dropped++]);
+ } else {
+ // Draw fixed item if current view is in the pic list
+ Common::Array<byte>::const_iterator pic;
+
+ for (pic = item->roomPictures.begin(); pic != item->roomPictures.end(); ++pic) {
+ if (*pic == getCurRoom().curPicture) {
+ drawItem(*item, item->position);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void HiRes1Engine::drawItem(Item &item, const Common::Point &pos) {
if (item.isLineArt) {
StreamPtr stream(_corners[item.picture - 1]->createReadStream());
static_cast<Graphics_v1 *>(_graphics)->drawCorners(*stream, pos);
@@ -302,6 +330,9 @@ void HiRes1Engine::loadRoom(byte roomNr) {
}
void HiRes1Engine::showRoom() {
+ clearScreen();
+ loadRoom(_state.room);
+
if (!_state.isDark) {
drawPic(getCurRoom().curPicture);
drawItems();
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 251d079..8dc7081 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -106,7 +106,8 @@ private:
void restartGame();
void printString(const Common::String &str);
void printMessage(uint idx);
- void drawItem(const Item &item, const Common::Point &pos) const;
+ void drawItems();
+ void drawItem(Item &item, const Common::Point &pos);
void loadRoom(byte roomNr);
void showRoom();
Commit: d361f2e4b09fee1b36c4c3c4c8715497990e6e26
https://github.com/scummvm/scummvm/commit/d361f2e4b09fee1b36c4c3c4c8715497990e6e26
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add (experimental) support for NIB files
Changed paths:
engines/adl/disk.cpp
engines/adl/disk.h
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 22a7d7a..1ec1218 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -63,6 +63,159 @@ bool DiskImage_DSK::open(const Common::String &filename) {
return true;
}
+const DataBlockPtr DiskImage_NIB::getDataBlock(uint track, uint sector, uint offset, uint size) const {
+ return Common::SharedPtr<DiskImage::DataBlock>(new DiskImage::DataBlock(this, track, sector, offset, size));
+}
+
+Common::SeekableReadStream *DiskImage_NIB::createReadStream(uint track, uint sector, uint offset, uint size) const {
+ _memStream->seek((track * _sectorsPerTrack + sector) * _bytesPerSector + offset);
+ Common::SeekableReadStream *stream = _memStream->readStream(size * _bytesPerSector + _bytesPerSector - offset);
+
+ if (_memStream->eos() || _memStream->err())
+ error("Error reading NIB image");
+
+ return stream;
+}
+
+// 4-and-4 encoding (odd-even)
+static uint8 read44(Common::SeekableReadStream *f) {
+ // 1s in the other fields, so we can just AND
+ uint8 ret = f->readByte();
+ return ((ret << 1) | 1) & f->readByte();
+}
+
+bool DiskImage_NIB::open(const Common::String &filename) {
+ assert(!_f->isOpen());
+
+ if (!_f->open(filename))
+ return false;
+
+ uint filesize = _f->size();
+ switch (filesize) {
+ case 232960:
+ _tracks = 35;
+ _sectorsPerTrack = 13;
+ _bytesPerSector = 256;
+ break;
+ default:
+ error("Unrecognized NIB image '%s' of size %d bytes", filename.c_str(), filesize);
+ }
+
+ // starting at 0xaa, 32 is invalid (see below)
+ const byte c_5and3_lookup[] = { 32, 0, 32, 1, 2, 3, 32, 32, 32, 32, 32, 4, 5, 6, 32, 32, 7, 8, 32, 9, 10, 11, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 12, 13, 32, 32, 14, 15, 32, 16, 17, 18, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 19, 20, 32, 21, 22, 23, 32, 32, 32, 32, 32, 24, 25, 26, 32, 32, 27, 28, 32, 29, 30, 31 };
+
+ uint32 diskSize = _tracks * _sectorsPerTrack * _bytesPerSector;
+ byte *diskImage = (byte *)calloc(diskSize, 1);
+ _memStream = new Common::MemoryReadStream(diskImage, diskSize, DisposeAfterUse::YES);
+
+ bool sawAddress = false;
+ uint8 volNo, track, sector;
+
+ while (_f->pos() < _f->size()) {
+ // Read until we find two sync bytes.
+ if (_f->readByte() != 0xd5 || _f->readByte() != 0xaa)
+ continue;
+
+ byte prologue = _f->readByte();
+
+ if (sawAddress && prologue == 0xb5) {
+ warning("NIB: data for %02x/%02x/%02x missing", volNo, track, sector);
+ sawAddress = false;
+ }
+
+ if (!sawAddress) {
+ sawAddress = true;
+
+ // We should always find the address field first.
+ if (prologue != 0xb5) {
+ // Accept a DOS 3.3(?) header at the start.
+ if (_f->pos() == 3 || prologue == 0x96) {
+ // But skip it.
+ _f->skip(20);
+ sawAddress = false;
+ continue;
+ } else {
+ error("unknown NIB field prologue %02x", prologue);
+ }
+ }
+
+ volNo = read44(_f);
+ track = read44(_f);
+ sector = read44(_f);
+ uint8 checksum = read44(_f);
+ if ((volNo ^ track ^ sector) != checksum)
+ error("invalid NIB checksum");
+
+ // FIXME: This is a hires0/hires2-specific hack.
+ if (sector == 1)
+ sector = 2;
+ else if (sector == 2)
+ sector = 1;
+
+ // Epilogue is de/aa plus a gap, but we don't care.
+ } else {
+ sawAddress = false;
+
+ // We should always find the data field after an address field.
+ // TODO: we ignore volNo?
+ byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+
+ // 5-and-3 uses 410 on-disk bytes, decoding to just over 256 bytes
+ byte inbuffer[410];
+ _f->read(inbuffer, 410);
+
+ bool truncated = false;
+ byte oldVal = 0;
+ for (uint n = 0; n < 410; ++n) {
+ // expand
+ assert(inbuffer[n] >= 0xaa); // corrupt file (TODO: assert?)
+ if (inbuffer[n] == 0xd5) {
+ // Early end of block.
+ truncated = true;
+ _f->seek(-(410 - n), SEEK_CUR);
+ warning("NIB: early end of block @ 0x%x (%x, %x)", _f->pos(), track, sector);
+ break;
+ }
+ byte val = c_5and3_lookup[inbuffer[n] - 0xaa];
+ if (val == 0x20) {
+ // Badly-encoded nibbles, stop trying to decode here.
+ truncated = true;
+ warning("NIB: bad nibble %02x @ 0x%x (%x, %x)", inbuffer[n], _f->pos(), track, sector);
+ _f->seek(-(410 - n), SEEK_CUR);
+ break;
+ }
+ // undo checksum
+ oldVal = val ^ oldVal;
+ inbuffer[n] = oldVal;
+ }
+ if (!truncated) {
+ byte checksum = _f->readByte();
+ if (checksum < 0xaa || oldVal != c_5and3_lookup[checksum - 0xaa])
+ warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
+ }
+
+ // 8 bytes of nibbles expand to 5 bytes
+ // so we have 51 of these batches (255 bytes), plus 2 bytes of 'leftover' nibbles for byte 256
+ for (uint n = 0; n < 51; ++n) {
+ // e.g. figure 3.18 of Beneath Apple DOS
+ byte lowbits1 = inbuffer[51*3 - n];
+ byte lowbits2 = inbuffer[51*2 - n];
+ byte lowbits3 = inbuffer[51*1 - n];
+ byte lowbits4 = (lowbits1 & 2) << 1 | (lowbits2 & 2) | (lowbits3 & 2) >> 1;
+ byte lowbits5 = (lowbits1 & 1) << 2 | (lowbits2 & 1) << 1 | (lowbits3 & 1);
+ output[250 - 5*n] = (inbuffer[n + 51*3 + 1] << 3) | ((lowbits1 >> 2) & 0x7);
+ output[251 - 5*n] = (inbuffer[n + 51*4 + 1] << 3) | ((lowbits2 >> 2) & 0x7);
+ output[252 - 5*n] = (inbuffer[n + 51*5 + 1] << 3) | ((lowbits3 >> 2) & 0x7);
+ output[253 - 5*n] = (inbuffer[n + 51*6 + 1] << 3) | lowbits4;
+ output[254 - 5*n] = (inbuffer[n + 51*7 + 1] << 3) | lowbits5;
+ }
+ output[255] = (inbuffer[409] << 3) | (inbuffer[0] & 0x7);
+ }
+ }
+
+ return true;
+}
+
const DataBlockPtr Files_Plain::getDataBlock(const Common::String &filename, uint offset) const {
return Common::SharedPtr<Files::DataBlock>(new Files::DataBlock(this, filename, offset));
}
diff --git a/engines/adl/disk.h b/engines/adl/disk.h
index 4cab81d..43b9e38 100644
--- a/engines/adl/disk.h
+++ b/engines/adl/disk.h
@@ -125,6 +125,22 @@ public:
Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
};
+// .NIB disk image
+class DiskImage_NIB : public DiskImage {
+public:
+ DiskImage_NIB() : _memStream(nullptr) { }
+ virtual ~DiskImage_NIB() {
+ delete _memStream;
+ }
+
+ bool open(const Common::String &filename);
+ const DataBlockPtr getDataBlock(uint track, uint sector, uint offset = 0, uint size = 0) const;
+ Common::SeekableReadStream *createReadStream(uint track, uint sector, uint offset = 0, uint size = 0) const;
+
+private:
+ Common::SeekableReadStream *_memStream;
+};
+
// Data in files contained in Apple DOS 3.3 disk image
class Files_DOS33 : public Files {
public:
Commit: 5db8f401a89b89f763dc8eb949a1db81f4e3fa90
https://github.com/scummvm/scummvm/commit/5db8f401a89b89f763dc8eb949a1db81f4e3fa90
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add detection entry for hires0
Changed paths:
engines/adl/detection.cpp
engines/adl/detection.h
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 457db2d..0a8a98f 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -71,6 +71,7 @@ static const ADExtraGuiOptionsMap optionsList[] = {
};
static const PlainGameDescriptor adlGames[] = {
+ { "hires0", "Hi-Res Adventure #0: Mission Asteroid" },
{ "hires1", "Hi-Res Adventure #1: Mystery House" },
{ "hires2", "Hi-Res Adventure #2: Wizard and the Princess" },
{ 0, 0 }
@@ -107,7 +108,7 @@ static const AdlGameDescription gameDescriptions[] = {
},
GAME_TYPE_HIRES1
},
- { // Hi-Res Adventure #2: Wizard and the Princess - Apple II - 1986 SierraVenture release
+ { // Hi-Res Adventure #2: Wizard and the Princess - Apple II - Roberta Williams Anthology
{
"hires2", 0,
{
@@ -121,6 +122,20 @@ static const AdlGameDescription gameDescriptions[] = {
},
GAME_TYPE_HIRES2
},
+ { // Hi-Res Adventure #0: Mission Asteroid - Apple II - Roberta Williams Anthology
+ {
+ "hires0", 0,
+ {
+ { "MISSION.NIB", 0, "b158f6f79681d4edd651e1932f9e01d7", 232960 },
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformApple2GS, // FIXME
+ ADGF_UNSTABLE,
+ GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
+ },
+ GAME_TYPE_HIRES0
+ },
{ AD_TABLE_END_MARKER, GAME_TYPE_NONE }
};
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index 4275286..bd01529 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -32,6 +32,7 @@ namespace Adl {
enum GameType {
GAME_TYPE_NONE,
+ GAME_TYPE_HIRES0,
GAME_TYPE_HIRES1,
GAME_TYPE_HIRES2
};
Commit: e89f34857f647c608add26dd8317829ab867fa30
https://github.com/scummvm/scummvm/commit/e89f34857f647c608add26dd8317829ab867fa30
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix NIB track swapping hack
Changed paths:
engines/adl/disk.cpp
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 1ec1218..80463af 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -147,10 +147,10 @@ bool DiskImage_NIB::open(const Common::String &filename) {
error("invalid NIB checksum");
// FIXME: This is a hires0/hires2-specific hack.
- if (sector == 1)
- sector = 2;
- else if (sector == 2)
- sector = 1;
+ if (track == 1)
+ track = 2;
+ else if (track == 2)
+ track = 1;
// Epilogue is de/aa plus a gap, but we don't care.
} else {
Commit: 266e63453f386b5a0b043c4cdc5e278b8b6134a3
https://github.com/scummvm/scummvm/commit/266e63453f386b5a0b043c4cdc5e278b8b6134a3
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add support for newer NIB files
Changed paths:
engines/adl/disk.cpp
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index 80463af..a9c7a59 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -94,7 +94,7 @@ bool DiskImage_NIB::open(const Common::String &filename) {
switch (filesize) {
case 232960:
_tracks = 35;
- _sectorsPerTrack = 13;
+ _sectorsPerTrack = 16; // we always pad it out
_bytesPerSector = 256;
break;
default:
@@ -103,6 +103,8 @@ bool DiskImage_NIB::open(const Common::String &filename) {
// starting at 0xaa, 32 is invalid (see below)
const byte c_5and3_lookup[] = { 32, 0, 32, 1, 2, 3, 32, 32, 32, 32, 32, 4, 5, 6, 32, 32, 7, 8, 32, 9, 10, 11, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 12, 13, 32, 32, 14, 15, 32, 16, 17, 18, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 19, 20, 32, 21, 22, 23, 32, 32, 32, 32, 32, 24, 25, 26, 32, 32, 27, 28, 32, 29, 30, 31 };
+ // starting at 0x96, 64 is invalid (see below)
+ const byte c_6and2_lookup[] = { 0, 1, 64, 64, 2, 3, 64, 4, 5, 6, 64, 64, 64, 64, 64, 64, 7, 8, 64, 64, 64, 9, 10, 11, 12, 13, 64, 64, 14, 15, 16, 17, 18, 19, 64, 20, 21, 22, 23, 24, 25, 26, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 27, 64, 28, 29, 30, 64, 64, 64, 31, 64, 64, 32, 33, 64, 34, 35, 36, 37, 38, 39, 40, 64, 64, 64, 64, 64, 41, 42, 43, 64, 44, 45, 46, 47, 48, 49, 50, 64, 64, 51, 52, 53, 54, 55, 56, 64, 57, 58, 59, 60, 61, 62, 63 };
uint32 diskSize = _tracks * _sectorsPerTrack * _bytesPerSector;
byte *diskImage = (byte *)calloc(diskSize, 1);
@@ -110,6 +112,7 @@ bool DiskImage_NIB::open(const Common::String &filename) {
bool sawAddress = false;
uint8 volNo, track, sector;
+ bool newStyle;
while (_f->pos() < _f->size()) {
// Read until we find two sync bytes.
@@ -118,22 +121,20 @@ bool DiskImage_NIB::open(const Common::String &filename) {
byte prologue = _f->readByte();
- if (sawAddress && prologue == 0xb5) {
+ if (sawAddress && (prologue == 0xb5 || prologue == 0x96)) {
warning("NIB: data for %02x/%02x/%02x missing", volNo, track, sector);
sawAddress = false;
}
if (!sawAddress) {
sawAddress = true;
+ newStyle = false;
// We should always find the address field first.
if (prologue != 0xb5) {
// Accept a DOS 3.3(?) header at the start.
- if (_f->pos() == 3 || prologue == 0x96) {
- // But skip it.
- _f->skip(20);
- sawAddress = false;
- continue;
+ if (prologue == 0x96) {
+ newStyle = true;
} else {
error("unknown NIB field prologue %02x", prologue);
}
@@ -147,19 +148,59 @@ bool DiskImage_NIB::open(const Common::String &filename) {
error("invalid NIB checksum");
// FIXME: This is a hires0/hires2-specific hack.
- if (track == 1)
- track = 2;
- else if (track == 2)
- track = 1;
+ if (volNo == 0xfe) {
+ if (track == 1)
+ track = 2;
+ else if (track == 2)
+ track = 1;
+ }
// Epilogue is de/aa plus a gap, but we don't care.
- } else {
- sawAddress = false;
+ continue;
+ }
- // We should always find the data field after an address field.
- // TODO: we ignore volNo?
- byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+ sawAddress = false;
+
+ // We should always find the data field after an address field.
+ // TODO: we ignore volNo?
+ byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+
+ if (newStyle) {
+ // 6-and-2 uses 342 on-disk bytes
+ byte inbuffer[342];
+ _f->read(inbuffer, 342);
+
+ byte oldVal = 0;
+ for (uint n = 0; n < 342; ++n) {
+ // expand
+ assert(inbuffer[n] >= 0x96); // corrupt file (TODO: assert?)
+ byte val = c_6and2_lookup[inbuffer[n] - 0x96];
+ if (val == 0x40) {
+ error("NIB: invalid nibble value %02x", inbuffer[n]);
+ }
+ // undo checksum
+ oldVal = val ^ oldVal;
+ inbuffer[n] = oldVal;
+ }
+ byte checksum = _f->readByte();
+ if (checksum < 0x96 || oldVal != c_6and2_lookup[checksum - 0x96])
+ warning("NIB: checksum mismatch @ (%x, %x)", track, sector);
+
+ for (uint n = 0; n < 256; ++n) {
+ output[n] = inbuffer[86 + n] << 2;
+ if (n < 86) { // use first pair of bits
+ output[n] |= ((inbuffer[n] & 1) << 1);
+ output[n] |= ((inbuffer[n] & 2) >> 1);
+ } else if (n < 86*2) { // second pair
+ output[n] |= ((inbuffer[n-86] & 4) >> 1);
+ output[n] |= ((inbuffer[n-86] & 8) >> 3);
+ } else { // third pair
+ output[n] |= ((inbuffer[n-86*2] & 0x10) >> 3);
+ output[n] |= ((inbuffer[n-86*2] & 0x20) >> 5);
+ }
+ }
+ } else {
// 5-and-3 uses 410 on-disk bytes, decoding to just over 256 bytes
byte inbuffer[410];
_f->read(inbuffer, 410);
Commit: ae405707cc398af3afbd7c5c00723eec2a5538f7
https://github.com/scummvm/scummvm/commit/ae405707cc398af3afbd7c5c00723eec2a5538f7
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add skeleton for hires6
Changed paths:
A engines/adl/hires6.cpp
A engines/adl/hires6.h
engines/adl/detection.cpp
engines/adl/detection.h
engines/adl/hires2.h
engines/adl/module.mk
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 0a8a98f..12405e7 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -74,6 +74,7 @@ static const PlainGameDescriptor adlGames[] = {
{ "hires0", "Hi-Res Adventure #0: Mission Asteroid" },
{ "hires1", "Hi-Res Adventure #1: Mystery House" },
{ "hires2", "Hi-Res Adventure #2: Wizard and the Princess" },
+ { "hires6", "Hi-Res Adventure #6: The Dark Crystal" },
{ 0, 0 }
};
@@ -136,6 +137,23 @@ static const AdlGameDescription gameDescriptions[] = {
},
GAME_TYPE_HIRES0
},
+ { // Hi-Res Adventure #6: The Dark Crystal - Apple II - Roberta Williams Anthology
+ {
+ "hires6", 0,
+ {
+ { "DARK1A.DSK", 0, "00c2646d6943d1405717332a6f42d493", 143360 },
+ { "DARK2A.NIB", 0, "271eb92db107e8d5829437f8ba77991e", 232960 },
+ { "DARK1B.NIB", 0, "dbedd736617343ade0e6bead8bf2b10c", 232960 },
+ { "DARK2B.NIB", 0, "cb72044a9b391c4285f4752f746bea2e", 232960 },
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformApple2GS, // FIXME
+ ADGF_UNSTABLE,
+ GUIO2(GAMEOPTION_MONO, GAMEOPTION_SCANLINES)
+ },
+ GAME_TYPE_HIRES6
+ },
{ AD_TABLE_END_MARKER, GAME_TYPE_NONE }
};
@@ -276,6 +294,7 @@ void AdlMetaEngine::removeSaveState(const char *target, int slot) const {
Engine *HiRes1Engine_create(OSystem *syst, const AdlGameDescription *gd);
Engine *HiRes2Engine_create(OSystem *syst, const AdlGameDescription *gd);
+Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd);
bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
if (!gd)
@@ -290,6 +309,9 @@ bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameD
case GAME_TYPE_HIRES2:
*engine = HiRes2Engine_create(syst, adlGd);
break;
+ case GAME_TYPE_HIRES6:
+ *engine = HiRes6Engine_create(syst, adlGd);
+ break;
default:
error("Unknown GameType");
}
diff --git a/engines/adl/detection.h b/engines/adl/detection.h
index bd01529..533466c 100644
--- a/engines/adl/detection.h
+++ b/engines/adl/detection.h
@@ -34,7 +34,8 @@ enum GameType {
GAME_TYPE_NONE,
GAME_TYPE_HIRES0,
GAME_TYPE_HIRES1,
- GAME_TYPE_HIRES2
+ GAME_TYPE_HIRES2,
+ GAME_TYPE_HIRES6
};
struct AdlGameDescription {
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index a882b68..b99fd66 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -20,8 +20,8 @@
*
*/
-#ifndef ADL_HIRES1_H
-#define ADL_HIRES1_H
+#ifndef ADL_HIRES2_H
+#define ADL_HIRES2_H
#include "common/str.h"
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
new file mode 100644
index 0000000..7c9292f
--- /dev/null
+++ b/engines/adl/hires6.cpp
@@ -0,0 +1,152 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "common/debug.h"
+#include "common/error.h"
+#include "common/file.h"
+#include "common/stream.h"
+#include "common/memstream.h"
+
+#include "adl/hires6.h"
+#include "adl/display.h"
+#include "adl/graphics.h"
+#include "adl/disk.h"
+
+namespace Adl {
+
+static const char *disks[] = { "DARK1A.DSK", "DARK1B.NIB", "DARK2A.NIB", "DARK2B.NIB" };
+
+#define SECTORS_PER_TRACK 16
+#define BYTES_PER_SECTOR 256
+
+static Common::MemoryReadStream *loadSectors(DiskImage *disk, byte track, byte sector = SECTORS_PER_TRACK - 1, byte count = SECTORS_PER_TRACK) {
+ const int bufSize = count * BYTES_PER_SECTOR;
+ byte *const buf = (byte *)malloc(bufSize);
+ byte *p = buf;
+
+ while (count-- > 0) {
+ StreamPtr stream(disk->createReadStream(track, sector, 0, 0));
+ stream->read(p, BYTES_PER_SECTOR);
+
+ if (stream->err() || stream->eos())
+ error("Error loading from disk image");
+
+ p += BYTES_PER_SECTOR;
+ if (sector > 0)
+ --sector;
+ else {
+ ++track;
+
+ // Skip VTOC track
+ if (track == 17)
+ ++track;
+
+ sector = SECTORS_PER_TRACK - 1;
+ }
+ }
+
+ return new Common::MemoryReadStream(buf, bufSize, DisposeAfterUse::YES);
+}
+
+void HiRes6Engine::runIntro() const {
+ DiskImage_DSK *boot(new DiskImage_DSK());
+
+ if (!boot->open(disks[0]))
+ error("Failed to open disk image '%s'", disks[0]);
+
+ StreamPtr stream(loadSectors(boot, 11, 1, 96));
+
+ _display->setMode(DISPLAY_MODE_HIRES);
+ _display->loadFrameBuffer(*stream);
+ _display->updateHiResScreen();
+ delay(256 * 8609 / 1000);
+
+ _display->loadFrameBuffer(*stream);
+ _display->updateHiResScreen();
+ delay(256 * 8609 / 1000);
+
+ _display->loadFrameBuffer(*stream);
+
+ delete boot;
+
+ // Load copyright string from boot file
+ Files_DOS33 *files(new Files_DOS33());
+
+ if (!files->open(disks[0]))
+ error("Failed to open disk image '%s'", disks[0]);
+
+ stream.reset(files->createReadStream("\010\010\010\010\010\010"));
+ Common::String copyright(readStringAt(*stream, 0x103, APPLECHAR('\r')));
+
+ delete files;
+
+ _display->updateHiResScreen();
+ _display->home();
+ _display->setMode(DISPLAY_MODE_MIXED);
+ _display->moveCursorTo(Common::Point(0, 21));
+ _display->printString(copyright);
+ delay(256 * 8609 / 1000);
+}
+
+void HiRes6Engine::init() {
+ DiskImage_DSK *boot(new DiskImage_DSK());
+ _graphics = new Graphics_v2(*_display);
+
+ if (!boot->open(disks[0]))
+ error("Failed to open disk image '%s'", disks[0]);
+
+ StreamPtr stream(loadSectors(boot, 7));
+
+ // Read parser messages
+ _strings.verbError = readStringAt(*stream, 0x666);
+ _strings.nounError = readStringAt(*stream, 0x6bd);
+ _strings.enterCommand = readStringAt(*stream, 0x6e9);
+
+ // Read line feeds
+ _strings.lineFeeds = readStringAt(*stream, 0x408);
+
+ // Read opcode strings (TODO)
+ _strings_v2.saveInsert = readStringAt(*stream, 0xad8);
+ readStringAt(*stream, 0xb95); // Confirm save
+ // _strings_v2.saveReplace
+ _strings_v2.restoreInsert = readStringAt(*stream, 0xc07);
+ // _strings_v2.restoreReplace
+ _strings.playAgain = readStringAt(*stream, 0xcdf, 0xff);
+
+ _messageIds.cantGoThere = IDI_HR6_MSG_CANT_GO_THERE;
+ _messageIds.dontUnderstand = IDI_HR6_MSG_DONT_UNDERSTAND;
+ _messageIds.itemDoesntMove = IDI_HR6_MSG_ITEM_DOESNT_MOVE;
+ _messageIds.itemNotHere = IDI_HR6_MSG_ITEM_NOT_HERE;
+ _messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
+
+ delete boot;
+}
+
+void HiRes6Engine::initState() {
+}
+
+Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
+ return new HiRes6Engine(syst, gd);
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
new file mode 100644
index 0000000..ecc0a6a
--- /dev/null
+++ b/engines/adl/hires6.h
@@ -0,0 +1,64 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_HIRES6_H
+#define ADL_HIRES6_H
+
+#include "common/str.h"
+
+#include "adl/adl_v2.h"
+#include "adl/disk.h"
+
+namespace Common {
+class ReadStream;
+class Point;
+}
+
+namespace Adl {
+
+#define IDI_HR6_NUM_ROOMS 35
+#define IDI_HR6_NUM_MESSAGES 255
+#define IDI_HR6_NUM_VARS 40
+#define IDI_HR6_NUM_ITEM_PICS 15
+#define IDI_HR6_NUM_ITEM_OFFSETS 16
+
+// Messages used outside of scripts
+#define IDI_HR6_MSG_CANT_GO_THERE 249
+#define IDI_HR6_MSG_DONT_UNDERSTAND 247
+#define IDI_HR6_MSG_ITEM_DOESNT_MOVE 253
+#define IDI_HR6_MSG_ITEM_NOT_HERE 254
+#define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
+
+class HiRes6Engine : public AdlEngine_v2 {
+public:
+ HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
+
+private:
+ // AdlEngine
+ void runIntro() const;
+ void init();
+ void initState();
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index 7f097a4..c726a6b 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -12,6 +12,7 @@ MODULE_OBJS := \
graphics_v2.o \
hires1.o \
hires2.o \
+ hires6.o \
speaker.o
MODULE_DIRS += \
Commit: 7dc5f636f8ebbff1ce46cad818f1e241017f83b0
https://github.com/scummvm/scummvm/commit/7dc5f636f8ebbff1ce46cad818f1e241017f83b0
Author: Alyssa Milburn (fuzzie at fuzzie.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Map DOS 3.3 NIB to logical sectors
Changed paths:
engines/adl/disk.cpp
diff --git a/engines/adl/disk.cpp b/engines/adl/disk.cpp
index a9c7a59..214f76a 100644
--- a/engines/adl/disk.cpp
+++ b/engines/adl/disk.cpp
@@ -166,6 +166,11 @@ bool DiskImage_NIB::open(const Common::String &filename) {
byte *output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
if (newStyle) {
+ // We hardcode the DOS 3.3 mapping here. TODO: Do we also need raw/prodos?
+ int raw2dos[16] = { 0, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 15 };
+ sector = raw2dos[sector];
+ output = diskImage + (track * _sectorsPerTrack + sector) * _bytesPerSector;
+
// 6-and-2 uses 342 on-disk bytes
byte inbuffer[342];
_f->read(inbuffer, 342);
Commit: a320b319eb385d3ceca16567215a7d7609247bb4
https://github.com/scummvm/scummvm/commit/a320b319eb385d3ceca16567215a7d7609247bb4
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load more hires6 data
Now shows pic of first room
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index fd316c0..90ed794 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -338,6 +338,8 @@ DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
if (track == 0 && sector == 0 && offset == 0 && size == 0)
return DataBlockPtr();
+ applyDataBlockOffset(track, sector);
+
return _disk->getDataBlock(track, sector, offset, size);
}
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 46a8813..2251a93 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -52,6 +52,7 @@ protected:
void showRoom();
void takeItem(byte noun);
+ virtual void applyDataBlockOffset(byte &track, byte §or) const { }
DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
void checkTextOverflow(char c);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 7c9292f..a87cb7b 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -115,6 +115,10 @@ void HiRes6Engine::init() {
if (!boot->open(disks[0]))
error("Failed to open disk image '%s'", disks[0]);
+ // TODO (needs refactoring of message handling)
+ for (uint i = 0; i < 256; ++i)
+ _messages.push_back(Common::String());
+
StreamPtr stream(loadSectors(boot, 7));
// Read parser messages
@@ -139,10 +143,106 @@ void HiRes6Engine::init() {
_messageIds.itemNotHere = IDI_HR6_MSG_ITEM_NOT_HERE;
_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
+ // Load dropped item offsets
+ stream.reset(boot->createReadStream(0x8, 0x9, 0x16));
+ for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
+ Common::Point p;
+ p.x = stream->readByte();
+ p.y = stream->readByte();
+ _itemOffsets.push_back(p);
+ }
+
+ _disk = new DiskImage_NIB();
+
+ if (!_disk->open(disks[1]))
+ error("Failed to open disk image '%s'", disks[1]);
+
+ // Load item picture data
+ stream.reset(boot->createReadStream(0xb, 0xd, 0x08));
+ for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
+ stream->readByte();
+ _itemPics.push_back(readDataBlockPtr(*stream));
+ }
+
+ // Load global picture data
+ stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16, 0));
+ byte picNr;
+ while ((picNr = stream->readByte()) != 0xff) {
+ if (stream->eos() || stream->err())
+ error("Error reading global pic list");
+ _pictures[picNr] = readDataBlockPtr(*stream);
+ }
+
+ // Load commands
+ stream.reset(_disk->createReadStream(0x21, 0x4, 0x85, 7));
+ readCommands(*stream, _roomCommands);
+
+ stream.reset(_disk->createReadStream(0x20, 0xf, 0x82, 5));
+ readCommands(*stream, _globalCommands);
+
+ // Load verbs
+ stream.reset(_disk->createReadStream(0x1f, 0xf, 0x56, 6));
+ loadWords(*stream, _verbs, _priVerbs);
+
+ // Load nouns
+ stream.reset(_disk->createReadStream(0x20, 0x5, 0x8e, 8));
+ loadWords(*stream, _nouns, _priNouns);
+
delete boot;
}
void HiRes6Engine::initState() {
+ _linesPrinted = 0;
+
+ _state = State();
+ _state.vars.resize(IDI_HR6_NUM_VARS);
+
+ StreamPtr stream(_disk->createReadStream(0x20, 0xd, 0x94, 2));
+
+ for (uint i = 0; i < IDI_HR6_NUM_ROOMS; ++i) {
+ Room room;
+ stream->readByte(); // number
+ for (uint j = 0; j < 6; ++j)
+ room.connections[j] = stream->readByte();
+ room.data = readDataBlockPtr(*stream);
+ room.picture = stream->readByte();
+ room.curPicture = stream->readByte();
+ room.isFirstTime = stream->readByte();
+ _state.rooms.push_back(room);
+ }
+
+ stream.reset(_disk->createReadStream(0x22, 0x0, 0x07, 0));
+
+ byte id;
+ while ((id = stream->readByte()) != 0xff) {
+ Item item = { };
+ item.id = id;
+ item.noun = stream->readByte();
+ item.room = stream->readByte();
+ item.picture = stream->readByte();
+ item.isLineArt = stream->readByte(); // Now seems to be disk number
+ item.position.x = stream->readByte();
+ item.position.y = stream->readByte();
+ item.state = stream->readByte();
+ item.description = stream->readByte();
+
+ stream->readByte(); // Struct size
+
+ byte picListSize = stream->readByte();
+
+ // Flag to keep track of what has been drawn on the screen
+ stream->readByte();
+
+ for (uint i = 0; i < picListSize; ++i)
+ item.roomPictures.push_back(stream->readByte());
+
+ _state.items.push_back(item);
+ }
+}
+
+void HiRes6Engine::applyDataBlockOffset(byte &track, byte §or) const {
+ // FIXME: this uses a table
+ ++track;
}
Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index ecc0a6a..99e9371 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -57,6 +57,9 @@ private:
void runIntro() const;
void init();
void initState();
+
+ // AdlEngine_v2
+ void applyDataBlockOffset(byte &track, byte §or) const;
};
} // End of namespace Adl
Commit: 1842d0c45f3b37442dcf94466589e0a4960bdc08
https://github.com/scummvm/scummvm/commit/1842d0c45f3b37442dcf94466589e0a4960bdc08
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add loadMessage function
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires1.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 50e7af4..37f1d04 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -123,7 +123,7 @@ void AdlEngine::openFile(Common::File &file, const Common::String &name) const {
}
void AdlEngine::printMessage(uint idx) {
- printString(_messages[idx - 1]);
+ printString(loadMessage(idx));
}
void AdlEngine::delay(uint32 ms) const {
@@ -1214,7 +1214,7 @@ Common::String AdlEngine::itemStr(uint i) const {
}
if (desc > 0) {
name += "/";
- name += toAscii(_messages[desc - 1]);
+ name += toAscii(loadMessage(desc));
}
return name;
}
@@ -1254,7 +1254,7 @@ Common::String AdlEngine::nounStr(uint i) const {
}
Common::String AdlEngine::msgStr(uint i) const {
- return Common::String::format("%d/%s", i, toAscii(_messages[i - 1]).c_str());
+ return Common::String::format("%d/%s", i, toAscii(loadMessage(i)).c_str());
}
Common::String AdlEngine::dirStr(Direction dir) const {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 1b6d02b..6832769 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -226,6 +226,7 @@ protected:
void openFile(Common::File &file, const Common::String &name) const;
virtual void printString(const Common::String &str) = 0;
+ virtual Common::String loadMessage(uint idx) const { return _messages[idx - 1]; }
virtual void printMessage(uint idx);
void delay(uint32 ms) const;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index cca2fe4..9193c27 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -268,7 +268,7 @@ void HiRes1Engine::printString(const Common::String &str) {
}
void HiRes1Engine::printMessage(uint idx) {
- const Common::String &msg = _messages[idx - 1];
+ const Common::String &msg = loadMessage(idx);
// Messages with hardcoded overrides don't delay after printing.
// It's unclear if this is a bug or not. In some cases the result
@@ -326,7 +326,7 @@ void HiRes1Engine::drawItem(Item &item, const Common::Point &pos) {
}
void HiRes1Engine::loadRoom(byte roomNr) {
- _roomData.description = _messages[_roomDesc[_state.room - 1] - 1];
+ _roomData.description = loadMessage(_roomDesc[_state.room - 1]);
}
void HiRes1Engine::showRoom() {
Commit: 4f932afd60a25366188f07a68996c5fcb097ae38
https://github.com/scummvm/scummvm/commit/4f932afd60a25366188f07a68996c5fcb097ae38
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Load messages on demand
Changed paths:
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/console.cpp
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 6832769..14e38eb 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -226,7 +226,7 @@ protected:
void openFile(Common::File &file, const Common::String &name) const;
virtual void printString(const Common::String &str) = 0;
- virtual Common::String loadMessage(uint idx) const { return _messages[idx - 1]; }
+ virtual Common::String loadMessage(uint idx) const = 0;
virtual void printMessage(uint idx);
void delay(uint32 ms) const;
@@ -317,7 +317,7 @@ protected:
typedef Common::Functor1<ScriptEnv &, int> Opcode;
Common::Array<const Opcode *> _condOpcodes, _actOpcodes;
// Message strings in data file
- Common::Array<Common::String> _messages;
+ Common::Array<DataBlockPtr> _messages;
// Picture data
PictureMap _pictures;
// Dropped item screen offsets
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 90ed794..39cf0a7 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -161,6 +161,15 @@ void AdlEngine_v2::checkTextOverflow(char c) {
}
}
+Common::String AdlEngine_v2::loadMessage(uint idx) const {
+ if (_messages[idx]) {
+ StreamPtr strStream(_messages[idx]->createReadStream());
+ return readString(*strStream, 0xff);
+ }
+
+ return Common::String();
+}
+
void AdlEngine_v2::printString(const Common::String &str) {
Common::String s(str);
byte endPos = TEXT_WIDTH - 1;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 2251a93..947b0d8 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -46,6 +46,7 @@ protected:
byte roomArg(byte room) const;
void advanceClock();
void printString(const Common::String &str);
+ Common::String loadMessage(uint idx) const;
void drawItems();
void drawItem(Item &item, const Common::Point &pos);
void loadRoom(byte roomNr);
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index c62d21c..0415bcd 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -300,7 +300,7 @@ void Console::printItem(const Item &item) {
name = _engine->_priNouns[item.noun - 1];
if (item.description > 0) {
- desc = toAscii(_engine->_messages[item.description - 1]);
+ desc = toAscii(_engine->loadMessage(item.description));
if (desc.lastChar() == '\r')
desc.deleteLastChar();
}
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 9193c27..4b3a83d 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -137,18 +137,13 @@ void HiRes1Engine::init() {
_graphics = new Graphics_v1(*_display);
- StreamPtr stream(_files->createReadStream(IDS_HR1_MESSAGES));
-
- for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
- _messages.push_back(readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r'));
-
- stream.reset(_files->createReadStream(IDS_HR1_EXE_1));
+ StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
// Some messages have overrides inside the executable
- _messages[IDI_HR1_MSG_CANT_GO_THERE - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
- _messages[IDI_HR1_MSG_DONT_HAVE_IT - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_HAVE_IT);
- _messages[IDI_HR1_MSG_DONT_UNDERSTAND - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
- _messages[IDI_HR1_MSG_GETTING_DARK - 1] = readStringAt(*stream, IDI_HR1_OFS_STR_GETTING_DARK);
+ _gameStrings.cantGoThere = readStringAt(*stream, IDI_HR1_OFS_STR_CANT_GO_THERE);
+ _gameStrings.dontHaveIt = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_HAVE_IT);
+ _gameStrings.dontUnderstand = readStringAt(*stream, IDI_HR1_OFS_STR_DONT_UNDERSTAND);
+ _gameStrings.gettingDark = readStringAt(*stream, IDI_HR1_OFS_STR_GETTING_DARK);
// Load other strings from executable
_strings.enterCommand = readStringAt(*stream, IDI_HR1_OFS_STR_ENTER_COMMAND);
@@ -165,6 +160,11 @@ void HiRes1Engine::init() {
_messageIds.itemNotHere = IDI_HR1_MSG_ITEM_NOT_HERE;
_messageIds.thanksForPlaying = IDI_HR1_MSG_THANKS_FOR_PLAYING;
+ // Load message offsets
+ stream->seek(IDI_HR1_OFS_MSGS);
+ for (uint i = 0; i < IDI_HR1_NUM_MESSAGES; ++i)
+ _messages.push_back(_files->getDataBlock(IDS_HR1_MESSAGES, stream->readUint16LE()));
+
// Load picture data from executable
stream->seek(IDI_HR1_OFS_PICS);
for (uint i = 1; i <= IDI_HR1_NUM_PICS; ++i) {
@@ -267,9 +267,12 @@ void HiRes1Engine::printString(const Common::String &str) {
delay(14 * 166018 / 1000);
}
-void HiRes1Engine::printMessage(uint idx) {
- const Common::String &msg = loadMessage(idx);
+Common::String HiRes1Engine::loadMessage(uint idx) const {
+ StreamPtr stream(_messages[idx]->createReadStream());
+ return readString(*stream, APPLECHAR('\r')) + APPLECHAR('\r');
+}
+void HiRes1Engine::printMessage(uint idx) {
// Messages with hardcoded overrides don't delay after printing.
// It's unclear if this is a bug or not. In some cases the result
// is that these strings will scroll past the four-line text window
@@ -279,14 +282,20 @@ void HiRes1Engine::printMessage(uint idx) {
// that system for this game as well.
switch (idx) {
case IDI_HR1_MSG_CANT_GO_THERE:
+ _display->printString(_gameStrings.cantGoThere);
+ return;
case IDI_HR1_MSG_DONT_HAVE_IT:
+ _display->printString(_gameStrings.dontHaveIt);
+ return;
case IDI_HR1_MSG_DONT_UNDERSTAND:
+ _display->printString(_gameStrings.dontUnderstand);
+ return;
case IDI_HR1_MSG_GETTING_DARK:
- _display->printString(msg);
+ _display->printString(_gameStrings.gettingDark);
return;
+ default:
+ printString(loadMessage(idx));
}
-
- printString(msg);
}
void HiRes1Engine::drawItems() {
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 8dc7081..273b781 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -45,7 +45,7 @@ namespace Adl {
#define IDI_HR1_NUM_PICS 97
#define IDI_HR1_NUM_VARS 20
#define IDI_HR1_NUM_ITEM_OFFSETS 21
-#define IDI_HR1_NUM_MESSAGES 167
+#define IDI_HR1_NUM_MESSAGES 168
// Messages used outside of scripts
#define IDI_HR1_MSG_CANT_GO_THERE 137
@@ -83,6 +83,7 @@ namespace Adl {
#define IDI_HR1_OFS_PICS 0x4b03
#define IDI_HR1_OFS_CMDS_0 0x3c00
#define IDI_HR1_OFS_CMDS_1 0x3d00
+#define IDI_HR1_OFS_MSGS 0x4d00
#define IDI_HR1_OFS_ITEM_OFFSETS 0x68ff
#define IDI_HR1_OFS_CORNERS 0x4f00
@@ -105,6 +106,7 @@ private:
void initState();
void restartGame();
void printString(const Common::String &str);
+ Common::String loadMessage(uint idx) const;
void printMessage(uint idx);
void drawItems();
void drawItem(Item &item, const Common::Point &pos);
@@ -118,6 +120,13 @@ private:
Common::Array<DataBlockPtr> _corners;
Common::Array<byte> _roomDesc;
bool _messageDelay;
+
+ struct {
+ Common::String cantGoThere;
+ Common::String dontHaveIt;
+ Common::String dontUnderstand;
+ Common::String gettingDark;
+ } _gameStrings;
};
} // End of namespace Adl
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index a0fa5a0..06fdc5f 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -54,18 +54,10 @@ void HiRes2Engine::init() {
if (!_disk->open(IDS_HR2_DISK_IMAGE))
error("Failed to open disk image '" IDS_HR2_DISK_IMAGE "'");
- StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x04, 4));
+ StreamPtr stream(_disk->createReadStream(0x1f, 0x2, 0x00, 4));
- for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i) {
- DataBlockPtr str(readDataBlockPtr(*stream));
-
- if (str) {
- StreamPtr strStream(str->createReadStream());
- _messages.push_back(readString(*strStream, 0xff));
- } else {
- _messages.push_back(Common::String());
- }
- }
+ for (uint i = 0; i < IDI_HR2_NUM_MESSAGES; ++i)
+ _messages.push_back(readDataBlockPtr(*stream));
// Read parser messages
stream.reset(_disk->createReadStream(0x1a, 0x1));
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index b99fd66..6647e00 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -38,7 +38,7 @@ namespace Adl {
#define IDS_HR2_DISK_IMAGE "WIZARD.DSK"
#define IDI_HR2_NUM_ROOMS 135
-#define IDI_HR2_NUM_MESSAGES 254
+#define IDI_HR2_NUM_MESSAGES 255
#define IDI_HR2_NUM_VARS 40
#define IDI_HR2_NUM_ITEM_PICS 38
#define IDI_HR2_NUM_ITEM_OFFSETS 16
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index a87cb7b..e15cf43 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -115,10 +115,6 @@ void HiRes6Engine::init() {
if (!boot->open(disks[0]))
error("Failed to open disk image '%s'", disks[0]);
- // TODO (needs refactoring of message handling)
- for (uint i = 0; i < 256; ++i)
- _messages.push_back(Common::String());
-
StreamPtr stream(loadSectors(boot, 7));
// Read parser messages
@@ -165,7 +161,7 @@ void HiRes6Engine::init() {
}
// Load global picture data
- stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16, 0));
+ stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16));
byte picNr;
while ((picNr = stream->readByte()) != 0xff) {
if (stream->eos() || stream->err())
@@ -173,6 +169,11 @@ void HiRes6Engine::init() {
_pictures[picNr] = readDataBlockPtr(*stream);
}
+ // Load message offsets
+ stream.reset(_disk->createReadStream(0x1f, 0xb, 0x16, 4));
+ for (uint i = 0; i < IDI_HR6_NUM_MESSAGES; ++i)
+ _messages.push_back(readDataBlockPtr(*stream));
+
// Load commands
stream.reset(_disk->createReadStream(0x21, 0x4, 0x85, 7));
readCommands(*stream, _roomCommands);
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 99e9371..c4e279d 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -36,7 +36,7 @@ class Point;
namespace Adl {
#define IDI_HR6_NUM_ROOMS 35
-#define IDI_HR6_NUM_MESSAGES 255
+#define IDI_HR6_NUM_MESSAGES 256
#define IDI_HR6_NUM_VARS 40
#define IDI_HR6_NUM_ITEM_PICS 15
#define IDI_HR6_NUM_ITEM_OFFSETS 16
Commit: ca47d3bb2273f5fde754bb51ef500e0eca3a25ed
https://github.com/scummvm/scummvm/commit/ca47d3bb2273f5fde754bb51ef500e0eca3a25ed
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Decrypt hires6 messages
Changed paths:
A engines/adl/adl_v3.cpp
A engines/adl/adl_v3.h
engines/adl/hires6.h
engines/adl/module.mk
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
new file mode 100644
index 0000000..608c22b
--- /dev/null
+++ b/engines/adl/adl_v3.cpp
@@ -0,0 +1,125 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/random.h"
+#include "common/error.h"
+
+#include "adl/adl_v3.h"
+#include "adl/display.h"
+#include "adl/graphics.h"
+
+namespace Adl {
+
+AdlEngine_v3::AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v2(syst, gd) {
+}
+
+Common::String AdlEngine_v3::loadMessage(uint idx) const {
+ Common::String str = AdlEngine_v2::loadMessage(idx);
+
+ for (uint i = 0; i < str.size(); ++i) {
+ const char *xorStr = "AVISDURGAN";
+ str.setChar(str[i] ^ xorStr[i % strlen(xorStr)], i);
+ }
+
+ return str;
+}
+
+typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v3> OpcodeV3;
+#define SetOpcodeTable(x) table = &x;
+#define Opcode(x) table->push_back(new OpcodeV3(this, &AdlEngine_v3::x))
+#define OpcodeUnImpl() table->push_back(new OpcodeV3(this, 0))
+
+void AdlEngine_v3::setupOpcodeTables() {
+ Common::Array<const Opcode *> *table = 0;
+
+ SetOpcodeTable(_condOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o2_isFirstTime);
+ Opcode(o2_isRandomGT);
+ Opcode(o1_isItemInRoom);
+ // 0x04
+ Opcode(o2_isNounNotInRoom);
+ Opcode(o1_isMovesGT);
+ Opcode(o1_isVarEQ);
+ Opcode(o2_isCarryingSomething);
+ // 0x08
+ Opcode(o3_isVarGT);
+ Opcode(o1_isCurPicEQ);
+ Opcode(o1_isItemPicEQ);
+
+ SetOpcodeTable(_actOpcodes);
+ // 0x00
+ OpcodeUnImpl();
+ Opcode(o1_varAdd);
+ Opcode(o1_varSub);
+ Opcode(o1_varSet);
+ // 0x04
+ Opcode(o1_listInv);
+ Opcode(o2_moveItem);
+ Opcode(o1_setRoom);
+ Opcode(o1_setCurPic);
+ // 0x08
+ Opcode(o1_setPic);
+ Opcode(o1_printMsg);
+ Opcode(o1_setLight);
+ Opcode(o1_setDark);
+ // 0x0c
+ Opcode(o2_moveAllItems);
+ Opcode(o1_quit);
+ OpcodeUnImpl();
+ Opcode(o2_save);
+ // 0x10
+ Opcode(o2_restore);
+ Opcode(o1_restart);
+ Opcode(o2_placeItem);
+ Opcode(o1_setItemPic);
+ // 0x14
+ Opcode(o1_resetPic);
+ Opcode(o1_goDirection<IDI_DIR_NORTH>);
+ Opcode(o1_goDirection<IDI_DIR_SOUTH>);
+ Opcode(o1_goDirection<IDI_DIR_EAST>);
+ // 0x18
+ Opcode(o1_goDirection<IDI_DIR_WEST>);
+ Opcode(o1_goDirection<IDI_DIR_UP>);
+ Opcode(o1_goDirection<IDI_DIR_DOWN>);
+ Opcode(o1_takeItem);
+ // 0x1c
+ Opcode(o1_dropItem);
+ Opcode(o1_setRoomPic);
+ Opcode(o2_tellTime);
+ Opcode(o2_setRoomFromVar);
+ // 0x20
+ Opcode(o2_initDisk);
+}
+
+int AdlEngine_v3::o3_isVarGT(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& VARS[%d] > %d", e.arg(1), e.arg(2));
+
+ if (getVar(e.arg(1)) > e.arg(2))
+ return 2;
+
+ return -1;
+}
+
+} // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
new file mode 100644
index 0000000..c0b7fad
--- /dev/null
+++ b/engines/adl/adl_v3.h
@@ -0,0 +1,53 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef ADL_ADL_V3_H
+#define ADL_ADL_V3_H
+
+#include "adl/adl_v2.h"
+
+// Note: this version of ADL redraws only when necessary, but
+// this is not currently implemented.
+
+namespace Common{
+class RandomSource;
+}
+
+namespace Adl {
+
+class AdlEngine_v3 : public AdlEngine_v2 {
+public:
+ virtual ~AdlEngine_v3() { }
+
+protected:
+ AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd);
+
+ // AdlEngine
+ virtual void setupOpcodeTables();
+ virtual Common::String loadMessage(uint idx) const;
+
+ int o3_isVarGT(ScriptEnv &e);
+};
+
+} // End of namespace Adl
+
+#endif
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index c4e279d..395e852 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -25,7 +25,7 @@
#include "common/str.h"
-#include "adl/adl_v2.h"
+#include "adl/adl_v3.h"
#include "adl/disk.h"
namespace Common {
@@ -48,9 +48,9 @@ namespace Adl {
#define IDI_HR6_MSG_ITEM_NOT_HERE 254
#define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
-class HiRes6Engine : public AdlEngine_v2 {
+class HiRes6Engine : public AdlEngine_v3 {
public:
- HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v2(syst, gd) { }
+ HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd) { }
private:
// AdlEngine
diff --git a/engines/adl/module.mk b/engines/adl/module.mk
index c726a6b..7ab37ef 100644
--- a/engines/adl/module.mk
+++ b/engines/adl/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/adl
MODULE_OBJS := \
adl.o \
adl_v2.o \
+ adl_v3.o \
console.o \
detection.o \
disk.o \
Commit: 6044022c8ed3349242d86206adb57cb9f4f3031e
https://github.com/scummvm/scummvm/commit/6044022c8ed3349242d86206adb57cb9f4f3031e
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add '%' string code processing for hires6
Changed paths:
engines/adl/adl_v2.h
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 947b0d8..60af4de 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -45,8 +45,8 @@ protected:
virtual void setupOpcodeTables();
byte roomArg(byte room) const;
void advanceClock();
- void printString(const Common::String &str);
- Common::String loadMessage(uint idx) const;
+ virtual void printString(const Common::String &str);
+ virtual Common::String loadMessage(uint idx) const;
void drawItems();
void drawItem(Item &item, const Common::Point &pos);
void loadRoom(byte roomNr);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index e15cf43..7ac953c 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -246,6 +246,39 @@ void HiRes6Engine::applyDataBlockOffset(byte &track, byte §or) const {
++track;
}
+void HiRes6Engine::printString(const Common::String &str) {
+ Common::String s;
+ uint found = 0;
+
+ // This does not emulate the corner cases of the original, hence this check
+ if (getVar(27) > 1)
+ error("Invalid value %i encountered for variable 27", getVar(27));
+
+ for (uint i = 0; i < str.size(); ++i) {
+ if (str[i] == '%') {
+ ++found;
+ if (found == 3)
+ found = 0;
+ continue;
+ }
+
+ switch (found) {
+ case 0:
+ s += str[i];
+ break;
+ case 1:
+ if (getVar(27) == 0)
+ s += str[i];
+ break;
+ case 2:
+ if (getVar(27) == 1)
+ s += str[i];
+ }
+ }
+
+ AdlEngine_v2::printString(s);
+}
+
Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
return new HiRes6Engine(syst, gd);
}
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 395e852..a845070 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -59,6 +59,7 @@ private:
void initState();
// AdlEngine_v2
+ void printString(const Common::String &str);
void applyDataBlockOffset(byte &track, byte §or) const;
};
Commit: 8cc5100afd022f089bcba1cfc9b90d64601b2754
https://github.com/scummvm/scummvm/commit/8cc5100afd022f089bcba1cfc9b90d64601b2754
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix OB1 bug in ADL v2 word wrapping
Changed paths:
engines/adl/adl_v2.cpp
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 39cf0a7..dba6b61 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -176,7 +176,7 @@ void AdlEngine_v2::printString(const Common::String &str) {
byte pos = 0;
while (true) {
- while (pos != endPos && pos != s.size()) {
+ while (pos <= endPos && pos != s.size()) {
s.setChar(APPLECHAR(s[pos]), pos);
++pos;
}
Commit: 5fe95d51ea3d35e9de725a08b3681fbc3f8844bc
https://github.com/scummvm/scummvm/commit/5fe95d51ea3d35e9de725a08b3681fbc3f8844bc
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Separate game-specific state init
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires1.cpp
engines/adl/hires1.h
engines/adl/hires2.cpp
engines/adl/hires2.h
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 37f1d04..328638a 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -379,6 +379,12 @@ void AdlEngine::setupOpcodeTables() {
Opcode(o1_setRoomPic);
}
+void AdlEngine::initState() {
+ _state = State();
+
+ initGameState();
+}
+
byte AdlEngine::roomArg(byte room) const {
return room;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 14e38eb..f7a6ed9 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -240,6 +240,7 @@ protected:
virtual bool isInputValid(const Commands &commands, byte verb, byte noun, bool &is_any);
virtual void setupOpcodeTables();
+ virtual void initState();
virtual byte roomArg(byte room) const;
virtual void advanceClock() { }
@@ -358,7 +359,7 @@ protected:
private:
virtual void runIntro() const { }
virtual void init() = 0;
- virtual void initState() = 0;
+ virtual void initGameState() = 0;
virtual void drawItems() = 0;
virtual void drawItem(Item &item, const Common::Point &pos) = 0;
virtual void loadRoom(byte roomNr) = 0;
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index dba6b61..55060be 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -114,6 +114,16 @@ void AdlEngine_v2::setupOpcodeTables() {
Opcode(o2_initDisk);
}
+void AdlEngine_v2::initState() {
+ AdlEngine::initState();
+
+ _linesPrinted = 0;
+ _picOnScreen = 0;
+ _roomOnScreen = 0;
+ _itemRemoved = false;
+ _itemsOnScreen = 0;
+}
+
byte AdlEngine_v2::roomArg(byte room) const {
if (room == IDI_CUR_ROOM)
return _state.room;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 60af4de..fa12a48 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -43,6 +43,7 @@ protected:
// AdlEngine
virtual void setupOpcodeTables();
+ virtual void initState();
byte roomArg(byte room) const;
void advanceClock();
virtual void printString(const Common::String &str);
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 4b3a83d..c8b9989 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -206,8 +206,7 @@ void HiRes1Engine::init() {
loadWords(*stream, _nouns, _priNouns);
}
-void HiRes1Engine::initState() {
- _state = State();
+void HiRes1Engine::initGameState() {
_state.vars.resize(IDI_HR1_NUM_VARS);
StreamPtr stream(_files->createReadStream(IDS_HR1_EXE_1));
diff --git a/engines/adl/hires1.h b/engines/adl/hires1.h
index 273b781..c060bc8 100644
--- a/engines/adl/hires1.h
+++ b/engines/adl/hires1.h
@@ -103,7 +103,7 @@ private:
// AdlEngine
void runIntro() const;
void init();
- void initState();
+ void initGameState();
void restartGame();
void printString(const Common::String &str);
Common::String loadMessage(uint idx) const;
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index 06fdc5f..d1dd065 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -130,10 +130,7 @@ void HiRes2Engine::init() {
loadWords(*stream, _nouns, _priNouns);
}
-void HiRes2Engine::initState() {
- _linesPrinted = 0;
-
- _state = State();
+void HiRes2Engine::initGameState() {
_state.vars.resize(IDI_HR2_NUM_VARS);
StreamPtr stream(_disk->createReadStream(0x21, 0x5, 0x0e, 7));
diff --git a/engines/adl/hires2.h b/engines/adl/hires2.h
index 6647e00..7a0769a 100644
--- a/engines/adl/hires2.h
+++ b/engines/adl/hires2.h
@@ -58,7 +58,7 @@ private:
// AdlEngine
void runIntro() const;
void init();
- void initState();
+ void initGameState();
};
} // End of namespace Adl
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 7ac953c..37c7154 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -192,10 +192,7 @@ void HiRes6Engine::init() {
delete boot;
}
-void HiRes6Engine::initState() {
- _linesPrinted = 0;
-
- _state = State();
+void HiRes6Engine::initGameState() {
_state.vars.resize(IDI_HR6_NUM_VARS);
StreamPtr stream(_disk->createReadStream(0x20, 0xd, 0x94, 2));
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index a845070..a2f6e42 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -56,7 +56,7 @@ private:
// AdlEngine
void runIntro() const;
void init();
- void initState();
+ void initGameState();
// AdlEngine_v2
void printString(const Common::String &str);
Commit: bf520ca3211a1638396efe71e19291e7dbd979c0
https://github.com/scummvm/scummvm/commit/bf520ca3211a1638396efe71e19291e7dbd979c0
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix restarting from AllCommands list
Changed paths:
engines/adl/adl.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 328638a..b77f8da 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -573,6 +573,12 @@ Common::Error AdlEngine::run() {
}
doAllCommands(_globalCommands, verb, noun);
+
+ if (_isRestarting) {
+ _isRestarting = false;
+ continue;
+ }
+
advanceClock();
_state.moves++;
}
@@ -1197,8 +1203,12 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
ScriptEnv env(*cmd, _state.room, verb, noun);
- if (matchCommand(env))
+ if (matchCommand(env)) {
doActions(env);
+ // The original long jumps on restart, so we need to abort here
+ if (_isRestarting)
+ return;
+ }
}
}
Commit: 7e9a8c00728592290c2c4f2ba0aa5bf3bf7efff9
https://github.com/scummvm/scummvm/commit/7e9a8c00728592290c2c4f2ba0aa5bf3bf7efff9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Partially implement hires6 var handling
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/hires1.cpp
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index b77f8da..98895ce 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -385,6 +385,10 @@ void AdlEngine::initState() {
initGameState();
}
+void AdlEngine::printRoomDescription() {
+ printString(_roomData.description);
+}
+
byte AdlEngine::roomArg(byte room) const {
return room;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index f7a6ed9..e5fbf35 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -241,6 +241,7 @@ protected:
virtual void setupOpcodeTables();
virtual void initState();
+ virtual void printRoomDescription();
virtual byte roomArg(byte room) const;
virtual void advanceClock() { }
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 55060be..05cfaac 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -278,7 +278,7 @@ void AdlEngine_v2::showRoom() {
drawItems();
_display->updateHiResScreen();
- printString(_roomData.description);
+ printRoomDescription();
// FIXME: move to main loop?
_linesPrinted = 0;
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c8b9989..7a85d89 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -348,7 +348,7 @@ void HiRes1Engine::showRoom() {
_display->updateHiResScreen();
_messageDelay = false;
- printString(_roomData.description);
+ printRoomDescription();
_messageDelay = true;
}
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 37c7154..5bc7711 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -236,6 +236,13 @@ void HiRes6Engine::initGameState() {
_state.items.push_back(item);
}
+
+ _currVerb = _currNoun = 0;
+}
+
+void HiRes6Engine::printRoomDescription() {
+ setVar(2, 0xff);
+ AdlEngine_v3::printRoomDescription();
}
void HiRes6Engine::applyDataBlockOffset(byte &track, byte §or) const {
@@ -256,24 +263,28 @@ void HiRes6Engine::printString(const Common::String &str) {
++found;
if (found == 3)
found = 0;
- continue;
- }
-
- switch (found) {
- case 0:
- s += str[i];
- break;
- case 1:
- if (getVar(27) == 0)
- s += str[i];
- break;
- case 2:
- if (getVar(27) == 1)
+ } else {
+ if (found == 0 || found - 1 == getVar(27))
s += str[i];
}
}
- AdlEngine_v2::printString(s);
+ if (getVar(2) != 0xff) {
+ AdlEngine_v2::printString(s);
+ } else {
+ if (getVar(26) == 0) {
+ if (str.size() != 1 || APPLECHAR(str[0]) != APPLECHAR(' '))
+ return AdlEngine_v2::printString(s);
+ setVar(2, APPLECHAR(' '));
+ } else if (getVar(26) == 0xff) {
+ setVar(2, 'P');
+ } else {
+ setVar(26, _state.room);
+ setVar(2, 1);
+ }
+
+ doAllCommands(_globalCommands, _currVerb, _currNoun);
+ }
}
Engine *HiRes6Engine_create(OSystem *syst, const AdlGameDescription *gd) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index a2f6e42..42211d1 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -50,17 +50,20 @@ namespace Adl {
class HiRes6Engine : public AdlEngine_v3 {
public:
- HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd) { }
+ HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd), _currVerb(0), _currNoun(0) { }
private:
// AdlEngine
void runIntro() const;
void init();
void initGameState();
+ void printRoomDescription();
// AdlEngine_v2
void printString(const Common::String &str);
void applyDataBlockOffset(byte &track, byte §or) const;
+
+ byte _currVerb, _currNoun;
};
} // End of namespace Adl
Commit: b8c40f9a8b81631c610c0bdadaefb4b9b7df5792
https://github.com/scummvm/scummvm/commit/b8c40f9a8b81631c610c0bdadaefb4b9b7df5792
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires6 cond opcode 0xa
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v3.cpp
engines/adl/adl_v3.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 98895ce..fdbb2aa 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -58,6 +58,7 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) :
_graphics(nullptr),
_isRestarting(false),
_isRestoring(false),
+ _skipOneCommand(false),
_gameDescription(gd),
_saveVerb(0),
_saveNoun(0),
@@ -1192,6 +1193,12 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+
+ if (_skipOneCommand) {
+ _skipOneCommand = false;
+ continue;
+ }
+
ScriptEnv env(*cmd, _state.room, verb, noun);
if (matchCommand(env)) {
doActions(env);
@@ -1199,6 +1206,7 @@ bool AdlEngine::doOneCommand(const Commands &commands, byte verb, byte noun) {
}
}
+ _skipOneCommand = false;
return false;
}
@@ -1206,6 +1214,11 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
Commands::const_iterator cmd;
for (cmd = commands.begin(); cmd != commands.end(); ++cmd) {
+ if (_skipOneCommand) {
+ _skipOneCommand = false;
+ continue;
+ }
+
ScriptEnv env(*cmd, _state.room, verb, noun);
if (matchCommand(env)) {
doActions(env);
@@ -1214,6 +1227,8 @@ void AdlEngine::doAllCommands(const Commands &commands, byte verb, byte noun) {
return;
}
}
+
+ _skipOneCommand = false;
}
Common::String AdlEngine::toAscii(const Common::String &str) {
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index e5fbf35..06d378e 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -356,6 +356,7 @@ protected:
State _state;
bool _isRestarting, _isRestoring;
+ bool _skipOneCommand;
private:
virtual void runIntro() const { }
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 608c22b..e326b05 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -66,7 +66,7 @@ void AdlEngine_v3::setupOpcodeTables() {
// 0x08
Opcode(o3_isVarGT);
Opcode(o1_isCurPicEQ);
- Opcode(o1_isItemPicEQ);
+ Opcode(o3_skipOneCommand);
SetOpcodeTable(_actOpcodes);
// 0x00
@@ -122,4 +122,14 @@ int AdlEngine_v3::o3_isVarGT(ScriptEnv &e) {
return -1;
}
+// FIXME: Move to HiRes6 class?
+int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
+ OP_DEBUG_0("\t&& SKIP_NEXT_COMMAND()");
+
+ _skipOneCommand = true;
+ setVar(2, 0);
+
+ return -1;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index c0b7fad..f99e0bd 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -46,6 +46,7 @@ protected:
virtual Common::String loadMessage(uint idx) const;
int o3_isVarGT(ScriptEnv &e);
+ int o3_skipOneCommand(ScriptEnv &e);
};
} // End of namespace Adl
Commit: bb6cd4612dd25d93c6b7d928b8aec5537dac9480
https://github.com/scummvm/scummvm/commit/bb6cd4612dd25d93c6b7d928b8aec5537dac9480
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix bug in hires6 printString
Changed paths:
engines/adl/hires6.cpp
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 5bc7711..4ee5663 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -276,7 +276,7 @@ void HiRes6Engine::printString(const Common::String &str) {
if (str.size() != 1 || APPLECHAR(str[0]) != APPLECHAR(' '))
return AdlEngine_v2::printString(s);
setVar(2, APPLECHAR(' '));
- } else if (getVar(26) == 0xff) {
+ } else if (getVar(26) != 0xff) {
setVar(2, 'P');
} else {
setVar(26, _state.room);
Commit: 04604ed6023aa322660f3ab5e93a3a067b22bbf4
https://github.com/scummvm/scummvm/commit/04604ed6023aa322660f3ab5e93a3a067b22bbf4
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires6 showRoom() var handling
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/hires1.cpp
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index fdbb2aa..edcd804 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -386,10 +386,6 @@ void AdlEngine::initState() {
initGameState();
}
-void AdlEngine::printRoomDescription() {
- printString(_roomData.description);
-}
-
byte AdlEngine::roomArg(byte room) const {
return room;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 06d378e..0cf9024 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -241,7 +241,6 @@ protected:
virtual void setupOpcodeTables();
virtual void initState();
- virtual void printRoomDescription();
virtual byte roomArg(byte room) const;
virtual void advanceClock() { }
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 05cfaac..55060be 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -278,7 +278,7 @@ void AdlEngine_v2::showRoom() {
drawItems();
_display->updateHiResScreen();
- printRoomDescription();
+ printString(_roomData.description);
// FIXME: move to main loop?
_linesPrinted = 0;
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index fa12a48..164af7d 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -51,7 +51,7 @@ protected:
void drawItems();
void drawItem(Item &item, const Common::Point &pos);
void loadRoom(byte roomNr);
- void showRoom();
+ virtual void showRoom();
void takeItem(byte noun);
virtual void applyDataBlockOffset(byte &track, byte §or) const { }
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index 7a85d89..c8b9989 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -348,7 +348,7 @@ void HiRes1Engine::showRoom() {
_display->updateHiResScreen();
_messageDelay = false;
- printRoomDescription();
+ printString(_roomData.description);
_messageDelay = true;
}
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 4ee5663..7f6de17 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -240,9 +240,51 @@ void HiRes6Engine::initGameState() {
_currVerb = _currNoun = 0;
}
-void HiRes6Engine::printRoomDescription() {
+void HiRes6Engine::showRoom() {
+ bool redrawPic = false;
+
+ if (getVar(26) == 0xfe)
+ setVar(26, 0);
+ else if (getVar(26) != 0xff)
+ setVar(26, _state.room);
+
+ if (_state.room != _roomOnScreen) {
+ loadRoom(_state.room);
+
+ if (getVar(26) < 0x80 && getCurRoom().isFirstTime)
+ setVar(26, 0);
+
+ clearScreen();
+
+ if (!_state.isDark)
+ redrawPic = true;
+ } else {
+ if (getCurRoom().curPicture != _picOnScreen || _itemRemoved)
+ redrawPic = true;
+ }
+
+ if (redrawPic) {
+ _roomOnScreen = _state.room;
+ _picOnScreen = getCurRoom().curPicture;
+
+ drawPic(getCurRoom().curPicture);
+ _itemRemoved = false;
+ _itemsOnScreen = 0;
+
+ Common::List<Item>::iterator item;
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ item->isOnScreen = false;
+ }
+
+ if (!_state.isDark)
+ drawItems();
+
+ _display->updateHiResScreen();
setVar(2, 0xff);
- AdlEngine_v3::printRoomDescription();
+ printString(_roomData.description);
+
+ // FIXME: move to main loop?
+ _linesPrinted = 0;
}
void HiRes6Engine::applyDataBlockOffset(byte &track, byte §or) const {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 42211d1..9f886aa 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -58,6 +58,7 @@ private:
void init();
void initGameState();
void printRoomDescription();
+ void showRoom();
// AdlEngine_v2
void printString(const Common::String &str);
Commit: d2175a70ce3873e09f9f7b7bc84dcc1b614ae054
https://github.com/scummvm/scummvm/commit/d2175a70ce3873e09f9f7b7bc84dcc1b614ae054
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement remaining hires6 conditionals
Changed paths:
engines/adl/adl_v3.cpp
engines/adl/adl_v3.h
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index e326b05..4f2b344 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -30,7 +30,8 @@
namespace Adl {
AdlEngine_v3::AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd) :
- AdlEngine_v2(syst, gd) {
+ AdlEngine_v2(syst, gd),
+ _curDisk(1) {
}
Common::String AdlEngine_v3::loadMessage(uint idx) const {
@@ -57,9 +58,9 @@ void AdlEngine_v3::setupOpcodeTables() {
OpcodeUnImpl();
Opcode(o2_isFirstTime);
Opcode(o2_isRandomGT);
- Opcode(o1_isItemInRoom);
+ Opcode(o3_isItemInRoom);
// 0x04
- Opcode(o2_isNounNotInRoom);
+ Opcode(o3_isNounNotInRoom);
Opcode(o1_isMovesGT);
Opcode(o1_isVarEQ);
Opcode(o2_isCarryingSomething);
@@ -122,9 +123,8 @@ int AdlEngine_v3::o3_isVarGT(ScriptEnv &e) {
return -1;
}
-// FIXME: Move to HiRes6 class?
int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
- OP_DEBUG_0("\t&& SKIP_NEXT_COMMAND()");
+ OP_DEBUG_0("\t&& SKIP_ONE_COMMAND()");
_skipOneCommand = true;
setVar(2, 0);
@@ -132,4 +132,36 @@ int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
return -1;
}
+int AdlEngine_v3::o3_isItemInRoom(ScriptEnv &e) {
+ OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
+ const Item &item = getItem(e.arg(1));
+
+ if (e.arg(2) != IDI_ANY && item.isLineArt != _curDisk)
+ return -1;
+
+ if (item.room == roomArg(e.arg(2)))
+ return 2;
+
+ return -1;
+}
+
+int AdlEngine_v3::o3_isNounNotInRoom(ScriptEnv &e) {
+ OP_DEBUG_1("\t&& NO_SUCH_ITEMS_IN_ROOM(%s)", itemRoomStr(e.arg(1)).c_str());
+
+ Common::List<Item>::const_iterator item;
+
+ setVar(24, 0);
+
+ for (item = _state.items.begin(); item != _state.items.end(); ++item)
+ if (item->noun == e.getNoun()) {
+ setVar(24, 1);
+
+ if (item->room == roomArg(e.arg(1)))
+ return -1;
+ }
+
+ return 1;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index f99e0bd..7d4790f 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -46,7 +46,12 @@ protected:
virtual Common::String loadMessage(uint idx) const;
int o3_isVarGT(ScriptEnv &e);
+ int o3_isItemInRoom(ScriptEnv &e);
+ int o3_isNounNotInRoom(ScriptEnv &e);
int o3_skipOneCommand(ScriptEnv &e);
+
+private:
+ byte _curDisk;
};
} // End of namespace Adl
Commit: e79f26c9bcda2c08ef7a7628960c71cff336daaf
https://github.com/scummvm/scummvm/commit/e79f26c9bcda2c08ef7a7628960c71cff336daaf
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires6 item descriptions
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/adl_v3.cpp
engines/adl/adl_v3.h
engines/adl/console.cpp
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index edcd804..c17855d 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -127,6 +127,13 @@ void AdlEngine::printMessage(uint idx) {
printString(loadMessage(idx));
}
+Common::String AdlEngine::getItemDescription(const Item &item) const {
+ if (item.description > 0)
+ return loadMessage(item.description);
+ else
+ return Common::String();
+}
+
void AdlEngine::delay(uint32 ms) const {
uint32 start = g_system->getMillis();
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 0cf9024..a23f6b7 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -228,6 +228,7 @@ protected:
virtual void printString(const Common::String &str) = 0;
virtual Common::String loadMessage(uint idx) const = 0;
virtual void printMessage(uint idx);
+ virtual Common::String getItemDescription(const Item &item) const;
void delay(uint32 ms) const;
Common::String inputString(byte prompt = 0) const;
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 4f2b344..d0e9242 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -45,6 +45,10 @@ Common::String AdlEngine_v3::loadMessage(uint idx) const {
return str;
}
+Common::String AdlEngine_v3::getItemDescription(const Item &item) const {
+ return _itemDesc[item.id - 1];
+}
+
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v3> OpcodeV3;
#define SetOpcodeTable(x) table = &x;
#define Opcode(x) table->push_back(new OpcodeV3(this, &AdlEngine_v3::x))
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 7d4790f..f022adf 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -44,13 +44,14 @@ protected:
// AdlEngine
virtual void setupOpcodeTables();
virtual Common::String loadMessage(uint idx) const;
+ Common::String getItemDescription(const Item &item) const;
int o3_isVarGT(ScriptEnv &e);
int o3_isItemInRoom(ScriptEnv &e);
int o3_isNounNotInRoom(ScriptEnv &e);
int o3_skipOneCommand(ScriptEnv &e);
-private:
+ Common::Array<Common::String> _itemDesc;
byte _curDisk;
};
diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp
index 0415bcd..c35e8b0 100644
--- a/engines/adl/console.cpp
+++ b/engines/adl/console.cpp
@@ -299,11 +299,9 @@ void Console::printItem(const Item &item) {
if (item.noun > 0)
name = _engine->_priNouns[item.noun - 1];
- if (item.description > 0) {
- desc = toAscii(_engine->loadMessage(item.description));
- if (desc.lastChar() == '\r')
- desc.deleteLastChar();
- }
+ desc = toAscii(_engine->getItemDescription(item));
+ if (desc.lastChar() == '\r')
+ desc.deleteLastChar();
switch (item.state) {
case IDI_ITEM_NOT_MOVED:
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 7f6de17..eaf468c 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -115,7 +115,7 @@ void HiRes6Engine::init() {
if (!boot->open(disks[0]))
error("Failed to open disk image '%s'", disks[0]);
- StreamPtr stream(loadSectors(boot, 7));
+ StreamPtr stream(loadSectors(boot, 0x7));
// Read parser messages
_strings.verbError = readStringAt(*stream, 0x666);
@@ -139,6 +139,12 @@ void HiRes6Engine::init() {
_messageIds.itemNotHere = IDI_HR6_MSG_ITEM_NOT_HERE;
_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
+ // Item descriptions
+ stream.reset(loadSectors(boot, 0x6, 0xb, 2));
+ stream->seek(0x34);
+ for (uint i = 0; i < IDI_HR6_NUM_ITEM_DESCS; ++i)
+ _itemDesc.push_back(readString(*stream, 0xff));
+
// Load dropped item offsets
stream.reset(boot->createReadStream(0x8, 0x9, 0x16));
for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 9f886aa..443a9ca 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -38,6 +38,7 @@ namespace Adl {
#define IDI_HR6_NUM_ROOMS 35
#define IDI_HR6_NUM_MESSAGES 256
#define IDI_HR6_NUM_VARS 40
+#define IDI_HR6_NUM_ITEM_DESCS 15
#define IDI_HR6_NUM_ITEM_PICS 15
#define IDI_HR6_NUM_ITEM_OFFSETS 16
Commit: e755f8fcba4d3dfc746d83f60b70d2aad86360b9
https://github.com/scummvm/scummvm/commit/e755f8fcba4d3dfc746d83f60b70d2aad86360b9
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires6 "move item" opcode
Changed paths:
engines/adl/adl_v3.cpp
engines/adl/adl_v3.h
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index d0e9242..9041a47 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -81,7 +81,7 @@ void AdlEngine_v3::setupOpcodeTables() {
Opcode(o1_varSet);
// 0x04
Opcode(o1_listInv);
- Opcode(o2_moveItem);
+ Opcode(o3_moveItem);
Opcode(o1_setRoom);
Opcode(o1_setCurPic);
// 0x08
@@ -136,6 +136,7 @@ int AdlEngine_v3::o3_skipOneCommand(ScriptEnv &e) {
return -1;
}
+// FIXME: Rename "isLineArt" and look at code duplication
int AdlEngine_v3::o3_isItemInRoom(ScriptEnv &e) {
OP_DEBUG_2("\t&& GET_ITEM_ROOM(%s) == %s", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
@@ -168,4 +169,23 @@ int AdlEngine_v3::o3_isNounNotInRoom(ScriptEnv &e) {
return 1;
}
+int AdlEngine_v3::o3_moveItem(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_ITEM_ROOM(%s, %s)", itemStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
+
+ byte room = roomArg(e.arg(2));
+
+ Item &item = getItem(e.arg(1));
+
+ if (item.room == _roomOnScreen)
+ _picOnScreen = 0;
+
+ // Set items that move from inventory to a room to state "dropped"
+ if (item.room == IDI_ANY && room != IDI_VOID_ROOM)
+ item.state = IDI_ITEM_DROPPED;
+
+ item.room = room;
+ item.isLineArt = _curDisk;
+ return 2;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index f022adf..77b64fd 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -50,6 +50,7 @@ protected:
int o3_isItemInRoom(ScriptEnv &e);
int o3_isNounNotInRoom(ScriptEnv &e);
int o3_skipOneCommand(ScriptEnv &e);
+ int o3_moveItem(ScriptEnv &e);
Common::Array<Common::String> _itemDesc;
byte _curDisk;
Commit: 92b1b287b1686424a58abfb06661916bf3dfcaeb
https://github.com/scummvm/scummvm/commit/92b1b287b1686424a58abfb06661916bf3dfcaeb
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Preliminary support for hires6 disk changing
Changed paths:
engines/adl/adl.cpp
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index c17855d..761b60c 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -219,6 +219,9 @@ byte AdlEngine::inputKey(bool showCursor) const {
void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const {
uint index = 0;
+ map.clear();
+ pri.clear();
+
while (1) {
++index;
@@ -255,6 +258,8 @@ void AdlEngine::loadWords(Common::ReadStream &stream, WordMap &map, Common::Stri
}
void AdlEngine::readCommands(Common::ReadStream &stream, Commands &commands) {
+ commands.clear();
+
while (1) {
Command command;
command.room = stream.readByte();
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index eaf468c..c3c4138 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -109,13 +109,13 @@ void HiRes6Engine::runIntro() const {
}
void HiRes6Engine::init() {
- DiskImage_DSK *boot(new DiskImage_DSK());
+ _boot = new DiskImage_DSK();
_graphics = new Graphics_v2(*_display);
- if (!boot->open(disks[0]))
+ if (!_boot->open(disks[0]))
error("Failed to open disk image '%s'", disks[0]);
- StreamPtr stream(loadSectors(boot, 0x7));
+ StreamPtr stream(loadSectors(_boot, 0x7));
// Read parser messages
_strings.verbError = readStringAt(*stream, 0x666);
@@ -140,13 +140,13 @@ void HiRes6Engine::init() {
_messageIds.thanksForPlaying = IDI_HR6_MSG_THANKS_FOR_PLAYING;
// Item descriptions
- stream.reset(loadSectors(boot, 0x6, 0xb, 2));
+ stream.reset(loadSectors(_boot, 0x6, 0xb, 2));
stream->seek(0x34);
for (uint i = 0; i < IDI_HR6_NUM_ITEM_DESCS; ++i)
_itemDesc.push_back(readString(*stream, 0xff));
// Load dropped item offsets
- stream.reset(boot->createReadStream(0x8, 0x9, 0x16));
+ stream.reset(_boot->createReadStream(0x8, 0x9, 0x16));
for (uint i = 0; i < IDI_HR6_NUM_ITEM_OFFSETS; ++i) {
Common::Point p;
p.x = stream->readByte();
@@ -154,68 +154,129 @@ void HiRes6Engine::init() {
_itemOffsets.push_back(p);
}
+ // Location of game data for each disc
+ stream.reset(_boot->createReadStream(0x5, 0xa, 0x03));
+ for (uint i = 0; i < sizeof(disks); ++i) {
+ DiskDataDesc desc;
+ desc.track = stream->readByte();
+ desc.sector = stream->readByte();
+ desc.offset = stream->readByte();
+ desc.volume = stream->readByte();
+ _diskDataDesc.push_back(desc);
+ }
+}
+
+void HiRes6Engine::loadDisk(byte disk) {
+ delete _disk;
_disk = new DiskImage_NIB();
- if (!_disk->open(disks[1]))
- error("Failed to open disk image '%s'", disks[1]);
+ if (!_disk->open(disks[disk]))
+ error("Failed to open disk image '%s'", disks[disk]);
- // Load item picture data
- stream.reset(boot->createReadStream(0xb, 0xd, 0x08));
- for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
- stream->readByte();
- _itemPics.push_back(readDataBlockPtr(*stream));
- }
+ _curDisk = disk;
- // Load global picture data
- stream.reset(_disk->createReadStream(0x1f, 0xf, 0x16));
- byte picNr;
- while ((picNr = stream->readByte()) != 0xff) {
- if (stream->eos() || stream->err())
- error("Error reading global pic list");
- _pictures[picNr] = readDataBlockPtr(*stream);
- }
+ byte track = _diskDataDesc[disk].track;
+ byte sector = _diskDataDesc[disk].sector;
+ uint offset = _diskDataDesc[disk].offset;
- // Load message offsets
- stream.reset(_disk->createReadStream(0x1f, 0xb, 0x16, 4));
- for (uint i = 0; i < IDI_HR6_NUM_MESSAGES; ++i)
- _messages.push_back(readDataBlockPtr(*stream));
+ applyDataBlockOffset(track, sector);
- // Load commands
- stream.reset(_disk->createReadStream(0x21, 0x4, 0x85, 7));
- readCommands(*stream, _roomCommands);
+ StreamPtr stream;
- stream.reset(_disk->createReadStream(0x20, 0xf, 0x82, 5));
- readCommands(*stream, _globalCommands);
+ for (uint block = 0; block < 7; ++block) {
+ stream.reset(_disk->createReadStream(track, sector, offset, 1));
- // Load verbs
- stream.reset(_disk->createReadStream(0x1f, 0xf, 0x56, 6));
- loadWords(*stream, _verbs, _priVerbs);
+ uint16 addr = stream->readUint16LE();
+ uint16 size = stream->readUint16LE();
- // Load nouns
- stream.reset(_disk->createReadStream(0x20, 0x5, 0x8e, 8));
- loadWords(*stream, _nouns, _priNouns);
+ stream.reset(_disk->createReadStream(track, sector, offset, size / 256 + 1));
+ stream->skip(4);
- delete boot;
+ switch (addr) {
+ case 0x9000: {
+ // Messages
+ _messages.clear();
+ uint count = size / 4;
+ for (uint i = 0; i < count; ++i)
+ _messages.push_back(readDataBlockPtr(*stream));
+ break;
+ }
+ case 0x4a80: {
+ // Global pics
+ _pictures.clear();
+ byte picNr;
+ while ((picNr = stream->readByte()) != 0xff) {
+ if (stream->eos() || stream->err())
+ error("Error reading global pic list");
+ _pictures[picNr] = readDataBlockPtr(*stream);
+ }
+ break;
+ }
+ case 0x4000:
+ // Verbs
+ loadWords(*stream, _verbs, _priVerbs);
+ break;
+ case 0x1800:
+ // Nouns
+ loadWords(*stream, _nouns, _priNouns);
+ break;
+ case 0x0e00: {
+ // Rooms
+ uint count = size / 14 - 1;
+ stream->skip(14); // Skip invalid room 0
+
+ _state.rooms.clear();
+ for (uint i = 0; i < count; ++i) {
+ Room room;
+ stream->readByte(); // number
+ for (uint j = 0; j < 6; ++j)
+ room.connections[j] = stream->readByte();
+ room.data = readDataBlockPtr(*stream);
+ room.picture = stream->readByte();
+ room.curPicture = stream->readByte();
+ room.isFirstTime = stream->readByte();
+ _state.rooms.push_back(room);
+ }
+ break;
+ }
+ case 0x7b00:
+ // Global commands
+ readCommands(*stream, _globalCommands);
+ break;
+ case 0x9500:
+ // Room commands
+ readCommands(*stream, _roomCommands);
+ break;
+ default:
+ error("Unknown data block found (addr %04x; size %04x)", addr, size);
+ }
+
+ offset += 4 + size;
+ while (offset >= 256) {
+ offset -= 256;
+ ++sector;
+ if (sector >= 16) {
+ sector = 0;
+ ++track;
+ }
+ }
+ }
+
+ // Load item picture data (indexed on boot disk)
+ stream.reset(_boot->createReadStream(0xb, 0xd, 0x08));
+ _itemPics.clear();
+ for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
+ stream->readByte();
+ _itemPics.push_back(readDataBlockPtr(*stream));
+ }
}
void HiRes6Engine::initGameState() {
_state.vars.resize(IDI_HR6_NUM_VARS);
- StreamPtr stream(_disk->createReadStream(0x20, 0xd, 0x94, 2));
-
- for (uint i = 0; i < IDI_HR6_NUM_ROOMS; ++i) {
- Room room;
- stream->readByte(); // number
- for (uint j = 0; j < 6; ++j)
- room.connections[j] = stream->readByte();
- room.data = readDataBlockPtr(*stream);
- room.picture = stream->readByte();
- room.curPicture = stream->readByte();
- room.isFirstTime = stream->readByte();
- _state.rooms.push_back(room);
- }
+ loadDisk(1);
- stream.reset(_disk->createReadStream(0x22, 0x0, 0x07, 0));
+ StreamPtr stream(_boot->createReadStream(0x3, 0xe, 0x03));
byte id;
while ((id = stream->readByte()) != 0xff) {
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 443a9ca..aa3dbf5 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -49,9 +49,23 @@ namespace Adl {
#define IDI_HR6_MSG_ITEM_NOT_HERE 254
#define IDI_HR6_MSG_THANKS_FOR_PLAYING 252
+struct DiskDataDesc {
+ byte track;
+ byte sector;
+ byte offset;
+ byte volume;
+};
+
class HiRes6Engine : public AdlEngine_v3 {
public:
- HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) : AdlEngine_v3(syst, gd), _currVerb(0), _currNoun(0) { }
+ HiRes6Engine(OSystem *syst, const AdlGameDescription *gd) :
+ AdlEngine_v3(syst, gd),
+ _boot(nullptr),
+ _currVerb(0),
+ _currNoun(0) {
+ }
+
+ ~HiRes6Engine() { delete _boot; }
private:
// AdlEngine
@@ -65,7 +79,11 @@ private:
void printString(const Common::String &str);
void applyDataBlockOffset(byte &track, byte §or) const;
+ void loadDisk(byte disk);
+
+ DiskImage_DSK *_boot;
byte _currVerb, _currNoun;
+ Common::Array<DiskDataDesc> _diskDataDesc;
};
} // End of namespace Adl
Commit: 2cdb1d49a5cb0d91d70244383a05d4fed12d1ca2
https://github.com/scummvm/scummvm/commit/2cdb1d49a5cb0d91d70244383a05d4fed12d1ca2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Add stubs for hires6 opcodes
Changed paths:
engines/adl/adl.cpp
engines/adl/adl_v3.cpp
engines/adl/adl_v3.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 761b60c..de2edde 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -544,6 +544,7 @@ Common::Error AdlEngine::run() {
while (1) {
uint verb = 0, noun = 0;
+ _isRestarting = false;
// When restoring from the launcher, we don't read
// input on the first iteration. This is needed to
@@ -553,6 +554,9 @@ Common::Error AdlEngine::run() {
if (!_isRestoring) {
showRoom();
+ if (_isRestarting)
+ continue;
+
_canSaveNow = _canRestoreNow = true;
getInput(verb, noun);
_canSaveNow = _canRestoreNow = false;
@@ -580,17 +584,13 @@ Common::Error AdlEngine::run() {
}
// Restarting does end command processing
- if (_isRestarting) {
- _isRestarting = false;
+ if (_isRestarting)
continue;
- }
doAllCommands(_globalCommands, verb, noun);
- if (_isRestarting) {
- _isRestarting = false;
+ if (_isRestarting)
continue;
- }
advanceClock();
_state.moves++;
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index 9041a47..a017f9a 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -87,18 +87,18 @@ void AdlEngine_v3::setupOpcodeTables() {
// 0x08
Opcode(o1_setPic);
Opcode(o1_printMsg);
- Opcode(o1_setLight);
- Opcode(o1_setDark);
+ Opcode(o3_dummy);
+ Opcode(o3_setTextMode);
// 0x0c
Opcode(o2_moveAllItems);
Opcode(o1_quit);
- OpcodeUnImpl();
+ Opcode(o3_dummy);
Opcode(o2_save);
// 0x10
Opcode(o2_restore);
Opcode(o1_restart);
- Opcode(o2_placeItem);
- Opcode(o1_setItemPic);
+ Opcode(o3_setDisk);
+ Opcode(o3_dummy);
// 0x14
Opcode(o1_resetPic);
Opcode(o1_goDirection<IDI_DIR_NORTH>);
@@ -112,8 +112,8 @@ void AdlEngine_v3::setupOpcodeTables() {
// 0x1c
Opcode(o1_dropItem);
Opcode(o1_setRoomPic);
- Opcode(o2_tellTime);
- Opcode(o2_setRoomFromVar);
+ Opcode(o3_sound);
+ OpcodeUnImpl();
// 0x20
Opcode(o2_initDisk);
}
@@ -188,4 +188,45 @@ int AdlEngine_v3::o3_moveItem(ScriptEnv &e) {
return 2;
}
+int AdlEngine_v3::o3_dummy(ScriptEnv &e) {
+ OP_DEBUG_0("\tDUMMY()");
+
+ return 0;
+}
+
+int AdlEngine_v3::o3_setTextMode(ScriptEnv &e) {
+ OP_DEBUG_1("\tSET_TEXT_MODE(%d)", e.arg(1));
+
+ // TODO
+ // 1: 4-line mode
+ // 2: 24-line mode
+
+ switch (e.arg(1)) {
+ case 3:
+ // We re-use the restarting flag here, to simulate a long jump
+ _isRestarting = true;
+ return -1;
+ }
+
+ return 1;
+}
+
+int AdlEngine_v3::o3_setDisk(ScriptEnv &e) {
+ OP_DEBUG_2("\tSET_DISK(%d, %d)", e.arg(1), e.arg(2));
+
+ // TODO
+ // Arg 1: disk
+ // Arg 2: room
+
+ return 2;
+}
+
+int AdlEngine_v3::o3_sound(ScriptEnv &e) {
+ OP_DEBUG_0("\tSOUND()");
+
+ // TODO
+
+ return 0;
+}
+
} // End of namespace Adl
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 77b64fd..b36c97e 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -51,6 +51,10 @@ protected:
int o3_isNounNotInRoom(ScriptEnv &e);
int o3_skipOneCommand(ScriptEnv &e);
int o3_moveItem(ScriptEnv &e);
+ int o3_dummy(ScriptEnv &e);
+ int o3_setTextMode(ScriptEnv &e);
+ int o3_setDisk(ScriptEnv &e);
+ int o3_sound(ScriptEnv &e);
Common::Array<Common::String> _itemDesc;
byte _curDisk;
Commit: 12fe7dabab6d8256f5c50e77c84c33cb769a907b
https://github.com/scummvm/scummvm/commit/12fe7dabab6d8256f5c50e77c84c33cb769a907b
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix debug output in 'move all items' opcode
Changed paths:
engines/adl/adl_v2.cpp
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 55060be..6a3cb25 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -428,7 +428,7 @@ int AdlEngine_v2::o2_moveItem(ScriptEnv &e) {
}
int AdlEngine_v2::o2_moveAllItems(ScriptEnv &e) {
- OP_DEBUG_2("\tMOVE_ALL_ITEMS(%d %d)", roomStr(e.arg(1)).c_str(), roomStr(e.arg(2)).c_str());
+ OP_DEBUG_2("\tMOVE_ALL_ITEMS(%s, %s)", itemRoomStr(e.arg(1)).c_str(), itemRoomStr(e.arg(2)).c_str());
byte room1 = roomArg(e.arg(1));
Commit: d435f5b4ebd0d2fe0a8d8ac260d69fb67ed7650f
https://github.com/scummvm/scummvm/commit/d435f5b4ebd0d2fe0a8d8ac260d69fb67ed7650f
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix item rendering in hires6
Changed paths:
engines/adl/adl_v2.cpp
engines/adl/adl_v2.h
engines/adl/adl_v3.cpp
engines/adl/adl_v3.h
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp
index 6a3cb25..4fdf796 100644
--- a/engines/adl/adl_v2.cpp
+++ b/engines/adl/adl_v2.cpp
@@ -357,8 +357,6 @@ DataBlockPtr AdlEngine_v2::readDataBlockPtr(Common::ReadStream &f) const {
if (track == 0 && sector == 0 && offset == 0 && size == 0)
return DataBlockPtr();
- applyDataBlockOffset(track, sector);
-
return _disk->getDataBlock(track, sector, offset, size);
}
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 164af7d..508af91 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -54,8 +54,7 @@ protected:
virtual void showRoom();
void takeItem(byte noun);
- virtual void applyDataBlockOffset(byte &track, byte §or) const { }
- DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+ virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
void checkTextOverflow(char c);
diff --git a/engines/adl/adl_v3.cpp b/engines/adl/adl_v3.cpp
index a017f9a..623db66 100644
--- a/engines/adl/adl_v3.cpp
+++ b/engines/adl/adl_v3.cpp
@@ -31,7 +31,7 @@ namespace Adl {
AdlEngine_v3::AdlEngine_v3(OSystem *syst, const AdlGameDescription *gd) :
AdlEngine_v2(syst, gd),
- _curDisk(1) {
+ _curDisk(0) {
}
Common::String AdlEngine_v3::loadMessage(uint idx) const {
@@ -49,6 +49,33 @@ Common::String AdlEngine_v3::getItemDescription(const Item &item) const {
return _itemDesc[item.id - 1];
}
+void AdlEngine_v3::applyDiskOffset(byte &track, byte §or) const {
+ sector += _diskOffsets[_curDisk].sector;
+ if (sector >= 16) {
+ sector -= 16;
+ ++track;
+ }
+
+ track += _diskOffsets[_curDisk].track;
+}
+
+DataBlockPtr AdlEngine_v3::readDataBlockPtr(Common::ReadStream &f) const {
+ byte track = f.readByte();
+ byte sector = f.readByte();
+ byte offset = f.readByte();
+ byte size = f.readByte();
+
+ if (f.eos() || f.err())
+ error("Error reading DataBlockPtr");
+
+ if (track == 0 && sector == 0 && offset == 0 && size == 0)
+ return DataBlockPtr();
+
+ applyDiskOffset(track, sector);
+
+ return _disk->getDataBlock(track, sector, offset, size);
+}
+
typedef Common::Functor1Mem<ScriptEnv &, int, AdlEngine_v3> OpcodeV3;
#define SetOpcodeTable(x) table = &x;
#define Opcode(x) table->push_back(new OpcodeV3(this, &AdlEngine_v3::x))
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index b36c97e..16f61ea 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -32,6 +32,11 @@ namespace Common{
class RandomSource;
}
+struct DiskOffset {
+ byte track;
+ byte sector;
+};
+
namespace Adl {
class AdlEngine_v3 : public AdlEngine_v2 {
@@ -46,6 +51,11 @@ protected:
virtual Common::String loadMessage(uint idx) const;
Common::String getItemDescription(const Item &item) const;
+ // AdlEngine_v2
+ virtual DataBlockPtr readDataBlockPtr(Common::ReadStream &f) const;
+
+ void applyDiskOffset(byte &track, byte §or) const;
+
int o3_isVarGT(ScriptEnv &e);
int o3_isItemInRoom(ScriptEnv &e);
int o3_isNounNotInRoom(ScriptEnv &e);
@@ -58,6 +68,7 @@ protected:
Common::Array<Common::String> _itemDesc;
byte _curDisk;
+ Common::Array<DiskOffset> _diskOffsets;
};
} // End of namespace Adl
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index c3c4138..c44a917 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -164,6 +164,15 @@ void HiRes6Engine::init() {
desc.volume = stream->readByte();
_diskDataDesc.push_back(desc);
}
+
+ // DataBlockPtr offsets for each disk
+ stream.reset(_boot->createReadStream(0x3, 0xf, 0x03));
+ for (uint i = 0; i < sizeof(disks); ++i) {
+ DiskOffset offset;
+ offset.track = stream->readByte();
+ offset.sector = stream->readByte();
+ _diskOffsets.push_back(offset);
+ }
}
void HiRes6Engine::loadDisk(byte disk) {
@@ -173,15 +182,23 @@ void HiRes6Engine::loadDisk(byte disk) {
if (!_disk->open(disks[disk]))
error("Failed to open disk image '%s'", disks[disk]);
+ _curDisk = 0;
+
+ // Load item picture data (indexed on boot disk)
+ StreamPtr stream(_boot->createReadStream(0xb, 0xd, 0x08));
+ _itemPics.clear();
+ for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
+ stream->readByte();
+ _itemPics.push_back(readDataBlockPtr(*stream));
+ }
+
_curDisk = disk;
byte track = _diskDataDesc[disk].track;
byte sector = _diskDataDesc[disk].sector;
uint offset = _diskDataDesc[disk].offset;
- applyDataBlockOffset(track, sector);
-
- StreamPtr stream;
+ applyDiskOffset(track, sector);
for (uint block = 0; block < 7; ++block) {
stream.reset(_disk->createReadStream(track, sector, offset, 1));
@@ -261,14 +278,6 @@ void HiRes6Engine::loadDisk(byte disk) {
}
}
}
-
- // Load item picture data (indexed on boot disk)
- stream.reset(_boot->createReadStream(0xb, 0xd, 0x08));
- _itemPics.clear();
- for (uint i = 0; i < IDI_HR6_NUM_ITEM_PICS; ++i) {
- stream->readByte();
- _itemPics.push_back(readDataBlockPtr(*stream));
- }
}
void HiRes6Engine::initGameState() {
@@ -354,11 +363,6 @@ void HiRes6Engine::showRoom() {
_linesPrinted = 0;
}
-void HiRes6Engine::applyDataBlockOffset(byte &track, byte §or) const {
- // FIXME: this uses a table
- ++track;
-}
-
void HiRes6Engine::printString(const Common::String &str) {
Common::String s;
uint found = 0;
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index aa3dbf5..27aa956 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -77,7 +77,6 @@ private:
// AdlEngine_v2
void printString(const Common::String &str);
- void applyDataBlockOffset(byte &track, byte §or) const;
void loadDisk(byte disk);
Commit: f8d75bbc8642ffe3baa56220c05f37eae31c3829
https://github.com/scummvm/scummvm/commit/f8d75bbc8642ffe3baa56220c05f37eae31c3829
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Implement hires6 verb/noun error messages
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index de2edde..f9d04b7 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -855,6 +855,22 @@ Common::String AdlEngine::getWord(const Common::String &line, uint &index) const
}
}
+Common::String AdlEngine::formatVerbError(const Common::String &verbStr) const {
+ Common::String err = _strings.verbError;
+ for (uint i = 0; i < verbStr.size(); ++i)
+ err.setChar(verbStr[i], i + 19);
+ return err;
+}
+
+Common::String AdlEngine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+ Common::String err = _strings.nounError;
+ for (uint i = 0; i < verbStr.size(); ++i)
+ err.setChar(verbStr[i], i + 19);
+ for (uint i = 0; i < nounStr.size(); ++i)
+ err.setChar(nounStr[i], i + 30);
+ return err;
+}
+
void AdlEngine::getInput(uint &verb, uint &noun) {
while (1) {
_display->printString(_strings.enterCommand);
@@ -867,10 +883,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
Common::String verbStr = getWord(line, index);
if (!_verbs.contains(verbStr)) {
- Common::String err = _strings.verbError;
- for (uint i = 0; i < verbStr.size(); ++i)
- err.setChar(verbStr[i], i + 19);
- _display->printString(err);
+ _display->printString(formatVerbError(verbStr));
continue;
}
@@ -879,12 +892,7 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
Common::String nounStr = getWord(line, index);
if (!_nouns.contains(nounStr)) {
- Common::String err = _strings.nounError;
- for (uint i = 0; i < verbStr.size(); ++i)
- err.setChar(verbStr[i], i + 19);
- for (uint i = 0; i < nounStr.size(); ++i)
- err.setChar(nounStr[i], i + 30);
- _display->printString(err);
+ _display->printString(formatNounError(verbStr, nounStr));
continue;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index a23f6b7..9b6a7ea 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,6 +234,8 @@ protected:
Common::String inputString(byte prompt = 0) const;
byte inputKey(bool showCursor = true) const;
+ virtual Common::String formatVerbError(const Common::String &verbStr) const;
+ virtual Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
void checkInput(byte verb, byte noun);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index c44a917..d743d1a 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -363,6 +363,43 @@ void HiRes6Engine::showRoom() {
_linesPrinted = 0;
}
+Common::String HiRes6Engine::formatVerbError(const Common::String &verbStr) const {
+ Common::String err = _strings.verbError;
+
+ for (uint i = 0; i < verbStr.size(); ++i)
+ err.setChar(verbStr[i], i + 24);
+
+ err.setChar(APPLECHAR(' '), 32);
+
+ uint i = 24;
+ while (err[i] != APPLECHAR(' '))
+ ++i;
+
+ err.setChar(APPLECHAR('.'), i);
+
+ return err;
+}
+
+Common::String HiRes6Engine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+ Common::String err = _strings.nounError;
+
+ for (uint i = 0; i < nounStr.size(); ++i)
+ err.setChar(nounStr[i], i + 24);
+
+ for (uint i = 35; i > 31; --i)
+ err.setChar(APPLECHAR(' '), i);
+
+ uint i = 24;
+ while (err[i] != APPLECHAR(' '))
+ ++i;
+
+ err.setChar(APPLECHAR('I'), i + 1);
+ err.setChar(APPLECHAR('S'), i + 2);
+ err.setChar(APPLECHAR('.'), i + 3);
+
+ return err;
+}
+
void HiRes6Engine::printString(const Common::String &str) {
Common::String s;
uint found = 0;
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 27aa956..439d688 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -74,6 +74,8 @@ private:
void initGameState();
void printRoomDescription();
void showRoom();
+ Common::String formatVerbError(const Common::String &verbStr) const;
+ Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
// AdlEngine_v2
void printString(const Common::String &str);
Commit: 0c2d2b2c925e1a6ec639f6d59fe086b03cb440c2
https://github.com/scummvm/scummvm/commit/0c2d2b2c925e1a6ec639f6d59fe086b03cb440c2
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix GCC 4.9 shadow warnings
Changed paths:
engines/adl/adl.cpp
engines/adl/adl.h
engines/adl/hires6.cpp
engines/adl/hires6.h
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index f9d04b7..de1f8aa 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -855,19 +855,19 @@ Common::String AdlEngine::getWord(const Common::String &line, uint &index) const
}
}
-Common::String AdlEngine::formatVerbError(const Common::String &verbStr) const {
+Common::String AdlEngine::formatVerbError(const Common::String &verb) const {
Common::String err = _strings.verbError;
- for (uint i = 0; i < verbStr.size(); ++i)
- err.setChar(verbStr[i], i + 19);
+ for (uint i = 0; i < verb.size(); ++i)
+ err.setChar(verb[i], i + 19);
return err;
}
-Common::String AdlEngine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+Common::String AdlEngine::formatNounError(const Common::String &verb, const Common::String &noun) const {
Common::String err = _strings.nounError;
- for (uint i = 0; i < verbStr.size(); ++i)
- err.setChar(verbStr[i], i + 19);
- for (uint i = 0; i < nounStr.size(); ++i)
- err.setChar(nounStr[i], i + 30);
+ for (uint i = 0; i < verb.size(); ++i)
+ err.setChar(verb[i], i + 19);
+ for (uint i = 0; i < noun.size(); ++i)
+ err.setChar(noun[i], i + 30);
return err;
}
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 9b6a7ea..ee9bbb3 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -234,8 +234,8 @@ protected:
Common::String inputString(byte prompt = 0) const;
byte inputKey(bool showCursor = true) const;
- virtual Common::String formatVerbError(const Common::String &verbStr) const;
- virtual Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
+ virtual Common::String formatVerbError(const Common::String &verb) const;
+ virtual Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
void loadWords(Common::ReadStream &stream, WordMap &map, Common::StringArray &pri) const;
void readCommands(Common::ReadStream &stream, Commands &commands);
void checkInput(byte verb, byte noun);
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index d743d1a..422e9a9 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -363,11 +363,11 @@ void HiRes6Engine::showRoom() {
_linesPrinted = 0;
}
-Common::String HiRes6Engine::formatVerbError(const Common::String &verbStr) const {
+Common::String HiRes6Engine::formatVerbError(const Common::String &verb) const {
Common::String err = _strings.verbError;
- for (uint i = 0; i < verbStr.size(); ++i)
- err.setChar(verbStr[i], i + 24);
+ for (uint i = 0; i < verb.size(); ++i)
+ err.setChar(verb[i], i + 24);
err.setChar(APPLECHAR(' '), 32);
@@ -380,11 +380,11 @@ Common::String HiRes6Engine::formatVerbError(const Common::String &verbStr) cons
return err;
}
-Common::String HiRes6Engine::formatNounError(const Common::String &verbStr, const Common::String &nounStr) const {
+Common::String HiRes6Engine::formatNounError(const Common::String &verb, const Common::String &noun) const {
Common::String err = _strings.nounError;
- for (uint i = 0; i < nounStr.size(); ++i)
- err.setChar(nounStr[i], i + 24);
+ for (uint i = 0; i < noun.size(); ++i)
+ err.setChar(noun[i], i + 24);
for (uint i = 35; i > 31; --i)
err.setChar(APPLECHAR(' '), i);
diff --git a/engines/adl/hires6.h b/engines/adl/hires6.h
index 439d688..ebd0ce1 100644
--- a/engines/adl/hires6.h
+++ b/engines/adl/hires6.h
@@ -74,8 +74,8 @@ private:
void initGameState();
void printRoomDescription();
void showRoom();
- Common::String formatVerbError(const Common::String &verbStr) const;
- Common::String formatNounError(const Common::String &verbStr, const Common::String &nounStr) const;
+ Common::String formatVerbError(const Common::String &verb) const;
+ Common::String formatNounError(const Common::String &verb, const Common::String &noun) const;
// AdlEngine_v2
void printString(const Common::String &str);
Commit: 9967ae8c521716083f9edd1228a65f5d2eaee65d
https://github.com/scummvm/scummvm/commit/9967ae8c521716083f9edd1228a65f5d2eaee65d
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix more GCC 4.9 shadow warnings
Changed paths:
engines/adl/adl.cpp
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index de1f8aa..b6af549 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -880,23 +880,23 @@ void AdlEngine::getInput(uint &verb, uint &noun) {
return;
uint index = 0;
- Common::String verbStr = getWord(line, index);
+ Common::String verbString = getWord(line, index);
- if (!_verbs.contains(verbStr)) {
- _display->printString(formatVerbError(verbStr));
+ if (!_verbs.contains(verbString)) {
+ _display->printString(formatVerbError(verbString));
continue;
}
- verb = _verbs[verbStr];
+ verb = _verbs[verbString];
- Common::String nounStr = getWord(line, index);
+ Common::String nounString = getWord(line, index);
- if (!_nouns.contains(nounStr)) {
- _display->printString(formatNounError(verbStr, nounStr));
+ if (!_nouns.contains(nounString)) {
+ _display->printString(formatNounError(verbString, nounString));
continue;
}
- noun = _nouns[nounStr];
+ noun = _nouns[nounString];
return;
}
}
Commit: c71740bc5d9f2fae54c5d7722d3e0d0ac7bd7b89
https://github.com/scummvm/scummvm/commit/c71740bc5d9f2fae54c5d7722d3e0d0ac7bd7b89
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix GCC 4.9 missing initializer warnings
Changed paths:
engines/adl/hires1.cpp
engines/adl/hires2.cpp
engines/adl/hires6.cpp
diff --git a/engines/adl/hires1.cpp b/engines/adl/hires1.cpp
index c8b9989..096d8ef 100644
--- a/engines/adl/hires1.cpp
+++ b/engines/adl/hires1.cpp
@@ -229,7 +229,7 @@ void HiRes1Engine::initGameState() {
stream->seek(IDI_HR1_OFS_ITEMS);
byte id;
while ((id = stream->readByte()) != 0xff) {
- Item item = { };
+ Item item = Item();
item.id = id;
item.noun = stream->readByte();
item.room = stream->readByte();
diff --git a/engines/adl/hires2.cpp b/engines/adl/hires2.cpp
index d1dd065..d8e8a65 100644
--- a/engines/adl/hires2.cpp
+++ b/engines/adl/hires2.cpp
@@ -151,7 +151,7 @@ void HiRes2Engine::initGameState() {
byte id;
while ((id = stream->readByte()) != 0xff) {
- Item item = { };
+ Item item = Item();
item.id = id;
item.noun = stream->readByte();
item.room = stream->readByte();
diff --git a/engines/adl/hires6.cpp b/engines/adl/hires6.cpp
index 422e9a9..c42b416 100644
--- a/engines/adl/hires6.cpp
+++ b/engines/adl/hires6.cpp
@@ -289,7 +289,7 @@ void HiRes6Engine::initGameState() {
byte id;
while ((id = stream->readByte()) != 0xff) {
- Item item = { };
+ Item item = Item();
item.id = id;
item.noun = stream->readByte();
item.room = stream->readByte();
Commit: 9acf6c3838d0aaaf5cff8ea120ec4672cf6fe6c8
https://github.com/scummvm/scummvm/commit/9acf6c3838d0aaaf5cff8ea120ec4672cf6fe6c8
Author: Walter van Niftrik (walter at scummvm.org)
Date: 2016-06-06T20:35:49+02:00
Commit Message:
ADL: Fix formatting
Changed paths:
engines/adl/adl_v2.h
engines/adl/adl_v3.h
engines/adl/graphics.h
diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h
index 508af91..f18972b 100644
--- a/engines/adl/adl_v2.h
+++ b/engines/adl/adl_v2.h
@@ -28,7 +28,7 @@
// Note: this version of ADL redraws only when necessary, but
// this is not currently implemented.
-namespace Common{
+namespace Common {
class RandomSource;
}
diff --git a/engines/adl/adl_v3.h b/engines/adl/adl_v3.h
index 16f61ea..61dd585 100644
--- a/engines/adl/adl_v3.h
+++ b/engines/adl/adl_v3.h
@@ -28,7 +28,7 @@
// Note: this version of ADL redraws only when necessary, but
// this is not currently implemented.
-namespace Common{
+namespace Common {
class RandomSource;
}
diff --git a/engines/adl/graphics.h b/engines/adl/graphics.h
index b422959..3a300fb 100644
--- a/engines/adl/graphics.h
+++ b/engines/adl/graphics.h
@@ -23,7 +23,7 @@
#ifndef ADL_PICTURE_H
#define ADL_PICTURE_H
-namespace Common{
+namespace Common {
class SeekableReadStream;
class Point;
}
More information about the Scummvm-git-logs
mailing list