Added initial support for BMAP resources of HE 7.2 games. Doesn't work

correctly yet.

svn-id: r14759
This commit is contained in:
Eugene Sandulenko 2004-08-26 02:47:49 +00:00
parent 0d8488d605
commit 70dbcaf9da
2 changed files with 174 additions and 6 deletions

View File

@ -541,6 +541,7 @@ void ScummEngine::redrawBGAreas() {
int i;
int val;
int diff;
bool cont = true;
if (!(_features & GF_NEW_CAMERA))
if (camera._cur.x != camera._last.x && _charset->_hasMask && (_version > 3 && _gameId != GID_PASS))
@ -548,16 +549,28 @@ void ScummEngine::redrawBGAreas() {
val = 0;
if (_heversion >= 70) {
byte *room = getResourceAddress(rtRoomStart, _roomResource) + _IM00_offs;
if (findResource(MKID('BMAP'), room) != NULL) {
if (_fullRedraw) {
_BgNeedsRedraw = 0;
gdi.drawBMAPBg(room, &virtscr[0], _screenStartStrip, _screenWidth);
}
cont = false;
}
}
// Redraw parts of the background which are marked as dirty.
if (!_fullRedraw && _BgNeedsRedraw) {
if (!_fullRedraw && _BgNeedsRedraw && cont) {
for (i = 0; i != gdi._numStrips; i++) {
if (testGfxUsageBit(_screenStartStrip + i, USAGE_BIT_DIRTY)) {
redrawBGStrip(i, 1);
cont = false;
}
}
}
if (_features & GF_NEW_CAMERA) {
if (_features & GF_NEW_CAMERA && cont) {
diff = camera._cur.x / 8 - camera._last.x / 8;
if (_fullRedraw == 0 && diff == 1) {
val = 2;
@ -1027,11 +1040,14 @@ void Gdi::drawBitmap(const byte *ptr, VirtScreen *vs, int x, int y, const int wi
else
smap_ptr = _vm->findResource(MKID('SMAP'), ptr);
// newer Humongous titles use this
// smap_ptr = _vm->findResource(MKID('BMAP'), ptr);
// HACK Until BMAP support is added
if (smap_ptr == NULL)
if (!smap_ptr) {
// This will go away eventually. HE 7.2 titles used different function
// here which read BMAP. But it was replaced not in every place. So
// this is a placeholder which shows that not all such cases are
// processed yet.
warning("We shouldn't be here, no SMAP");
return;
}
assert(smap_ptr);
@ -1257,6 +1273,137 @@ next_iter:
}
}
/**
* Draw a bitmap onto a virtual screen. This is main drawing method for room backgrounds
* and objects, used throughout in 7.2+ HE versions
*/
void Gdi::drawBMAPBg(const byte *ptr, VirtScreen *vs, int startstrip, int width) {
assert(ptr);
const byte *bmap_ptr;
byte code;
const byte *z_plane_ptr;
byte *mask_ptr;
const byte *zplane_list[9];
bmap_ptr = _vm->findResource(MKID('BMAP'), ptr) + 8;
if (bmap_ptr == NULL) {
error("Room %d has no compressed bitmap?", _vm->_roomResource);
return;
}
code = *bmap_ptr++;
debug(0, "code: %d", code);
if ((code >= 134 && code <= 138) || (code >= 144 && code <= 148)) {
int decomp_shr = code % 10;
int decomp_mask = 0xFF >> (8 - decomp_shr);
decompressBMAPbg((byte *)vs->backBuf + startstrip * 8, width, vs->w, vs->h, bmap_ptr, decomp_shr, decomp_mask);
}
copyVirtScreenBuffers(0, 0, vs->w - 1, vs->h - 1);
if (_numZBuffer <= 1)
return;
const uint32 zplane_tags[] = {
MKID('ZP00'),
MKID('ZP01'),
MKID('ZP02'),
MKID('ZP03'),
MKID('ZP04')
};
for (int i = 1; i < _numZBuffer; i++) {
zplane_list[i] = _vm->findResource(zplane_tags[i], ptr);
}
for (int i = 0; i < _numStrips; i++)
for (int j = 1; j < _numZBuffer; j++) {
uint32 offs;
if (!zplane_list[j])
continue;
offs = READ_LE_UINT16(zplane_list[j] + i * 2 + 8);
mask_ptr = getMaskBuffer(i, 0, j);
if (offs) {
z_plane_ptr = zplane_list[j] + offs;
decompressMaskImg(mask_ptr, z_plane_ptr, vs->h);
}
}
}
void Gdi::decompressBMAPbg(byte *dst, int screenwidth, int w, int h, const byte *ptr, int shr, int mask) {
int reswidth = screenwidth - w;
int al, cl, eax, w_, ebp, ecx, ebx, edx;
// FIXME: This will be translated to C after debugging
ebx = *ptr++;
al = *ptr++;
cl = *ptr++;
eax = (cl << 8) | al;
cl = *ptr++;
eax |= cl << 16;
edx = 24;
do {
w_ = w;
do {
*dst++ = ebx;
if (edx <= 16) {
ebp = *ptr++;
ebp <<= edx;
eax |= ebp;
edx += 8;
ebp = *ptr++;
ebp <<= edx;
eax |= ebp;
edx += 8;
}
ecx = eax & 1;
edx--;
eax >>= 1;
if (ecx) {
ecx = eax & 1;
edx--;
eax >>= 1;
if (!ecx) {
ebx = eax & mask;
edx -= shr;
eax >>= shr;
} else {
ecx = eax & 7;
edx -= 3;
eax >>= 3;
if (ecx >= 4)
ebx += ecx - 3;
else
ebx += ecx - 4;
}
}
} while (--w_ > 0);
dst += reswidth;
} while (--h > 400); // FIXME: should be zero. But overwrites memory due to bugs
}
void Gdi::copyVirtScreenBuffers(int x, int y, int w, int h) {
int rw = w - x + 1;
int rh = h - y + 1;
byte *src, *dst;
src = (byte *)_vm->virtscr[0].backBuf + (_vm->_screenStartStrip + y * _numStrips) * 8 + x;
dst = (byte *)_vm->virtscr[0].pixels + (_vm->_screenStartStrip + y * _numStrips) * 8 + x;
copyBufferBox(dst, src, rw, rh);
_vm->markRectAsDirty(kMainVirtScreen, x, w, y, h, 0);
}
/**
* Reset the background behind an actor or blast object.
*/
@ -1619,6 +1766,22 @@ bool Gdi::decompressBitmap(byte *bgbak_ptr, const byte *src, int numLinesToProce
return useOrDecompress;
}
void Gdi::copyBufferBox(byte *dst, const byte *src, int width, int height) {
assert(width <= _vm->_screenWidth && width > 0);
assert(height <= _vm->_screenHeight && height > 0);
do {
#if defined(SCUMM_NEED_ALIGNMENT)
memcpy(dst, src, width);
#else
for(int i = 0; i < width; i++)
dst[i] = src[i];
#endif
dst += _vm->_screenWidth;
src += _vm->_screenWidth;
} while (--height);
}
void Gdi::draw8Col(byte *dst, const byte *src, int height) {
do {
#if defined(SCUMM_NEED_ALIGNMENT)

View File

@ -252,6 +252,7 @@ protected:
void decodeStrip3DO(byte *dst, const byte *src, int height, byte transpCheck);
void decodeStripHE(byte *dst, const byte *src, int height, byte transpCheck);
void copyBufferBox(byte *dst, const byte *src, int width, int height);
void draw8Col(byte *dst, const byte *src, int height);
void clear8Col(byte *dst, int height);
void decompressMaskImgOr(byte *dst, const byte *src, int height);
@ -262,6 +263,8 @@ protected:
byte *getMaskBuffer(int x, int y, int z);
void decompressBMAPbg(byte *dst, int screenwidth, int w, int h, const byte *ptr, int shr, int mask);
public:
void init();
@ -270,6 +273,8 @@ public:
void drawBitmapV2Helper(const byte *ptr, VirtScreen *vs, int x, int y, const int width, const int height,
int stripnr, int numstrip, StripTable *table);
StripTable *generateStripTable(const byte *src, int width, int height, StripTable *table);
void drawBMAPBg(const byte *ptr, VirtScreen *vs, int startstrip, int width);
void copyVirtScreenBuffers(int x, int y, int w, int h);
void disableZBuffer() { _zbufferDisabled = true; }
void enableZBuffer() { _zbufferDisabled = false; }