From 7a4984304721eb91ca5c3349871be1cab228451d Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 6 Dec 2008 02:07:30 +0000 Subject: 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 --- engines/tinsel/detection.cpp | 3 --- engines/tinsel/pcode.cpp | 20 ++++++++++++++++---- engines/tinsel/tinlib.cpp | 23 +++++++++++++++++++++-- engines/tinsel/tinsel.h | 1 + 4 files changed, 38 insertions(+), 9 deletions(-) (limited to 'engines/tinsel') 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 { -- cgit v1.2.3