mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-01 16:35:20 +00:00
HE 7.0 fixes
o Stub for o7_startSound o graphics decoders o findResource was moved to ScummEngine and extended o 7.0+ titles use akos costumes, so fix that in launcher o more o6_resourceRoutines stubs Now HE 7.0 games (first 320x200 windows ports) show intros and some are playable to some extent. svn-id: r14003
This commit is contained in:
parent
a350fcda0d
commit
2e0814514c
@ -1624,7 +1624,7 @@ void Actor::remapActorPaletteColor(int color, int new_color) {
|
||||
return;
|
||||
}
|
||||
|
||||
akpl = findResource(MKID('AKPL'), akos);
|
||||
akpl = _vm->findResource(MKID('AKPL'), akos);
|
||||
if (!akpl) {
|
||||
warning("Can't remap actor %d, costume %d doesn't contain an AKPL block", number, costume);
|
||||
return;
|
||||
@ -1660,7 +1660,7 @@ void Actor::remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold)
|
||||
return;
|
||||
}
|
||||
|
||||
akpl = findResource(MKID('AKPL'), akos);
|
||||
akpl = _vm->findResource(MKID('AKPL'), akos);
|
||||
if (!akpl) {
|
||||
warning("Can't remap actor %d, costume %d doesn't contain an AKPL block", number, costume);
|
||||
return;
|
||||
@ -1672,7 +1672,7 @@ void Actor::remapActorPalette(int r_fact, int g_fact, int b_fact, int threshold)
|
||||
//skip resource header
|
||||
akpl = RES_DATA(akpl);
|
||||
|
||||
rgbs = findResource(MKID('RGBS'), akos);
|
||||
rgbs = _vm->findResource(MKID('RGBS'), akos);
|
||||
|
||||
if (!rgbs) {
|
||||
warning("Can't remap actor %d costume %d doesn't contain an RGB block", number, costume);
|
||||
|
@ -466,7 +466,11 @@ void ScummEngine::initBGBuffers(int height) {
|
||||
initVirtScreen(kMainVirtScreen, 0, virtscr[0].topline, _screenWidth, height, 1, 1);
|
||||
}
|
||||
|
||||
room = getResourceAddress(rtRoom, _roomResource);
|
||||
if (_heversion >= 70)
|
||||
room = getResourceAddress(rtLast, _roomResource);
|
||||
else
|
||||
room = getResourceAddress(rtRoom, _roomResource);
|
||||
|
||||
if (_version <= 3) {
|
||||
gdi._numZBuffer = 2;
|
||||
} else if (_features & GF_SMALL_HEADER) {
|
||||
@ -488,6 +492,9 @@ void ScummEngine::initBGBuffers(int height) {
|
||||
// in V8 there is no RMIH and num z buffers is in RMHD
|
||||
ptr = findResource(MKID('RMHD'), room);
|
||||
gdi._numZBuffer = READ_LE_UINT32(ptr + 24) + 1;
|
||||
} else if (_heversion >= 70) {
|
||||
ptr = findResource(MKID('RMIH'), room);
|
||||
gdi._numZBuffer = READ_LE_UINT16(ptr + 8) + 1;
|
||||
} else {
|
||||
ptr = findResource(MKID('RMIH'), findResource(MKID('RMIM'), room));
|
||||
gdi._numZBuffer = READ_LE_UINT16(ptr + 8) + 1;
|
||||
@ -566,6 +573,8 @@ void ScummEngine::redrawBGAreas() {
|
||||
}
|
||||
|
||||
void ScummEngine::redrawBGStrip(int start, int num) {
|
||||
byte *room;
|
||||
|
||||
int s = _screenStartStrip + start;
|
||||
|
||||
assert(s >= 0 && (size_t) s < sizeof(gfxUsageBits) / (3 * sizeof(gfxUsageBits[0])));
|
||||
@ -576,7 +585,12 @@ void ScummEngine::redrawBGStrip(int start, int num) {
|
||||
if (_version == 1) {
|
||||
gdi._C64ObjectMode = false;
|
||||
}
|
||||
gdi.drawBitmap(getResourceAddress(rtRoom, _roomResource) + _IM00_offs,
|
||||
if (_heversion >= 70)
|
||||
room = getResourceAddress(rtRoomStart, _roomResource);
|
||||
else
|
||||
room = getResourceAddress(rtRoom, _roomResource);
|
||||
|
||||
gdi.drawBitmap(room + _IM00_offs,
|
||||
&virtscr[0], s, 0, _roomWidth, virtscr[0].height, s, num, 0, _roomStrips);
|
||||
}
|
||||
|
||||
@ -922,7 +936,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi
|
||||
else if (_vm->_version == 8)
|
||||
smap_ptr = ptr;
|
||||
else
|
||||
smap_ptr = findResource(MKID('SMAP'), ptr);
|
||||
smap_ptr = _vm->findResource(MKID('SMAP'), ptr);
|
||||
|
||||
assert(smap_ptr);
|
||||
|
||||
@ -974,7 +988,7 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi
|
||||
};
|
||||
|
||||
for (i = 1; i < numzbuf; i++) {
|
||||
zplane_list[i] = findResource(zplane_tags[i], ptr);
|
||||
zplane_list[i] = _vm->findResource(zplane_tags[i], ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1632,6 +1646,23 @@ bool Gdi::decompressBitmap(byte *bgbak_ptr, const byte *src, int numLinesToProce
|
||||
unkDecodeA_trans(bgbak_ptr, src, numLinesToProcess);
|
||||
break;
|
||||
|
||||
case 134:
|
||||
case 135:
|
||||
case 136:
|
||||
case 137:
|
||||
case 138:
|
||||
decodeStripHE(bgbak_ptr, src, numLinesToProcess, false);
|
||||
break;
|
||||
|
||||
case 144:
|
||||
case 145:
|
||||
case 146:
|
||||
case 147:
|
||||
case 148:
|
||||
useOrDecompress = true;
|
||||
decodeStripHE(bgbak_ptr, src, numLinesToProcess, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Gdi::decompressBitmap: default case %d", code);
|
||||
}
|
||||
@ -2241,6 +2272,56 @@ void Gdi::decodeStrip3DO(byte *dst, const byte *src, int height, byte transpChec
|
||||
}
|
||||
|
||||
|
||||
void Gdi::decodeStripHE(byte *dst, const byte *src, int height, byte transpCheck) {
|
||||
uint32 color, dataBit, data, shift, iteration;
|
||||
|
||||
color = *src;
|
||||
src++;
|
||||
data = READ_LE_UINT24(src);
|
||||
src += 3;
|
||||
shift = 24;
|
||||
|
||||
while (height) {
|
||||
for (iteration = 0; iteration < 8; iteration++) {
|
||||
if (color != _transparentColor || !transpCheck)
|
||||
*dst = color;
|
||||
dst++;
|
||||
if (shift <= 16) {
|
||||
data |= *src << shift;
|
||||
src++;
|
||||
shift += 8;
|
||||
data |= *src << shift;
|
||||
src++;
|
||||
shift += 8;
|
||||
}
|
||||
|
||||
dataBit = data & 1;
|
||||
shift--;
|
||||
data >>= 1;
|
||||
if (dataBit) {
|
||||
dataBit = data & 1;
|
||||
shift--;
|
||||
data >>= 1;
|
||||
if (!dataBit) {
|
||||
color = _decomp_mask & data;
|
||||
shift -= _decomp_shr;
|
||||
data >>= _decomp_shr;
|
||||
} else {
|
||||
dataBit = data & 7;
|
||||
shift -= 3;
|
||||
data >>= 3;
|
||||
if (dataBit >= 4)
|
||||
color += dataBit - 3;
|
||||
else
|
||||
color += dataBit - 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
dst += 312;
|
||||
height--;
|
||||
}
|
||||
}
|
||||
|
||||
#undef NEXT_ROW
|
||||
#undef READ_256BIT
|
||||
|
||||
|
@ -249,6 +249,7 @@ protected:
|
||||
void unkDecode10(byte *dst, const byte *src, int height);
|
||||
void unkDecode11(byte *dst, const byte *src, int height);
|
||||
void decodeStrip3DO(byte *dst, const byte *src, int height, byte transpCheck);
|
||||
void decodeStripHE(byte *dst, const byte *src, int height, byte transpCheck);
|
||||
|
||||
void draw8ColWithMasking(byte *dst, const byte *src, int height, byte *mask);
|
||||
void draw8Col(byte *dst, const byte *src, int height);
|
||||
|
@ -636,6 +636,7 @@ protected:
|
||||
void o7_unknownFB();
|
||||
void o7_quitPauseRestart();
|
||||
void o7_pickupObject();
|
||||
void o7_startSound();
|
||||
};
|
||||
|
||||
class ScummEngine_v7 : public ScummEngine_v6 {
|
||||
|
@ -2283,21 +2283,32 @@ const byte *ResourceIterator::findNext(uint32 tag) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const byte *findResource(uint32 tag, const byte *searchin) {
|
||||
const byte *ScummEngine::findResource(uint32 tag, const byte *searchin) {
|
||||
uint32 curpos, totalsize, size;
|
||||
|
||||
// It seems that in HE games if searchin == NULL, it continues
|
||||
// search from last position
|
||||
assert(searchin);
|
||||
debugC(DEBUG_RESOURCE, "findResource(%s, %lx)", tag2str(tag), searchin);
|
||||
|
||||
searchin += 4;
|
||||
totalsize = READ_BE_UINT32(searchin);
|
||||
curpos = 8;
|
||||
searchin += 4;
|
||||
if (!searchin) {
|
||||
if (_heversion >= 70) {
|
||||
searchin = _resourceLastSearchBuf;
|
||||
totalsize = _resourceLastSearchSize;
|
||||
curpos = 0;
|
||||
} else {
|
||||
assert(searchin);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
searchin += 4;
|
||||
_resourceLastSearchSize = totalsize = READ_BE_UINT32(searchin);
|
||||
curpos = 8;
|
||||
searchin += 4;
|
||||
}
|
||||
|
||||
while (curpos < totalsize) {
|
||||
if (READ_UINT32(searchin) == tag)
|
||||
if (READ_UINT32(searchin) == tag) {
|
||||
_resourceLastSearchBuf = searchin;
|
||||
return searchin;
|
||||
}
|
||||
|
||||
size = READ_BE_UINT32(searchin + 4);
|
||||
if ((int32)size <= 0) {
|
||||
|
@ -59,7 +59,6 @@ enum {
|
||||
};
|
||||
|
||||
|
||||
const byte *findResource(uint32 tag, const byte *searchin);
|
||||
const byte *findResourceSmall(uint32 tag, const byte *searchin);
|
||||
|
||||
class ResourceIterator {
|
||||
|
@ -386,7 +386,7 @@ const char *ScummEngine_v6::getOpcodeDesc(byte i) {
|
||||
int ScummEngine_v6::popRoomAndObj(int *room) {
|
||||
int obj;
|
||||
|
||||
if (_version >= 7) {
|
||||
if (_version >= 7 || _heversion >= 70) {
|
||||
obj = pop();
|
||||
*room = getObjectRoom(obj);
|
||||
} else {
|
||||
@ -1461,6 +1461,7 @@ void ScummEngine_v6::o6_resourceRoutines() {
|
||||
int resid, op;
|
||||
op = fetchScriptByte();
|
||||
|
||||
debug(0, "resourceRoutines op: %d", op);
|
||||
switch (op) {
|
||||
case 100: // SO_LOAD_SCRIPT
|
||||
resid = pop();
|
||||
@ -1586,7 +1587,7 @@ void ScummEngine_v6::o6_resourceRoutines() {
|
||||
// QL_QueGlobForLoad(3, pop(), 1);
|
||||
break;
|
||||
}
|
||||
case 123:
|
||||
case 123:
|
||||
{
|
||||
if (_heversion < 70)
|
||||
error("o6_resourceRoutines: default case %d", op);
|
||||
@ -1597,6 +1598,16 @@ void ScummEngine_v6::o6_resourceRoutines() {
|
||||
// QL_QueGlobForLoad(1, resid, 1);
|
||||
break;
|
||||
}
|
||||
case 233:
|
||||
resid = pop();
|
||||
warning("stub o6_resourceRoutines resource %d, 1", resid);
|
||||
// foo(resid, 1);
|
||||
break;
|
||||
case 235:
|
||||
resid = pop();
|
||||
warning("stub o6_resourceRoutines resource %d, 0", resid);
|
||||
// foo(resid, 0);
|
||||
break;
|
||||
default:
|
||||
error("o6_resourceRoutines: default case %d", op);
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ void ScummEngine_v7he::setupOpcodes() {
|
||||
OPCODE(o6_getOwner),
|
||||
OPCODE(o6_jump),
|
||||
/* 74 */
|
||||
OPCODE(o6_startSound),
|
||||
OPCODE(o7_startSound),
|
||||
OPCODE(o6_stopSound),
|
||||
OPCODE(o6_startMusic),
|
||||
OPCODE(o6_stopObjectScript),
|
||||
@ -644,4 +644,48 @@ void ScummEngine_v7he::o7_pickupObject() {
|
||||
}
|
||||
|
||||
|
||||
void ScummEngine_v7he::o7_startSound() {
|
||||
byte op;
|
||||
op = fetchScriptByte();
|
||||
|
||||
switch (op) {
|
||||
case 224:
|
||||
// _staticVar1 = pop();
|
||||
pop();
|
||||
break;
|
||||
|
||||
case 230:
|
||||
// _staticVar2 = pop();
|
||||
pop();
|
||||
break;
|
||||
|
||||
case 231:
|
||||
// _staticVar3 = pop();
|
||||
pop();
|
||||
break;
|
||||
|
||||
case 232:
|
||||
pop();
|
||||
// _staticVar4 = pop();
|
||||
// _staticVar3 = 0;
|
||||
// _staticVar1 = 11025;
|
||||
// _staticVar2 = VAR(VAR_MUSIC_TIMER);
|
||||
break;
|
||||
|
||||
case 245:
|
||||
// _staticVar5 |= 1;
|
||||
break;
|
||||
|
||||
case 255:
|
||||
// _sound->addSoundToQueue(_staticVar4, _staticVar3, _staticVar2, _staticVar5);
|
||||
// _staticVar5 = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
warning("o7_startSound stub (%d)", op);
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace Scumm
|
||||
|
@ -2060,6 +2060,7 @@ void ScummEngine::startScene(int room, Actor *a, int objectNr) {
|
||||
}
|
||||
|
||||
initRoomSubBlocks();
|
||||
|
||||
if (_features & GF_OLD_BUNDLE)
|
||||
loadRoomObjectsOldBundle();
|
||||
else if (_features & GF_SMALL_HEADER)
|
||||
@ -2149,7 +2150,7 @@ void ScummEngine::startScene(int room, Actor *a, int objectNr) {
|
||||
void ScummEngine::initRoomSubBlocks() {
|
||||
int i;
|
||||
const byte *ptr;
|
||||
byte *roomptr, *searchptr, *roomResPtr;
|
||||
byte *roomptr, *searchptr, *roomResPtr, *roomStartPtr = 0;
|
||||
const RoomHeader *rmhd;
|
||||
|
||||
_ENCD_offs = 0;
|
||||
@ -2169,7 +2170,9 @@ void ScummEngine::initRoomSubBlocks() {
|
||||
|
||||
// Determine the room and room script base address
|
||||
roomResPtr = roomptr = getResourceAddress(rtRoom, _roomResource);
|
||||
if (_version == 8)
|
||||
if (_heversion >= 70)
|
||||
roomStartPtr = getResourceAddress(rtRoomStart, _roomResource);
|
||||
else if (_version == 8)
|
||||
roomResPtr = getResourceAddress(rtRoomScripts, _roomResource);
|
||||
if (!roomptr || !roomResPtr)
|
||||
error("Room %d: data not found (" __FILE__ ":%d)", _roomResource, __LINE__);
|
||||
@ -2222,6 +2225,8 @@ void ScummEngine::initRoomSubBlocks() {
|
||||
_IM00_offs = getObjectImage(roomptr, 1) - roomptr;
|
||||
} else if (_features & GF_SMALL_HEADER) {
|
||||
_IM00_offs = findResourceData(MKID('IM00'), roomptr) - roomptr;
|
||||
} else if (_heversion >= 70) {
|
||||
_IM00_offs = findResource(MKID('IM00'), roomStartPtr) - roomStartPtr;
|
||||
} else {
|
||||
_IM00_offs = findResource(MKID('IM00'), findResource(MKID('RMIM'), roomptr)) - roomptr;
|
||||
}
|
||||
@ -2990,8 +2995,10 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) {
|
||||
|
||||
// There are both Windows and DOS versions of early HE titles
|
||||
// specify correct version here
|
||||
if (game.features & GF_HUMONGOUS && (game.heversion == 60 || game.id == GID_PUTTDEMO))
|
||||
if (game.features & GF_HUMONGOUS && (game.heversion == 60 || game.id == GID_PUTTDEMO)) {
|
||||
game.heversion = 70;
|
||||
game.features |= GF_NEW_COSTUMES;
|
||||
}
|
||||
break;
|
||||
case Common::kPlatformFMTowns:
|
||||
if (game.version == 3) {
|
||||
|
@ -204,6 +204,7 @@ enum ResTypes {
|
||||
rtBox = 15,
|
||||
rtObjectName = 16,
|
||||
rtRoomScripts = 17,
|
||||
rtRoomStart = 17,
|
||||
rtLast = 17,
|
||||
rtNumTypes = 18
|
||||
};
|
||||
@ -626,6 +627,8 @@ protected:
|
||||
byte _expire_counter;
|
||||
byte *_HEV7RoomOffsets;
|
||||
uint32 *_HEV7RoomIntOffsets;
|
||||
const byte *_resourceLastSearchBuf; // FIXME: need to put it to savefile?
|
||||
uint32 _resourceLastSearchSize; // FIXME: need to put it to savefile?
|
||||
|
||||
void allocateArrays();
|
||||
void openRoom(int room);
|
||||
@ -677,6 +680,7 @@ protected:
|
||||
int _lastLoadedRoom;
|
||||
public:
|
||||
const byte *findResourceData(uint32 tag, const byte *ptr);
|
||||
const byte *findResource(uint32 tag, const byte *ptr);
|
||||
int getResourceDataSize(const byte *ptr) const;
|
||||
void dumpResource(const char *tag, int index, const byte *ptr, int length = -1);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user