diff options
author | James Brown | 2002-10-06 06:09:32 +0000 |
---|---|---|
committer | James Brown | 2002-10-06 06:09:32 +0000 |
commit | 9612002d78bbf76a80f462ea1036e20739b2d9ca (patch) | |
tree | 0e95813c6499a06f3fd1c6e0c559fa90203b0bed /scumm | |
parent | 14831e74bf681de36e53b02ad7282a25727a7ff4 (diff) | |
download | scummvm-rg350-9612002d78bbf76a80f462ea1036e20739b2d9ca.tar.gz scummvm-rg350-9612002d78bbf76a80f462ea1036e20739b2d9ca.tar.bz2 scummvm-rg350-9612002d78bbf76a80f462ea1036e20739b2d9ca.zip |
Full Throttle / The Dig fixes.
drawDescString (for Full Throttle object names, in the 'ring of fire') is
still somewhat broken. Feel free to fix ;)
svn-id: r5090
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/akos.cpp | 150 | ||||
-rw-r--r-- | scumm/imuse.cpp | 7 | ||||
-rw-r--r-- | scumm/script_v2.cpp | 36 | ||||
-rw-r--r-- | scumm/scumm.h | 1 | ||||
-rw-r--r-- | scumm/string.cpp | 75 |
5 files changed, 226 insertions, 43 deletions
diff --git a/scumm/akos.cpp b/scumm/akos.cpp index ecd97b2b0f..7b420ecb03 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -860,60 +860,136 @@ void AkosRenderer::codec1_ignorePakCols(int num) void AkosRenderer::codec5() { VirtScreen *vs; - BompDrawData bdd; - int moveX; - int moveY; - int left; - int var_20; - int max_width; + int left, right, top, bottom; - int right; - int top; - int bottom; + byte *src, *dest; + int src_x, src_y; + uint dst_x, dst_y; + bool masking; + byte maskbit; + const byte *mask = NULL; + + // I don't know if this is complete. It used to simply call drawBomp() + // to draw an unscaled image, but I don't know if that was because it + // will never have to scale, or if it's because until quite recently + // drawBomp() didn't know how to scale images. + // + // What I do know is that drawBomp() doesn't care about masking and + // shadows, and these are both needed for Full Throttle. + vs = &_vm->virtscr[0]; - //setBlastObjectMode(shadow_mode); // not implemented yet - moveX = move_x_cur; - moveY = move_y_cur; if (!mirror) { - left = (x - moveX - width) + 1; + left = (x - move_x_cur - width) + 1; } else { - left = x + moveX - 1; + left = x + move_x_cur - 1; } - var_20 = 0; - max_width = outwidth; - - right = left + width - 1; - top = y + moveY; - bottom = top + height; + right = left + width; + top = y + move_y_cur; + bottom = top + height + 1; if (left < 0) left = 0; - if (left > max_width) - left -= left - max_width; + if (left > (int) outwidth) + left -= left - outwidth; + + if (top < draw_top) + draw_top = top; + if (bottom > draw_bottom) + draw_bottom = bottom; + + _vm->updateDirtyRect(0, left, right, top, bottom, 1 << dirty_id); - // Yazoo: this is not correct, but fix a lots of bugs for the momment + masking = false; + if (clipping) { + masking = _vm->isMaskActiveAt(left, top, right, bottom, + _vm->getResourceAddress(rtBuffer, 9) + + _vm->gdi._imgBufOffs[clipping] + + _vm->_screenStartStrip) != 0; + } + + v1.mask_ptr = NULL; + + if (masking || charsetmask || shadow_mode) { + v1.mask_ptr = _vm->getResourceAddress(rtBuffer, 9) + + top * 40 + _vm->_screenStartStrip; + v1.imgbufoffs = _vm->gdi._imgBufOffs[clipping]; + if (!charsetmask && masking) { + v1.mask_ptr += v1.imgbufoffs; + v1.imgbufoffs = 0; + } + } - draw_top = 0; - draw_bottom = vs->height; + src = srcptr; + dest = outptr + top * outwidth + left + 1; - _vm->updateDirtyRect(0, left, right + 1, top, bottom + 1, 1 << dirty_id); + for (src_y = 0, dst_y = top; src_y < height; src_y++) { + byte code, color; + uint len, num, i; + byte *d = dest; - bdd.dataptr = srcptr; - bdd.out = outptr; - bdd.outheight = outheight; - bdd.outwidth = outwidth; - bdd.scale_x = 0xFF; - bdd.scale_y = 0xFF; - bdd.srcheight = height; - bdd.srcwidth = width; - bdd.x = left + 1; - bdd.y = top; + if (dst_y < 0 || dst_y >= outheight) { + src += READ_LE_UINT16(src) + 2; + mask += 40; + continue; + } - _vm->drawBomp(&bdd, 0, bdd.dataptr, 0, 0); + len = width; + src_x = 0; + dst_x = left + 1; + src += 2; + + while (src_x <width) { + code = *src++; + num = (code >> 1) + 1; + if (num > len) + num = len; + len -= num; + if (code & 1) { + color = *src++; + for (i = 0; i < num; i++) { + if (dst_x >= 0 && dst_x < outwidth) { + if (color != 255) { + if (v1.mask_ptr) + mask = v1.mask_ptr + (dst_x >> 3); + maskbit = revBitMask[dst_x & 7]; + if (shadow_mode && color == 13) + color = shadow_table[*d]; + if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit)) + *d = color; + } + } + d++; + dst_x++; + src_x++; + } + } else { + for (i = 0; i < num; i++) { + color = src[i]; + if (dst_x >= 0 && dst_x < outwidth) { + if (color != 255) { + if (v1.mask_ptr) + mask = v1.mask_ptr + (dst_x >> 3); + maskbit = revBitMask[dst_x & 7]; + if (shadow_mode && color == 13) + color = shadow_table[*d]; + if (!mask || !((mask[0] | mask[v1.imgbufoffs]) & maskbit)) + *d = color; + } + } + d++; + dst_x++; + src_x++; + } + src += num; + } + } + dest += outwidth; + dst_y++; + } } void AkosRenderer::codec16() diff --git a/scumm/imuse.cpp b/scumm/imuse.cpp index 42627befde..ce528a44f7 100644 --- a/scumm/imuse.cpp +++ b/scumm/imuse.cpp @@ -4855,7 +4855,7 @@ IMuseDigital::~IMuseDigital() { void IMuseDigital::handler() { bool new_mixer; - uint32 l, i, idx = 0; + uint32 l = 0, i = 0; for (l = 0; l < MAX_DIGITAL_CHANNELS;l ++) { if (_channel[l]._used) { @@ -4901,6 +4901,11 @@ void IMuseDigital::handler() { } byte *buf = (byte*)malloc(mixer_size); + if (!buf) { + warning("DigitalMixer exploded: Blame Aquadran :)"); + continue; + } + memcpy(buf, _channel[l]._data + _channel[l]._offset, new_size); if ((new_size != _channel[l]._mixerSize) && (_channel[l]._isJump == true)) { memcpy(buf + new_size, _channel[l]._data + _channel[l]._jump[0]._dest, mixer_size - new_size); diff --git a/scumm/script_v2.cpp b/scumm/script_v2.cpp index c79af8acac..62b6e3ba76 100644 --- a/scumm/script_v2.cpp +++ b/scumm/script_v2.cpp @@ -2535,9 +2535,16 @@ void Scumm::o6_talkActor() _messagePtr = _scriptPointer; if ((_gameId == GID_DIG) && (_messagePtr[0] == '/')) { - _scriptPointer += strlen((char*)_scriptPointer) + 1; + char pointer[20]; + int i, j; + + _scriptPointer += resStrLen((char*)_scriptPointer)+ 1; translateText((char*)_messagePtr, (char*)&transText); - char *pointer = strtok((char *)_messagePtr, "/"); + for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) { + if (_messagePtr[i] != '/') + pointer[j++] = _messagePtr[i]; + } + pointer[j] = 0; _sound->playBundleSound(pointer); _messagePtr = (byte*)&transText; setStringVars(0); @@ -2555,9 +2562,16 @@ void Scumm::o6_talkEgo() _messagePtr = _scriptPointer; if ((_gameId == GID_DIG) && (_messagePtr[0] == '/')) { - _scriptPointer += strlen((char*)_scriptPointer) + 1; + char pointer[20]; + int i, j; + + _scriptPointer += resStrLen((char*)_scriptPointer) + 1; translateText((char*)_messagePtr, (char*)&transText); - char *pointer = strtok((char *)_messagePtr, "/"); + for (i = 0, j = 0; (_messagePtr[i] != '/' || j == 0) && j < 19; i++) { + if (_messagePtr[i] != '/') + pointer[j++] = _messagePtr[i]; + } + pointer[j] = 0; _sound->playBundleSound(pointer); _messagePtr = (byte*)&transText; setStringVars(0); @@ -2722,6 +2736,8 @@ void Scumm::o6_miscOps() speed = 71; else speed = 1000 / _insaneFlag; + if (args[1] == 1) printf("startSmush one is true\n"); + if (args[2] == 1) printf("startSmush two is true\n"); ScummRenderer * sr = new ScummRenderer(this, speed); SmushPlayer * sp = new SmushPlayer(sr); sp->play((char*)getStringAddressVar(VAR_VIDEONAME), getGameDataPath()); @@ -2763,6 +2779,16 @@ void Scumm::o6_miscOps() strcpy((char*)&charset._buffer, (char*)&buf + 13); description(); } + } else { + setStringVars(0); + + _string[0].charset = args[1]; + _string[0].color = args[2]; + _string[0].xpos = args[3]; + _string[0].ypos = args[4]; + + addMessageToStack(getStringAddressVar(VAR_STRING2DRAW)); + drawDescString(); } break; case 17: @@ -3104,7 +3130,7 @@ void Scumm::decodeParseString2(int m, int n) if ((_messagePtr[0] == '/') && (_gameId == GID_DIG)) { translateText((char*)_messagePtr, (char*)&transText); _messagePtr = (byte*)&transText; - _scriptPointer += strlen((char*)_scriptPointer) + 1; + _scriptPointer += resStrLen((char*)_scriptPointer) + 1; switch (m) { case 0: actorTalk(); diff --git a/scumm/scumm.h b/scumm/scumm.h index bd14d72e01..e562b7554a 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -939,6 +939,7 @@ public: int hasCharsetMask(int x, int y, int x2, int y2); void CHARSET_1(); void description(); + void drawDescString(); byte *_msgPtrToAdd; byte *addMessageToStack(byte *msg); void addIntToStack(int var); diff --git a/scumm/string.cpp b/scumm/string.cpp index 3d77a59131..5612a17a5b 100644 --- a/scumm/string.cpp +++ b/scumm/string.cpp @@ -504,6 +504,77 @@ void Scumm::description() gdi._mask_bottom = charset._strBottom; } +void Scumm::drawDescString() +{ + byte byte1=0, chr, *buf, *charsetptr; + uint color, i; + + buf = charset._buffer; + charset._bufPos = 0; + + charset._left2 = charset._left = _string[0].xpos; + charset._top = _string[0].ypos; + charset._curId = _string[0].charset; + charset._center = _string[0].center; + charset._right = _string[0].right; + charset._color = _string[0].color; + + charset._xpos2 = _string[0].xpos; + charset._ypos2 = _string[0].ypos; + charset._disableOffsX = charset._unk12 = 1; + _bkColor = 0; + _talkDelay = 1; + + charset._left -= charset.getStringWidth(0, buf, 0) >> 1; + + restoreCharsetBg(); + + // Read color mapping and height information + charsetptr = getResourceAddress(rtCharset, charset._curId); + assert(charsetptr); + charsetptr += 29; + for (i = 0; i < 4; i++) + charset._colorMap[i] = _charsetData[charset._curId][i]; + + byte1 = charsetptr[1]; // Character height + + for (i = 0; (chr = buf[i++]) != 0;) { + if (chr == 254) + chr = 255; + if (chr == 255) { + chr = buf[i++]; + switch (chr) { + case 9: + case 10: + case 13: + case 14: + i += 2; + break; + case 1: + case 8: + charset._left = charset._left2 - charset.getStringWidth(0, buf, i); + charset._top += byte1; + break; + case 12: + color = buf[i] + (buf[i + 1] << 8); + i += 2; + if (color == 0xFF) + charset._color = _string[0].color; + else + charset._color = color; + break; + } + } else { + charset.printChar(chr); + } + } + + gdi._mask_left = charset._strLeft; + gdi._mask_right = charset._strRight; + gdi._mask_top = charset._strTop; + gdi._mask_bottom = charset._strBottom; +} + void Scumm::drawString(int a) { byte buf[256]; @@ -560,6 +631,10 @@ void Scumm::drawString(int a) charset._left -= charset.getStringWidth(a, buf, 0) >> 1; } + if (!_features & GF_AFTER_V7) + charset._ignoreCharsetMask = 1; + + // Verb text should never time out. if (a == 4) _talkDelay = -1; |