diff options
-rw-r--r-- | scumm/akos.cpp | 51 | ||||
-rw-r--r-- | scumm/akos.h | 5 | ||||
-rw-r--r-- | scumm/script_v8.cpp | 58 |
3 files changed, 55 insertions, 59 deletions
diff --git a/scumm/akos.cpp b/scumm/akos.cpp index 452330864c..8cd0442202 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -353,22 +353,29 @@ void AkosRenderer::codec1_genericDecode() { do { if (*scaleytab++ < _scaleY) { - masked = (y < _outheight) && v1.mask_ptr && ((mask[0] | mask[v1.imgbufoffs]) & maskbit); - - if (color && y < _outheight && !masked && !skip_column) { - pcolor = palette[color]; - if (_shadow_mode == 1) { - if (pcolor == 13) - pcolor = _shadow_table[*dst]; - } else if (_shadow_mode == 2) { - warning("codec1_spec2"); // TODO - } else if (_shadow_mode == 3) { - if (pcolor < 8) { - pcolor = (pcolor << 8) + *dst; - pcolor = _shadow_table[pcolor]; + if (_actorHitMode) { + if (color && (int16) y == _actorHitY && v1.x == _actorHitX) { + _actorHitResult = true; + return; + } + } else { + masked = (y < _outheight) && v1.mask_ptr && ((mask[0] | mask[v1.imgbufoffs]) & maskbit); + + if (color && y < _outheight && !masked && !skip_column) { + pcolor = palette[color]; + if (_shadow_mode == 1) { + if (pcolor == 13) + pcolor = _shadow_table[*dst]; + } else if (_shadow_mode == 2) { + warning("codec1_spec2"); // TODO + } else if (_shadow_mode == 3) { + if (pcolor < 8) { + pcolor = (pcolor << 8) + *dst; + pcolor = _shadow_table[pcolor]; + } } + *dst = pcolor; } - *dst = pcolor; } dst += _outwidth; mask += _numStrips; @@ -644,7 +651,11 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) { v1.skip_width = _width; v1.scaleXstep = _mirror ? 1 : -1; - _vm->updateDirtyRect(0, x_left, x_right, y_top, y_bottom, _dirty_id); + if (_actorHitMode) { + if (_actorHitX < x_left || _actorHitX >= x_right || _actorHitY < y_top || _actorHitY >= y_bottom) + return 0; + } else + _vm->updateDirtyRect(0, x_left, x_right, y_top, y_bottom, _dirty_id); if (y_top >= (int)_outheight || y_bottom <= 0) return 0; @@ -717,6 +728,11 @@ byte AkosRenderer::codec1(int xmoveCur, int ymoveCur) { byte AkosRenderer::codec5(int xmoveCur, int ymoveCur) { int32 clip_left, clip_right, clip_top, clip_bottom, maxw, maxh; + if (_actorHitMode) { + warning("codec5: _actorHitMode not yet implemented"); + return 0; + } + if (!_mirror) { clip_left = (_actorX - xmoveCur - _width) + 1; } else { @@ -923,6 +939,11 @@ byte AkosRenderer::codec16(int xmoveCur, int ymoveCur) { int32 clip_left, clip_right, clip_top, clip_bottom, maxw, maxh; int32 skip_x, skip_y, cur_x, cur_y; const byte transparency = (_vm->_features & GF_HUMONGOUS) ? 0 : 255; + + if (_actorHitMode) { + warning("codec16: _actorHitMode not yet implemented"); + return 0; + } if (!_mirror) { clip_left = (_actorX - xmoveCur - _width) + 1; diff --git a/scumm/akos.h b/scumm/akos.h index 06572f110b..9cb5979cdd 100644 --- a/scumm/akos.h +++ b/scumm/akos.h @@ -65,8 +65,13 @@ public: aksq = 0; akof = 0; akcd = 0; + _actorHitMode = false; } + bool _actorHitMode; + int16 _actorHitX, _actorHitY; + bool _actorHitResult; + void setPalette(byte *palette); void setFacing(Actor *a); void setCostume(int costume); diff --git a/scumm/script_v8.cpp b/scumm/script_v8.cpp index 764820faee..e2c442cf52 100644 --- a/scumm/script_v8.cpp +++ b/scumm/script_v8.cpp @@ -22,6 +22,7 @@ #include "stdafx.h" #include "scumm.h" #include "actor.h" +#include "akos.h" #include "charset.h" #include "intern.h" #include "sound.h" @@ -1469,52 +1470,21 @@ void Scumm_v8::o8_kernelGetFunctions() { } case 0xD9: { // actorHit - used, for example, to detect ship collision // during ship-to-ship combat. -#if 0 Actor *a = derefActor(args[1], "actorHit"); - int x = args[2]; - int y = args[3]; - - // TODO: this should perform a collision test, i.e. check if - // point (x,y) lies on the given actor or not. - // To achieve this, one needs to consider the current costume - // etc. What the original code seems to do is to draw the - // actor/costume (but maybe in a custom buffer?), and let the - // draw code perform the hit test. - // But I am not 100% clear on this. For example, it probably - // shouldn't touch the gfx usage bits, and some other things... - // So maybe we need dedicated code for this after all? - - warning("actorHit(%d, %d, %d) NYI", args[1], x, y); - -#endif - - push(1); // FIXME - for now always return 1 -/* - // Rough sketch, thanks to DanielFox and ludde - struct SomeStruct { - int RoomHeight, RoomWidth; - byte *ScreenBuffer; - } + AkosRenderer *ar = (AkosRenderer *) _costumeRenderer; + bool old_need_redraw = a->needRedraw; + + ar->_actorHitX = args[2]; + ar->_actorHitY = args[3] + _screenTop; + ar->_actorHitMode = true; + ar->_actorHitResult = false; + + a->needRedraw = true; + a->drawActorCostume(); + a->needRedraw = old_need_redraw; - dword_4FC150 = args[3]; // X - dword_4FC154 = args[2]; // Y - Actor &a = pActors[args[1]]; - Point rel = GetScreenCoordsRelativeToRoom(), pt, scale; - SomeStruct tmp; - - pt.x = a.x + a.field_18 - rel.x; // 18/1C are some kind of - pt.y = a.y + a.field_1C - rel.y; // X/Y offsets... - scale.x = a.scale_x; - scale.y = a.scale_y; - - dword_4FC148 = 2; - graphics_getBuffer1Info(&tmp); // Some kind of get_virtscreen? - chore_drawActor(tmp, actor_nr, &pt, &scale); - - if (dword_4FC148 != 1) // Guess this is changed by - dword_4FC148 = 0; // chore_drawActor - push(dword_4FC148); -*/ + ar->_actorHitMode = false; + push(ar->_actorHitResult); break; } case 0xDA: // lipSyncWidth |