aboutsummaryrefslogtreecommitdiff
path: root/engines/tinsel
diff options
context:
space:
mode:
authorPaul Gilbert2008-12-06 02:07:30 +0000
committerPaul Gilbert2008-12-06 02:07:30 +0000
commit7a4984304721eb91ca5c3349871be1cab228451d (patch)
treea7557cb5f513219cd60b2a8ed8c83b48d6aae6f0 /engines/tinsel
parenta4923c5ba44dc6069dcd469c4a0bcb51b7911597 (diff)
downloadscummvm-rg350-7a4984304721eb91ca5c3349871be1cab228451d.tar.gz
scummvm-rg350-7a4984304721eb91ca5c3349871be1cab228451d.tar.bz2
scummvm-rg350-7a4984304721eb91ca5c3349871be1cab228451d.zip
Beginning of support for DW1 Demo - Interpret has been changed to support opcode differences, and CallLibraryRoutine has a new mapping list of routines
svn-id: r35252
Diffstat (limited to 'engines/tinsel')
-rw-r--r--engines/tinsel/detection.cpp3
-rw-r--r--engines/tinsel/pcode.cpp20
-rw-r--r--engines/tinsel/tinlib.cpp23
-rw-r--r--engines/tinsel/tinsel.h1
4 files changed, 38 insertions, 9 deletions
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index c60a430ee7..5ccb94ce59 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -250,8 +250,6 @@ static const TinselGameDescription gameDescriptions[] = {
},
#endif
-// Currently disabled since it isn't really supported
-#if 0
{ // Demo from http://www.adventure-treff.de/specials/dl_demos.php
{
"dw",
@@ -267,7 +265,6 @@ static const TinselGameDescription gameDescriptions[] = {
GF_DEMO,
TINSEL_V0,
},
-#endif
{ // German CD re-release "Neon Edition"
// Note: This release has ENGLISH.TXT (with german content) instead of GERMAN.TXT
diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp
index 815ce2cd2f..c92a366403 100644
--- a/engines/tinsel/pcode.cpp
+++ b/engines/tinsel/pcode.cpp
@@ -403,7 +403,11 @@ void SaveInterpretContexts(INT_CONTEXT *sICInfo) {
*/
static int32 Fetch(byte opcode, byte *code, int &ip) {
int32 tmp;
- if (opcode & OPSIZE8) {
+ if (TinselV0) {
+ // Fetch a 32 bit value.
+ tmp = (int32)READ_LE_UINT32(code + ip);
+ ip += 4;
+ } else if (opcode & OPSIZE8) {
// Fetch and sign extend a 8 bit value to 32 bits.
tmp = *(int8 *)(code + ip);
ip += 1;
@@ -427,7 +431,13 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
int tmp, tmp2;
int ip = ic->ip;
byte opcode = ic->code[ip++];
- debug(7, " Opcode %d (-> %d)", opcode, opcode & OPMASK);
+ if (TinselV0) {
+ ip += 3; // DW1 demo opcodes are 4 bytes long
+ if ((opcode & OPMASK) > OP_IMM)
+ opcode += 3;
+ }
+
+ debug(7, "ip=%d Opcode %d (-> %d)", ic->ip, opcode, opcode & OPMASK);
switch (opcode & OPMASK) {
case OP_HALT: // end of program
@@ -483,6 +493,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
case OP_CALL: // procedure call
tmp = Fetch(opcode, ic->code, ip);
+ if (TinselV0) tmp *= 4;
//assert(0 <= tmp && tmp < codeSize); // TODO: Verify jumps are not out of bounds
ic->stack[ic->sp + 1] = 0; // static link
ic->stack[ic->sp + 2] = ic->bp; // dynamic link
@@ -516,7 +527,8 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
tmp2 = CallLibraryRoutine(coroParam, tmp, &ic->stack[ic->sp], ic, &ic->resumeState);
if (coroParam)
return;
- ic->sp += tmp2;
+ if (!TinselV0)
+ ic->sp += tmp2;
LockCode(ic);
if (TinselV2 && (ic->resumeState == RES_1))
ic->resumeState = RES_NOT;
@@ -531,7 +543,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
case OP_ALLOC: // allocate storage on stack
- ic->sp += Fetch(opcode, ic->code, ip);
+ ic->sp += (int32)Fetch(opcode, ic->code, ip);
break;
case OP_JUMP: // unconditional jump
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 2313f343e8..b9e8972b69 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -177,6 +177,20 @@ enum MASTER_LIB_CODES {
HIGHEST_LIBCODE
};
+const MASTER_LIB_CODES DW1DEMO_CODES[] = {
+ ACTORREF, ACTORXPOS, ACTORYPOS, ADDTOPIC, ADDINV1, ADDINV2, AUXSCALE, BACKGROUND,
+ CAMERA, CONTROL, CONVERSATION, CONVTOPIC, HIGHEST_LIBCODE, CURSORXPOS, CURSORYPOS,
+ DECCONVW, DECCURSOR, DECFLAGS, DECINVW, DECINV1, DECINV2, DECLEAD, DELICON,
+ DELINV, EVENT, HIGHEST_LIBCODE, HELDOBJECT, HIDEACTOR, ININVENTORY, HIGHEST_LIBCODE,
+ INVENTORY, HIGHEST_LIBCODE, KILLACTOR, KILLBLOCK, KILLTAG, SCREENXPOS,
+ HIGHEST_LIBCODE, MOVECURSOR, NEWSCENE, NOSCROLL, OBJECTHELD, OFFSET, HIGHEST_LIBCODE,
+ PLAY, PLAYSAMPLE, PREPARESCENE, PRINT, PRINTOBJ, PRINTTAG, RESTORESCENE, SAVESCENE,
+ SCANICON, SCROLL, SETACTOR, SETBLOCK, HIGHEST_LIBCODE, SETTAG, SETTIMER, SHOWPOS,
+ SPLAY, STAND, STANDTAG, STOPWALK, HIGHEST_LIBCODE, SWALK, TAGACTOR, TALK,
+ SCREENYPOS, UNTAGACTOR, VIBRATE, WAITFRAME, WAITTIME, WALK, WALKINGACTOR, WALKPOLY,
+ WALKTAG, RANDOM, TIMER
+};
+
const MASTER_LIB_CODES DW1_CODES[] = {
ACTORATTR, ACTORDIRECTION, ACTORREF, ACTORSCALE, ACTORXPOS,
ACTORYPOS, ADDTOPIC, ADDINV1, ADDINV2, ADDOPENINV, AUXSCALE,
@@ -4170,7 +4184,10 @@ int WhichInventory(void) {
* @param pp Top of parameter stack
*/
int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pic, RESUME_STATE *pResumeState) {
- int libCode = TinselV2 ? DW2_CODES[operand] : DW1_CODES[operand];
+ int libCode;
+ if (TinselV0) libCode = DW1DEMO_CODES[operand];
+ else if (!TinselV2) libCode = DW1_CODES[operand];
+ else libCode = DW2_CODES[operand];
debug(7, "CallLibraryRoutine op %d (escOn %d, myEscape %d)", operand, pic->escOn, pic->myEscape);
switch (libCode) {
@@ -4205,7 +4222,9 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
case ACTORREF:
// Common to both DW1 & DW2
- error("actorref isn't a real function!");
+ if (!TinselV0)
+ error("actorref isn't a real function!");
+ return 0;
case ACTORRGB:
// DW2 only
diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h
index 9cb8126567..8e15755d4e 100644
--- a/engines/tinsel/tinsel.h
+++ b/engines/tinsel/tinsel.h
@@ -119,6 +119,7 @@ typedef bool (*KEYFPTR)(const Common::KeyState &);
#define GAME_FRAME_DELAY (1000 / ONE_SECOND)
#define TinselVersion (_vm->getVersion())
+#define TinselV0 (TinselVersion == TINSEL_V0)
#define TinselV2 (TinselVersion == TINSEL_V2)
class TinselEngine : public Engine {