Complete actor clipping override code for HE games.

Add akos speech queue for HE games
Minor cleanup

svn-id: r14883
This commit is contained in:
Travis Howell 2004-09-04 08:13:48 +00:00
parent 4bd05071e5
commit 255736dfb7
9 changed files with 203 additions and 128 deletions

View file

@ -65,11 +65,6 @@ Actor::Actor() {
memset(&walkdata, 0, sizeof(ActorWalkData));
walkdata.point3.x = 32000;
clipOverride.right = 0;
clipOverride.left = 0;
clipOverride.top = 0;
clipOverride.bottom = 0;
walkScript = 0;
initActor(1);
@ -138,6 +133,11 @@ void Actor::initActor(int mode) {
walkScript = 0;
talkScript = 0;
clipOverride.right = _vm->_actorClipRight;
clipOverride.left = _vm->_actorClipLeft;
clipOverride.top = _vm->_actorClipTop;
clipOverride.bottom = _vm->_actorClipBottom;
_vm->_classData[number] = (_vm->_version >= 7) ? _vm->_classData[0] : 0;
}

View file

@ -739,8 +739,16 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) {
v1.skip_width = _width;
v1.scaleXstep = _mirror ? 1 : -1;
if (_clipOverride.bottom)
rect.bottom = _clipOverride.bottom;
if (_vm->_heversion >= 71) {
if (rect.top < _clipOverride.top)
rect.top = _clipOverride.top;
if (rect.bottom > _clipOverride.bottom)
rect.bottom = _clipOverride.bottom;
if (rect.left < _clipOverride.left)
rect.left = _clipOverride.left;
if (rect.right > _clipOverride.right)
rect.right = _clipOverride.right;
}
if (_actorHitMode) {
if (_actorHitX < rect.left || _actorHitX >= rect.right || _actorHitY < rect.top || _actorHitY >= rect.bottom)
@ -1012,8 +1020,16 @@ byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) {
maxw = _outwidth;
maxh = _outheight;
if (_clipOverride.bottom)
clip.bottom = _clipOverride.bottom;
if (_vm->_heversion >= 71) {
if (clip.top < _clipOverride.top)
clip.top = _clipOverride.top;
if (clip.bottom > _clipOverride.bottom)
clip.bottom = _clipOverride.bottom;
if (clip.left < _clipOverride.left)
clip.left = _clipOverride.left;
if (clip.right > _clipOverride.right)
clip.right = _clipOverride.right;
}
_vm->markRectAsDirty(kMainVirtScreen, clip, _actorID);
@ -1363,7 +1379,7 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const
flag_value = true;
continue;
case AKC_C0A0:
//akos_queCommand(8, a, GB(2), 0);
akos_queCommand(8, a, GB(2), 0);
continue;
case AKC_C0A1:
if (a->talking) {
@ -1378,7 +1394,7 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const
}
continue;
case AKC_C0A3:
//akos_queCommand(8, a, a->getAnimVar(GB(2), 0);
akos_queCommand(8, a, a->getAnimVar(GB(2)), 0);
continue;
case AKC_C016:
if (_sound->isSoundRunning( a->sound[a->getAnimVar(GB(4))])) {
@ -1481,7 +1497,17 @@ void ScummEngine::akos_processQueue() {
}
break;
case 8:
if (param_1 != 0) {
if (_heversion >= 71) {
_actorToPrintStrFor = a->number;
a->talkPosX = _queueTalkPosX[param_1];
a->talkPosY = _queueTalkPosY[param_1];
a->talkColor = _queueTalkColor[param_1];
_string[0].loadDefault();
actorTalk(_queueTalkString[param_1]);
} else if (param_1 != 0) {
if (_imuseDigital) {
_imuseDigital->setPan(param_1, param_2);
}

View file

@ -746,6 +746,7 @@ protected:
void o72_readINI();
void o72_writeINI();
void o72_unknownF4();
void o72_unknownF5();
void o72_unknownF6();
void o72_unknownF8();
void o72_unknownF9();

View file

@ -2945,11 +2945,11 @@ void ScummEngine_v6::o6_stopTalking() {
}
void ScummEngine_v6::o6_findAllObjects() {
int a = pop();
int room = pop();
int i = 1;
if (a != _currentRoom)
warning("o6_findAllObjects: current room is not %d", a);
if (room != _currentRoom)
warning("o6_findAllObjects: current room is not %d", room);
writeVar(0, 0);
defineArray(0, kIntArray, 0, _numLocalObjects + 1);
writeArray(0, 0, 0, _numLocalObjects);

View file

@ -549,7 +549,7 @@ void ScummEngine_v6he::o6_roomOps() {
void ScummEngine_v6he::o6_actorOps() {
Actor *a;
int i, j, k, l;
int i, j, k;
int args[8];
byte b;
byte name[256];
@ -571,18 +571,18 @@ void ScummEngine_v6he::o6_actorOps() {
break;
case 30:
// _heversion >= 70
l = pop();
k = pop();
j = pop();
i = pop();
_actorClipBottom = pop();
_actorClipRight = pop();
_actorClipTop = pop();
_actorClipLeft = pop();
warning("o6_actorOps: stub case %d", b);
break;
case 64:
// _heversion >= 72
l = pop();
k = pop();
j = pop();
i = pop();
_actorClipBottom = pop();
_actorClipRight = pop();
_actorClipTop = pop();
_actorClipLeft = pop();
warning("o6_actorOps: stub case %d", b);
break;
case 76: // SO_COSTUME
@ -720,12 +720,16 @@ void ScummEngine_v6he::o6_actorOps() {
break;
case 225:
{
byte string[256];
byte string[128];
copyScriptString(string);
_actorToPrintStrFor = pop();
_string[0].loadDefault();
actorTalk(string);
warning("o6_actorOps: stub case %d", b);
int slot = pop();
int len = resStrLen(string) + 1;
addMessageToStack(string, _queueTalkString[slot], len);
_queueTalkPosX[slot] = a->talkPosX;
_queueTalkPosY[slot] = a->talkPosY;
_queueTalkColor[slot] = a->talkColor;
break;
}
default:
@ -790,7 +794,7 @@ void ScummEngine_v6he::o6_kernelSetFunctions() {
//Used before mini games in 3DO versions, seems safe to ignore.
break;
default:
warning("o6_kernelSetFunctions: default case %d (param count %d)", args[0], num);
error("o6_kernelSetFunctions: default case %d (param count %d)", args[0], num);
break;
}
}
@ -860,7 +864,6 @@ void ScummEngine_v6he::o6_kernelGetFunctions() {
case 1:
// Used to store images when decorating cake in
// Fatty Bear's Birthday Surprise
// XXX gdi_virtScreen = 0;
writeVar(0, 0);
defineArray(0, kByteArray, 0, virtScreenSave(0, args[1], args[2], args[3], args[4]));
retval = readVar(0);
@ -869,7 +872,7 @@ void ScummEngine_v6he::o6_kernelGetFunctions() {
push(retval);
break;
default:
warning("o6_kernelGetFunctions: default case %d", args[0]);
error("o6_kernelGetFunctions: default case %d", args[0]);
}
}
@ -1215,7 +1218,7 @@ void ScummEngine_v6he::o6_redimArray() {
redimArray(fetchScriptWord(), newX, newY, kByteArray);
break;
default:
break;
error("o6_redimArray: default type %d", subcode);
}
}

View file

@ -352,7 +352,7 @@ void ScummEngine_v72he::setupOpcodes() {
OPCODE(o72_readINI),
/* F4 */
OPCODE(o72_writeINI),
OPCODE(o6_invalid),
OPCODE(o72_unknownF5),
OPCODE(o72_unknownF6),
OPCODE(o6_invalid),
/* F8 */
@ -752,7 +752,7 @@ void ScummEngine_v72he::o72_drawObject() {
x = pop();
break;
default:
warning("o72_drawObject: default case %d", subOp);
error("o72_drawObject: default case %d", subOp);
}
int object = pop();
@ -782,19 +782,21 @@ void ScummEngine_v72he::o72_getArrayDimSize() {
ArrayHeader *ah;
switch (subOp) {
case 1:
case 3:
ah = (ArrayHeader *)getResourceAddress(rtString, readVar(fetchScriptWord()));
val1 = FROM_LE_32(ah->dim1end);
val2 = FROM_LE_32(ah->dim1start);
push(val1 - val2 + 1);
break;
case 2:
ah = (ArrayHeader *)getResourceAddress(rtString, readVar(fetchScriptWord()));
val1 = FROM_LE_32(ah->dim2end);
val2 = FROM_LE_32(ah->dim2start);
push(val1 - val2 + 1);
break;
case 1:
case 3:
ah = (ArrayHeader *)getResourceAddress(rtString, readVar(fetchScriptWord()));
val1 = FROM_LE_32(ah->dim1end);
val2 = FROM_LE_32(ah->dim1start);
push(val1 - val2 + 1);
break;
case 2:
ah = (ArrayHeader *)getResourceAddress(rtString, readVar(fetchScriptWord()));
val1 = FROM_LE_32(ah->dim2end);
val2 = FROM_LE_32(ah->dim2start);
push(val1 - val2 + 1);
break;
default:
error("o72_getArrayDimSize: default case %d", subOp);
}
}
@ -825,24 +827,21 @@ void ScummEngine_v72he::o72_pickupObject() {
void ScummEngine_v72he::o72_arrayOps() {
byte subOp = fetchScriptByte();
int array = 0;
int array = fetchScriptWord();
int b, c, d, len;
ArrayHeader *ah;
int list[128];
switch (subOp) {
case 7: // SO_ASSIGN_STRING
array = fetchScriptWord();
ah = defineArray(array, kStringArray, 0, 0, 0, 1024);
copyScriptString(ah->data);
break;
case 194: // SO_ASSIGN_STRING
array = fetchScriptWord();
ah = defineArray(array, kStringArray, 0, 0, 0, 4096);
decodeScriptString(ah->data);
break;
case 208: // SO_ASSIGN_INT_LIST
array = fetchScriptWord();
b = pop();
c = pop();
d = readVar(array);
@ -854,7 +853,6 @@ void ScummEngine_v72he::o72_arrayOps() {
}
break;
case 212: // SO_ASSIGN_2DIM_LIST
array = fetchScriptWord();
len = getStackList(list, ARRAYSIZE(list));
d = readVar(array);
if (d == 0)
@ -969,7 +967,7 @@ void ScummEngine_v72he::drawWizImage(int restype, int resnum, int x1, int y1, in
}
Common::Rect rScreen(0, 0, pvs->w, pvs->h);
if (flags & 2) {
// warning("unhandled Wiz image w/ rmap");
warning("unhandled Wiz image w/ rmap");
} else {
copyWizImage(dst, wizd, pvs->w, pvs->h, x1, y1, width, height, &rScreen);
}
@ -1099,7 +1097,7 @@ void ScummEngine_v72he::o72_openFile() {
byte filename[100];
mode = pop();
copyScriptString(filename, true);
copyScriptString(filename);
debug(1,"File %s", filename);
for (r = strlen((char*)filename); r != 0; r--) {
@ -1172,10 +1170,9 @@ void ScummEngine_v72he::o72_readFile() {
push(val);
break;
default:
error("default case %d", subOp);
error("o72_readFile: default case %d", subOp);
}
debug(1, "o72_readFile: slot %d, subOp %d val %d", slot, subOp, val);
}
void ScummEngine_v72he::writeFileFromArray(int slot, int resID) {
@ -1205,8 +1202,9 @@ void ScummEngine_v72he::o72_writeFile() {
writeFileFromArray(slot, resID);
break;
default:
error("default case %d", subOp);
error("o72_writeFile: default case %d", subOp);
}
debug(1, "o72_writeFile: slot %d, subOp %d", slot, subOp);
}
void ScummEngine_v72he::o72_findAllObjects() {
@ -1228,17 +1226,11 @@ void ScummEngine_v72he::o72_findAllObjects() {
}
void ScummEngine_v72he::o72_deleteFile() {
int r;
byte filename[100];
copyScriptString(filename);
for (r = strlen((char*)filename); r != 0; r--) {
if (filename[r - 1] == '\\')
break;
}
debug(1, "stub o72_deleteFile(\"%s\")", filename + r);
debug(1, "stub o72_deleteFile(%s)", filename);
}
void ScummEngine_v72he::o72_getPixel() {
@ -1326,7 +1318,7 @@ void ScummEngine_v72he::o72_redimArray() {
redimArray(fetchScriptWord(), 0, newX, 0, newY, kDwordArray);
break;
default:
break;
error("o72_redimArray: default type %d", subcode);
}
}
@ -1377,7 +1369,7 @@ void ScummEngine_v72he::o72_unknownED() {
}
writeVar(0, array);
while (len >= pos) {
while (len <= pos) {
letter = readArray(0, 0, pos);
if (letter)
result += getCharsetOffset(letter);
@ -1398,6 +1390,7 @@ void ScummEngine_v72he::o72_unknownEF() {
size = len - b + 2;
writeVar(0, 0);
defineArray(0, kStringArray, 0, 0, 0, size);
writeArray(0, 0, 0, 0);
@ -1437,16 +1430,21 @@ void ScummEngine_v72he::o72_unknownF1() {
}
void ScummEngine_v72he::o72_readINI() {
byte name[100];
int type;
int retval;
byte option[100];
int type, retval;
// we pretend that we don't have .ini file
copyScriptString(name);
copyScriptString(option);
type = fetchScriptByte();
switch (type) {
case 6: // number
push(0);
if (!strcmp((char *)option, "ReadPagesAutomatically"))
push(1);
else if (!strcmp((char *)option, "NoPrinting"))
push(1);
else
push(0);
break;
case 7: // string
defineArray(0, kStringArray, 0, 0, 0, 0);
@ -1455,31 +1453,54 @@ void ScummEngine_v72he::o72_readINI() {
push(retval); // var ID string
break;
default:
warning("o72_readINI( read-ini string not implemented", type);
error("o72_readINI: default type %d", type);
}
debug(1, "o72_readINI (%d) %s", type, name);
debug(1, "o72_readINI (%d) %s", type, option);
}
void ScummEngine_v72he::o72_writeINI() {
byte b;
byte name[256], name2[1024];
int type, value;
byte option[256], option2[1024];
b = fetchScriptByte();
type = fetchScriptByte();
copyScriptString(option);
switch (b) {
case 6:
pop();
copyScriptString(name);
switch (type) {
case 6: // number
value = pop();
break;
debug(1,"o72_writeINI stub (%s)", name);
case 7:
copyScriptString(name2);
copyScriptString(name);
debug(1,"o72_writeINI stub (%s, %s)", name, name2);
debug(1,"o72_writeINI: %s set to %d", option, value);
case 7: // string
copyScriptString(option2);
debug(1,"o72_writeINI: %s set to %s", option, option2);
break;
default:
error("o72_writeINI: default type %d", type);
}
}
void ScummEngine_v72he::o72_unknownF5() {
int letter, ebx;
int array, len, pos, result = 0;
ebx = pop();
pos = pop();
array = pop();
len = resStrLen(getStringAddress(array));
writeVar(0, array);
while (pos < len) {
letter = readArray(0, 0, pos);
result += getCharsetOffset(letter);
if (result >= ebx)
break;
pos++;
}
push(result);
debug(1,"stub o72_unknownF5 (%d)", result);
}
void ScummEngine_v72he::o72_unknownF6() {
int len, len2, pos, value, array;
value = pop();
@ -1525,14 +1546,14 @@ void ScummEngine_v72he::o72_unknownF8() {
int a = fetchScriptByte();
push(1);
warning("stub o72_unknownF8(%d)", a);
debug(1,"stub o72_unknownF8(%d)", a);
}
void ScummEngine_v72he::o72_unknownF9() {
// File related
//byte name[100];
//copyScriptString(name);
//debug(1,"o72_unknownF9: %s", name);
//byte filename[100];
//copyScriptString(filename);
//debug(1,"o72_unknownF9: %s", filename);
}
void ScummEngine_v72he::o72_unknownFA() {

View file

@ -383,11 +383,8 @@ const char *ScummEngine_v7he::getOpcodeDesc(byte i) {
byte ScummEngine_v7he::stringLen(byte *ptr) {
byte len;
byte c;
if (!ptr) {
//ptr = _someGlobalPtr;
if (!ptr)
error("ScummEngine_v7he::stringLen(): zero ptr. Undimplemented behaviour");
return 1;
}
len = 0;
c = *ptr++;
@ -409,13 +406,12 @@ byte ScummEngine_v7he::stringLen(byte *ptr) {
int ScummEngine_v7he::getCharsetOffset(int letter) {
int offset, result;
int id = _charset->getCurID();
byte *ptr = getResourceAddress(rtCharset, id);
byte *ptr = getResourceAddress(rtCharset, _string[0]._default.charset);
if (!ptr)
error("getCharsetOffset: charset %d not found!", id);
error("getCharsetOffset: charset %d not found!", _string[0]._default.charset);
offset = READ_LE_UINT32(ptr + 29 + letter + 4);
offset = READ_LE_UINT32(ptr + 29 + letter);
if (offset == 0)
return 0;
@ -673,7 +669,6 @@ void ScummEngine_v7he::o7_resourceRoutines() {
case 122:
case 123:
case 203:
case 239:
debug(5,"stub queueload (%d) resource %d", op, pop());
break;
case 159:
@ -701,7 +696,7 @@ void ScummEngine_v7he::o7_resourceRoutines() {
debug(5,"stub o7_resourceRoutines unlock object %d", resid);
break;
default:
error("o7_resourceRoutines: default case %d", op);
warning("o7_resourceRoutines: default case %d", op);
}
}
@ -750,9 +745,10 @@ void ScummEngine_v7he::o7_unknownED() {
}
writeVar(0, array);
while (len >= pos) {
while (pos <= len) {
letter = readArray(0, 0, pos);
result += getCharsetOffset(letter);
if (letter)
result += getCharsetOffset(letter);
pos++;
}
@ -828,6 +824,7 @@ void ScummEngine_v7he::o7_unknownEF() {
size = len - b + 2;
writeVar(0, 0);
defineArray(0, kStringArray, 0, size);
writeArray(0, 0, 0, 0);
@ -863,14 +860,22 @@ void ScummEngine_v7he::o7_readINI() {
int len;
int type;
int retval;
byte option[256];
// we pretend that we don't have .ini file
addMessageToStack(_scriptPointer, option, sizeof(option));
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
type = pop();
switch (type) {
case 1: // number
push(0);
if (!strcmp((char *)option, "ReadPagesAutomatically"))
push(1);
else if (!strcmp((char *)option, "NoPrinting"))
push(1);
else
push(0);
break;
case 2: // string
defineArray(0, kStringArray, 0, 0);
@ -879,38 +884,34 @@ void ScummEngine_v7he::o7_readINI() {
push(retval); // var ID string
break;
default:
warning("o7_readINI(%d): read-ini string not implemented", type);
error("o7_readINI: default type %d", type);
}
}
void ScummEngine_v7he::o7_writeINI() {
int a, b;
byte filename1[256], filename2[256];
int type, value;
byte option[256], option2[256];
int len;
b = pop();
a = pop();
type = pop();
value = pop();
switch (b) {
case 1:
addMessageToStack(_scriptPointer, filename1, sizeof(filename1));
addMessageToStack(_scriptPointer, option, sizeof(option));
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
debug(1, "o7_writeINI(%d, %d, \"%s\")", a, b, filename1);
switch (type) {
case 1: // number
debug(1, "o7_writeINI: %s set to %d", option, value);
break;
case 2:
addMessageToStack(_scriptPointer, filename1, sizeof(filename1));
case 2: // string
addMessageToStack(_scriptPointer, option2, sizeof(option2));
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
addMessageToStack(_scriptPointer, filename2, sizeof(filename2));
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
debug(1, "o7_writeINI(%d, %d, \"%s\", \"%s\")", a, b, filename1, filename2);
debug(1, "o7_writeINI: %s set to %s", option, option2);
break;
default:
error("o7_writeINI: default type %d", type);
}
}
@ -924,7 +925,7 @@ void ScummEngine_v7he::o7_unknownF5() {
len = resStrLen(getStringAddress(array));
writeVar(0, array);
while (len < pos) {
while (pos < len) {
letter = readArray(0, 0, pos);
result += getCharsetOffset(letter);
if (result >= ebx)
@ -1028,10 +1029,13 @@ void ScummEngine_v7he::o7_unknownFB() {
}
void ScummEngine_v7he::o7_unknownFC() {
int a = pop();
int b = pop();
debug(1,"o7_unknownFC (%d, %d) stub", b, a);
push(1);
// Checks virtual mouse x/y co-ordinates when in verb/inventory area
// Maybe checks for polygons ?
int y = pop();
int x = pop();
push(0);
debug(1,"o7_unknownFC (x %d, y %d) stub", x, y);
}
} // End of namespace Scumm

View file

@ -654,6 +654,11 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
_2byteFontPtr = 0;
_V1_talkingActor = 0;
_actorClipTop = 0;
_actorClipBottom = 479;
_actorClipLeft = 0;
_actorClipRight = 639;
_skipDrawObject = 0;
_skipProcessActors = 0;
_heSndSoundId = 0;
@ -669,6 +674,11 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS
memset(_queueParam2, 0, sizeof(_queueParam2));
_queuePos = 0;
memset(_queueTalkPosX, 0, sizeof(_queueTalkPosX));
memset(_queueTalkPosY, 0, sizeof(_queueTalkPosY));
memset(_queueTalkColor, 0, sizeof(_queueTalkColor));
memset(_queueTalkString, 0, sizeof(_queueTalkString));
//
// Init all VARS to 0xFF
//

View file

@ -844,6 +844,16 @@ public:
int16 _queueParam2[32];
int16 _queuePos;
int16 _queueTalkPosX[16];
int16 _queueTalkPosY[16];
int16 _queueTalkColor[16];
byte _queueTalkString[16][128];
int _actorClipTop;
int _actorClipBottom;
int _actorClipLeft;
int _actorClipRight;
bool akos_increaseAnims(const byte *akos, Actor *a);
bool akos_increaseAnim(Actor *a, int i, const byte *aksq, const uint16 *akfo, int numakfo);
void akos_queCommand(byte cmd, Actor *a, int param_1, int param_2);