aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorEugene Sandulenko2004-06-23 01:36:57 +0000
committerEugene Sandulenko2004-06-23 01:36:57 +0000
commit2e0814514c346cc3c7bf091131dce91f99473810 (patch)
tree839a79bfb88adce75c1fce320636f2dbb748b83a /scumm
parenta350fcda0d02806a0593d556745e16226543eaa0 (diff)
downloadscummvm-rg350-2e0814514c346cc3c7bf091131dce91f99473810.tar.gz
scummvm-rg350-2e0814514c346cc3c7bf091131dce91f99473810.tar.bz2
scummvm-rg350-2e0814514c346cc3c7bf091131dce91f99473810.zip
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
Diffstat (limited to 'scumm')
-rw-r--r--scumm/actor.cpp6
-rw-r--r--scumm/gfx.cpp89
-rw-r--r--scumm/gfx.h1
-rw-r--r--scumm/intern.h1
-rw-r--r--scumm/resource.cpp29
-rw-r--r--scumm/resource.h1
-rw-r--r--scumm/script_v6.cpp15
-rw-r--r--scumm/script_v7he.cpp46
-rw-r--r--scumm/scumm.cpp13
-rw-r--r--scumm/scumm.h4
10 files changed, 182 insertions, 23 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp
index 024a8886be..f30327ccde 100644
--- a/scumm/actor.cpp
+++ b/scumm/actor.cpp
@@ -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);
diff --git a/scumm/gfx.cpp b/scumm/gfx.cpp
index a0dea70ff2..d51cea01cb 100644
--- a/scumm/gfx.cpp
+++ b/scumm/gfx.cpp
@@ -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
diff --git a/scumm/gfx.h b/scumm/gfx.h
index f503eada83..ecfe6d2af1 100644
--- a/scumm/gfx.h
+++ b/scumm/gfx.h
@@ -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);
diff --git a/scumm/intern.h b/scumm/intern.h
index 9ee08890a9..8f42802103 100644
--- a/scumm/intern.h
+++ b/scumm/intern.h
@@ -636,6 +636,7 @@ protected:
void o7_unknownFB();
void o7_quitPauseRestart();
void o7_pickupObject();
+ void o7_startSound();
};
class ScummEngine_v7 : public ScummEngine_v6 {
diff --git a/scumm/resource.cpp b/scumm/resource.cpp
index e2fc0d9976..beaa1b7703 100644
--- a/scumm/resource.cpp
+++ b/scumm/resource.cpp
@@ -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) {
diff --git a/scumm/resource.h b/scumm/resource.h
index 567981ee14..77fdd147af 100644
--- a/scumm/resource.h
+++ b/scumm/resource.h
@@ -59,7 +59,6 @@ enum {
};
-const byte *findResource(uint32 tag, const byte *searchin);
const byte *findResourceSmall(uint32 tag, const byte *searchin);
class ResourceIterator {
diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp
index d836c28442..fea6f88b1f 100644
--- a/scumm/script_v6.cpp
+++ b/scumm/script_v6.cpp
@@ -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);
}
diff --git a/scumm/script_v7he.cpp b/scumm/script_v7he.cpp
index a58f4bb129..f29945759c 100644
--- a/scumm/script_v7he.cpp
+++ b/scumm/script_v7he.cpp
@@ -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
diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp
index ad08405d3b..8a4eecbe26 100644
--- a/scumm/scumm.cpp
+++ b/scumm/scumm.cpp
@@ -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) {
diff --git a/scumm/scumm.h b/scumm/scumm.h
index 27908e2d37..625c0823c4 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -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);