aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorJames Brown2002-10-06 06:09:32 +0000
committerJames Brown2002-10-06 06:09:32 +0000
commit9612002d78bbf76a80f462ea1036e20739b2d9ca (patch)
tree0e95813c6499a06f3fd1c6e0c559fa90203b0bed /scumm
parent14831e74bf681de36e53b02ad7282a25727a7ff4 (diff)
downloadscummvm-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.cpp150
-rw-r--r--scumm/imuse.cpp7
-rw-r--r--scumm/script_v2.cpp36
-rw-r--r--scumm/scumm.h1
-rw-r--r--scumm/string.cpp75
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;