AGI: Further work on v1 opcode difference

This commit is contained in:
Eugene Sandulenko 2011-08-11 16:58:04 +01:00
parent af691e46c4
commit 3fb50b815e
5 changed files with 100 additions and 33 deletions

View File

@ -88,6 +88,7 @@ typedef signed int Err;
#define _EMPTY 0xfffff
#define EGO_OWNED 0xff
#define EGO_OWNED_V1 0xf9
#define CRYPT_KEY_SIERRA "Avis Durgan"
#define CRYPT_KEY_AGDS "Alex Simkin"

View File

@ -56,8 +56,13 @@ namespace Agi {
#define getflag(a) state->_vm->getflag(a)
void cmdIncrement(AgiGame *state, uint8 *p) {
if (_v[p0] != 0xff)
++_v[p0];
if (getVersion() < 0x2000) {
if (_v[p0] < 0xf0)
++_v[p0];
} else {
if (_v[p0] != 0xff)
++_v[p0];
}
}
void cmdDecrement(AgiGame *state, uint8 *p) {
@ -115,6 +120,10 @@ void cmdDivV(AgiGame *state, uint8 *p) {
_v[p0] /= _v[p1];
}
void cmdRandomV1(AgiGame *state, uint8 *p) {
_v[p0] = state->_vm->_rnd->getRandomNumber(250);
}
void cmdRandom(AgiGame *state, uint8 *p) {
_v[p2] = state->_vm->_rnd->getRandomNumber(p1 - p0) + p0;
}
@ -399,6 +408,10 @@ void cmdGet(AgiGame *state, uint8 *p) {
state->_vm->objectSetLocation(p0, EGO_OWNED);
}
void cmdGetV1(AgiGame *state, uint8 *p) {
state->_vm->objectSetLocation(p0, EGO_OWNED_V1);
}
void cmdGetF(AgiGame *state, uint8 *p) {
state->_vm->objectSetLocation(_v[p0], EGO_OWNED);
}
@ -732,6 +745,16 @@ void cmdCallF(AgiGame *state, uint8 *p) {
cmdCall(state, &_v[p0]);
}
void cmdDrawPicV1(AgiGame *state, uint8 *p) {
debugC(6, kDebugLevelScripts, "=== draw pic V1 %d ===", _v[p0]);
state->_vm->_picture->decodePicture(_v[p0], true);
state->_vm->clearPrompt();
// Simulate slowww computer. Many effects rely on this
state->_vm->pause(kPausePicture);
}
void cmdDrawPic(AgiGame *state, uint8 *p) {
debugC(6, kDebugLevelScripts, "=== draw pic %d ===", _v[p0]);
state->_vm->_sprites->eraseBoth();
@ -811,11 +834,21 @@ void cmdShowPriScreen(AgiGame *state, uint8 *p) {
}
void cmdAnimateObj(AgiGame *state, uint8 *p) {
if (vt.flags & ANIMATED)
return;
if (getVersion() < 0x2000) {
if (vt.flags & DIDNT_MOVE)
return;
} else {
if (vt.flags & ANIMATED)
return;
}
debugC(4, kDebugLevelScripts, "animate vt entry #%d", p0);
vt.flags = ANIMATED | UPDATE | CYCLING;
if (getVersion() < 0x2000) {
vt.flags |= DIDNT_MOVE;
}
vt.motion = MOTION_NORMAL;
vt.cycle = CYCLE_NORMAL;
vt.direction = 0;
@ -918,6 +951,11 @@ void cmdPosition(AgiGame *state, uint8 *p) {
state->_vm->clipViewCoordinates(&vt);
}
void cmdPositionV1(AgiGame *state, uint8 *p) {
vt.xPos = p1;
vt.yPos = p2;
}
void cmdPositionF(AgiGame *state, uint8 *p) {
vt.xPos = vt.xPos2 = _v[p1];
vt.yPos = vt.yPos2 = _v[p2];
@ -929,6 +967,11 @@ void cmdPositionF(AgiGame *state, uint8 *p) {
state->_vm->clipViewCoordinates(&vt);
}
void cmdPositionFV1(AgiGame *state, uint8 *p) {
vt.xPos = _v[p1];
vt.yPos = _v[p2];
}
void cmdGetPosn(AgiGame *state, uint8 *p) {
state->vars[p1] = (unsigned char)vt.xPos;
state->vars[p2] = (unsigned char)vt.yPos;
@ -1045,8 +1088,14 @@ void cmdFollowEgo(AgiGame *state, uint8 *p) {
vt.parm1 = p1 > vt.stepSize ? p1 : vt.stepSize;
vt.parm2 = p2;
vt.parm3 = 0xff;
setflag(p2, false);
vt.flags |= UPDATE;
if (getVersion() < 0x2000) {
_v[p2] = 0;
vt.flags |= UPDATE | ANIMATED;
} else {
setflag(p2, false);
vt.flags |= UPDATE;
}
}
void cmdMoveObj(AgiGame *state, uint8 *p) {
@ -1061,8 +1110,13 @@ void cmdMoveObj(AgiGame *state, uint8 *p) {
if (p3 != 0)
vt.stepSize = p3;
setflag(p4, false);
vt.flags |= UPDATE;
if (getVersion() < 0x2000) {
_v[p4] = 0;
vt.flags |= UPDATE | ANIMATED;
} else {
setflag(p4, false);
vt.flags |= UPDATE;
}
if (p0 == 0)
state->playerControl = false;

View File

@ -38,6 +38,7 @@ namespace Agi {
#define testGreater(v1, v2) (getvar(v1) > (v2))
#define testIsSet(flag) (getflag(flag))
#define testHas(obj) (state->_vm->objectGetLocation(obj) == EGO_OWNED)
#define testHasV1(obj) (state->_vm->objectGetLocation(obj) == EGO_OWNED_V1)
#define testObjInRoom(obj, v) (state->_vm->objectGetLocation(obj) == getvar(v))
void condEqual(AgiGame *state, uint8 *p) {
@ -92,6 +93,10 @@ void condHas(AgiGame *state, uint8 *p) {
state->testResult = testHas(p[0]);
}
void condHasV1(AgiGame *state, uint8 *p) {
state->testResult = testHasV1(p[0]);
}
void condObjInRoom(AgiGame *state, uint8 *p) {
state->testResult = testObjInRoom(p[0], p[1]);
}

View File

@ -37,7 +37,7 @@ AgiInstruction insV1Test[] = {
{ "greatern", "vn", &condGreater }, // 05
{ "greaterv", "vv", &condGreaterV }, // 06
{ "isset", "v", &condIsSetV1 }, // 07
{ "has", "n", &condHas }, // 08
{ "has", "n", &condHasV1 }, // 08
{ "said", "nnnn", &condSaid2 }, // 09
{ "posn", "nnnnn", &condPosn }, // 0A
{ "controller", "n", &condController }, // 0B
@ -61,20 +61,20 @@ AgiInstruction insV1[] = {
{ "load.view", "n", &cmdLoadView }, // 09
{ "animate.obj", "n", &cmdAnimateObj }, // 0A
{ "new.room", "n", &cmdNewRoomV1 }, // 0B
{ "draw.pic", "v", &cmdDrawPic }, // 0C
{ "print", "s", &cmdPrint }, // 0D
{ "status", "", &cmdStatus }, // 0E
{ "save.game", "", &cmdSaveGame }, // 0F
{ "restore.game", "", &cmdLoadGame }, // 10
{ "...", "", &cmdInitDisk }, // 11 TODO
{ "restart.game", "", &cmdRestartGame }, // 12
{ "random", "v", &cmdRandom }, // 13 TODO: 1 vs 3 vars
{ "get", "n", &cmdGet }, // 14
{ "draw.pic", "v", &cmdDrawPicV1 }, // 0C
{ "print", "s", &cmdPrint }, // 0D TODO
{ "status", "", &cmdStatus }, // 0E TODO
{ "save.game", "", &cmdSaveGame }, // 0F TODO
{ "restore.game", "", &cmdLoadGame }, // 10 TODO
{ "init.disk", "", &cmdInitDisk }, // 11 TODO
{ "restart.game", "", &cmdRestartGame }, // 12 TODO
{ "random", "v", &cmdRandomV1 }, // 13
{ "get", "n", &cmdGetV1 }, // 14
{ "drop", "n", &cmdDrop }, // 15
{ "draw", "n", &cmdDraw }, // 16
{ "erase", "n", &cmdErase }, // 17
{ "position", "nnn", &cmdPosition }, // 18
{ "position.v", "nvv", &cmdPositionF }, // 19
{ "draw", "n", &cmdDraw }, // 16 TODO
{ "erase", "n", &cmdErase }, // 17 TODO
{ "position", "nnn", &cmdPositionV1 }, // 18
{ "position.v", "nvv", &cmdPositionFV1 }, // 19
{ "get.posn", "nvv", &cmdGetPosn }, // 1A
{ "set.cel", "nn", &cmdSetCel }, // 1B
{ "set.loop", "nn", &cmdSetLoop }, // 1C
@ -83,8 +83,8 @@ AgiInstruction insV1[] = {
{ "move.obj", "nnnnn", &cmdMoveObj }, // 1F
{ "set.view", "nn", &cmdSetView }, // 20
{ "follow.ego", "nnn", &cmdFollowEgo }, // 21
{ "...", "", &cmdUnknown }, // 22
{ "...", "", &cmdUnknown }, // 23
{ "...", "", &cmdUnknown }, // 22 # block
{ "...", "", &cmdUnknown }, // 23 # unblock
{ "ignore.blocks", "n", &cmdIgnoreBlocks }, // 24
{ "observe.blocks", "n", &cmdObserveBlocks }, // 25
{ "wander", "n", &cmdWander }, // 26
@ -120,32 +120,33 @@ AgiInstruction insV1[] = {
{ "...", "nn", &cmdUnknown }, // 44
{ "get.v", "v", &cmdUnknown }, // 45
{ "assign.v", "vv", &cmdUnknown }, // 46
{ "...", "n", &cmdUnknown }, // 47
{ "...", "n", &cmdUnknown }, // 47 # printvar.v
{ "get.priority", "nv", &cmdGetPriority }, // 48
{ "ignore.objs", "n", &cmdIgnoreObjs }, // 49
{ "observe.objs", "n", &cmdObserveObjs }, // 4A
{ "distance", "nnv", &cmdDistance }, // 4B
{ "object.on.land", "n", &cmdObjectOnLand }, // 4C
{ "...", "nv", &cmdUnknown }, // 4D set.priority.v???
{ "...", "", &cmdUnknown }, // 4E
{ "load.logics", "n", &cmdLoadLogic }, // 4F TODO: what is the other load.logics then?
{ "...", "nv", &cmdUnknown }, // 4D # set.priority.f
{ "...", "", &cmdUnknown }, // 4E # show.obj
{ "load.logics", "n", &cmdLoadLogic }, // 4F # load.global.logics
{ "display", "nnns", &cmdDisplay }, // 50 TODO: 4 vs 3 args
{ "prevent.input???", "", &cmdUnknown }, // 51
{ "...", "", &cmdUnknown }, // 52
{ "...", "n", &cmdUnknown }, // 53 ???
{ "prevent.input???", "", &cmdUnknown }, // 51
{ "...", "", &cmdUnknown }, // 52 # nop
{ "...", "n", &cmdUnknown }, // 53 # text.screen
{ "...", "", &cmdUnknown }, // 54 ???
{ "stop.motion", "", &cmdStopMotion }, // 55 or force.update??
{ "discard.view", "n", &cmdDiscardView }, // 56
{ "discard.pic", "v", &cmdDiscardPic }, // 57
{ "set.item.view", "nn", &cmdSetItemView }, // 58
{ "...", "", &cmdUnknown }, // 59
{ "...", "", &cmdUnknown }, // 59 # reverse.cycle
{ "last.cel", "nv", &cmdLastCel }, // 5A
{ "set.cel.v", "nv", &cmdSetCelF }, // 5B
{ "...", "", &cmdUnknown }, // 5C
{ "...", "", &cmdUnknown }, // 5C # normal.cycle
{ "load.view", "n", &cmdLoadView }, // 5D
{ "...", "", &cmdUnknown }, // 5E
{ "...", "", &cmdUnknown }, // 5F
{ "setbit", "nv", &cmdUnknown }, // 60
{ "...", "nv", &cmdUnknown }, // 61 # clearbit
};
AgiInstruction insV2Test[] = {

View File

@ -63,6 +63,7 @@ void cmdCall(AgiGame *state, uint8 *p);
void cmdCallF(AgiGame *state, uint8 *p);
void cmdLoadPic(AgiGame *state, uint8 *p); // 0x18
void cmdDrawPic(AgiGame *state, uint8 *p);
void cmdDrawPicV1(AgiGame *state, uint8 *p);
void cmdShowPic(AgiGame *state, uint8 *p);
void cmdDiscardPic(AgiGame *state, uint8 *p);
void cmdOverlayPic(AgiGame *state, uint8 *p);
@ -75,7 +76,9 @@ void cmdUnanimateAll(AgiGame *state, uint8 *p);
void cmdDraw(AgiGame *state, uint8 *p);
void cmdErase(AgiGame *state, uint8 *p);
void cmdPosition(AgiGame *state, uint8 *p);
void cmdPositionV1(AgiGame *state, uint8 *p);
void cmdPositionF(AgiGame *state, uint8 *p);
void cmdPositionFV1(AgiGame *state, uint8 *p);
void cmdGetPosn(AgiGame *state, uint8 *p);
void cmdReposition(AgiGame *state, uint8 *p); // 0x28
void cmdSetView(AgiGame *state, uint8 *p);
@ -130,6 +133,7 @@ void cmdObserveBlocks(AgiGame *state, uint8 *p);
void cmdBlock(AgiGame *state, uint8 *p);
void cmdUnblock(AgiGame *state, uint8 *p);
void cmdGet(AgiGame *state, uint8 *p);
void cmdGetV1(AgiGame *state, uint8 *p);
void cmdGetF(AgiGame *state, uint8 *p);
void cmdDrop(AgiGame *state, uint8 *p);
void cmdPut(AgiGame *state, uint8 *p);
@ -168,6 +172,7 @@ void cmdInitDisk(AgiGame *state, uint8 *p);
void cmdRestartGame(AgiGame *state, uint8 *p); // 0x80
void cmdShowObj(AgiGame *state, uint8 *p);
void cmdRandom(AgiGame *state, uint8 *p);
void cmdRandomV1(AgiGame *state, uint8 *p);
void cmdProgramControl(AgiGame *state, uint8 *p);
void cmdPlayerControl(AgiGame *state, uint8 *p);
void cmdObjStatusF(AgiGame *state, uint8 *p);
@ -237,6 +242,7 @@ void condGreaterV(AgiGame *state, uint8 *p);
void condIsSet(AgiGame *state, uint8 *p);
void condIsSetV(AgiGame *state, uint8 *p);
void condHas(AgiGame *state, uint8 *p);
void condHasV1(AgiGame *state, uint8 *p);
void condObjInRoom(AgiGame *state, uint8 *p);
void condPosn(AgiGame *state, uint8 *p);
void condController(AgiGame *state, uint8 *p);