Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCUMM: HE: Rewrite the majority of the graphics system #5752

Merged
merged 71 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
165b58f
SCUMM: HE: Preliminar clean up for WIZ rewrite
AndywinXp Jan 31, 2024
f7f7fdc
SCUMM: HE: Preliminar clean up for WIZ rewrite pt.2
AndywinXp Feb 6, 2024
8f84e57
SCUMM: HE: Preliminar clean up for WIZ rewrite pt.3
AndywinXp Feb 7, 2024
c987b98
SCUMM: HE: Preliminar clean up for WIZ rewrite pt.4
AndywinXp Feb 9, 2024
2785798
SCUMM: HE: Begin WIZ and graphics rewrite
AndywinXp Feb 16, 2024
5660efb
SCUMM: HE: Fix pixelDepth value for 16-bit color games
AndywinXp Feb 17, 2024
08bc751
SCUMM: HE: Add some basic WIZ primitives
AndywinXp Feb 18, 2024
31306cb
SCUMM: HE: Fix primitives after testing them
AndywinXp Feb 18, 2024
a5aa564
SCUMM: HE: Continue implementing WIZ stuff
AndywinXp Feb 22, 2024
d0f0c94
SCUMM: HE: Implement FloodFill operation
AndywinXp Feb 24, 2024
8730c0f
SCUMM: HE: Begin porting Wiz and other graphics code
AndywinXp Mar 1, 2024
fd87919
SCUMM: HE: Add auxiliary compression routines and more stuff
AndywinXp Mar 1, 2024
2b63393
SCUMM: HE: Add remaining compression routines
AndywinXp Mar 3, 2024
506d9fc
SCUMM: HE: Fix Wiz warping
AndywinXp Mar 4, 2024
184a00d
SCUMM: HE: Actually fix Wiz warping
AndywinXp Mar 8, 2024
e3b676c
SCUMM: HE: Fix TRLE FLIP comp
AndywinXp Mar 9, 2024
1a702d7
SCUMM: HE: Overhaul more of the GFX system
AndywinXp Mar 13, 2024
6283c24
SCUMM: HE: Bump save version
AndywinXp Mar 13, 2024
43e7c67
SCUMM: HE: Relabel Polygon functions
AndywinXp Mar 14, 2024
79cc007
SCUMM: HE: Implement proper sprite collision
AndywinXp Mar 14, 2024
bba7f87
SCUMM: HE: Clean-up pass
AndywinXp Mar 14, 2024
c8f4810
SCUMM: HE: Fix some transparency issues
AndywinXp Mar 16, 2024
05ef662
SCUMM: HE: Fix more 8-bit vs 16-bit discrepancies
AndywinXp Mar 16, 2024
a58e256
SCUMM: HE: Re-implement WIZ text and Aux images
AndywinXp Mar 17, 2024
9fa756e
SCUMM: HE: Re-implement BMAP routines
AndywinXp Mar 19, 2024
ffca292
SCUMM: HE: Re-implement AKOS TRLE drawing
AndywinXp Mar 19, 2024
ef35c75
SCUMM: HE: Fix TRLE AKOS cels not being erased
AndywinXp Mar 23, 2024
9a62196
SCUMM: HE: Fix several sprite rendering issues
AndywinXp Mar 24, 2024
32bb6e0
SCUMM: HE: More HE95 changes
AndywinXp Mar 24, 2024
20f1ae7
SCUMM: HE: Fix Aux Images rendering
AndywinXp Mar 24, 2024
1fb962f
SCUMM: HE: Fix sub HE95 games not starting
AndywinXp Mar 29, 2024
e1fdc5b
SCUMM: HE: Fix more 8-bit vs 16-bit issues
AndywinXp Mar 29, 2024
f6874fe
SCUMM: HE: Fix remap call
AndywinXp Mar 29, 2024
d890806
SCUMM: HE: More fixes
AndywinXp Mar 29, 2024
3fcfcc4
SCUMM: HE: More 8-bit vs 16-bit fixes
AndywinXp Mar 29, 2024
3af539a
SCUMM: HE: Compression function names cleanup
AndywinXp Mar 30, 2024
98e0336
SCUMM: HE: Fix WARPWIZ issue
AndywinXp Mar 30, 2024
017f18a
SCUMM: HE: More cleanup and changes
AndywinXp Mar 30, 2024
1738d3f
SCUMM: HE: Add new HE variant (99.5) as game feature flag
AndywinXp Mar 30, 2024
f659c69
SCUMM: HE: Fix TRLE compression rect
AndywinXp Mar 30, 2024
b905485
SCUMM: HE: Fix crash in Backyard Football
AndywinXp Mar 30, 2024
370d2df
SCUMM: HE: Fix some games crashing at startup
AndywinXp Mar 30, 2024
efa157b
SCUMM: HE: Mark actual HE99.5 games in detection table
AndywinXp Mar 30, 2024
8718d9f
SCUMM: HE: Fix palette remapping issues
AndywinXp Mar 31, 2024
8c22216
SCUMM: HE: Fix cursor wrong colors
AndywinXp Mar 31, 2024
318f833
SCUMM: HE: Remove useless casts
AndywinXp Mar 31, 2024
dbfa5b8
SCUMM: HE: Fix some Spy Fox 1 (HE90) issues
AndywinXp Apr 5, 2024
2906dbd
SCUMM: HE: Fix some mem leaks
AndywinXp Apr 6, 2024
976c7df
SCUMM: HE: Fix warnings
AndywinXp Apr 6, 2024
ef7f8e4
SCUMM: HE: Fix AUX animations
AndywinXp Apr 6, 2024
9caebc0
SCUMM: HE: Hopefully fix palette remapping for good
AndywinXp Apr 7, 2024
bd0d7fc
SCUMM: HE: Fix sprite ordering for HE95
AndywinXp Apr 7, 2024
331b4e6
SCUMM: HE: Fix pixel color retrieval
AndywinXp Apr 7, 2024
6b5fe8b
SCUMM: HE: Fix Backyard games sprite ordering issues
AndywinXp Apr 7, 2024
924cdec
SCUMM: HE: Swap some tags with MKTAG macros
AndywinXp Apr 8, 2024
f622dcf
SCUMM: HE: Cleanup
AndywinXp Apr 11, 2024
4c21e97
SCUMM: HE: Fix glitched bottom left score table on BASEBALL97
AndywinXp Apr 11, 2024
9524778
SCUMM: HE: Fix typo in palette remapping function
AndywinXp Apr 11, 2024
4d40bc6
SCUMM: HE: Comments and styling clean-up
AndywinXp Apr 12, 2024
193895d
SCUMM: HE: Begin implementing Moonbase Commander graphics hooks
AndywinXp Apr 15, 2024
e549912
SCUMM: HE: Fix null pointer access
AndywinXp Apr 16, 2024
419dc51
SCUMM: HE: Implement more Moonbase graphics
AndywinXp Apr 16, 2024
b7b9811
SCUMM: HE: Clean up and finish hooking up external U32 prototypes
AndywinXp Apr 16, 2024
e9b9a77
SCUMM: HE: Clean-up and removal of development functions
AndywinXp Apr 17, 2024
d180d81
SCUMM: HE: Reimplement Moonbase gfx T14 routine
AndywinXp Apr 18, 2024
1dcfe2f
SCUMM: HE: Reimplement Moonbase distortion routines
AndywinXp Apr 20, 2024
84d64a0
SCUMM: HE: Fix build when ENABLE_HE is not defined
AndywinXp Apr 20, 2024
ffc8d3f
SCUMM: HE: Fix build and warnings
AndywinXp Apr 20, 2024
8e78b9d
SCUMM: HE: Hopefully fix MSVC win32 errors
AndywinXp Apr 21, 2024
b0b0e1b
SCUMM: HE: Fix formatting
AndywinXp Apr 21, 2024
c27b799
SCUMM: HE: Fix another win32 build error
AndywinXp Apr 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
559 changes: 456 additions & 103 deletions engines/scumm/actor.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion engines/scumm/actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class Actor : public Common::Serializable {
bool _heSkipLimbs;
uint32 _heCondMask;
uint32 _hePaletteNum;
uint32 _heXmapNum;
uint32 _heShadow;

protected:
struct ActorWalkData {
Expand Down
42 changes: 23 additions & 19 deletions engines/scumm/actor_he.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,29 @@

namespace Scumm {

struct AuxBlock {
bool visible;
Common::Rect r;

void reset() {
visible = false;
r.left = r.top = 0;
r.right = r.bottom = -1;
}

void clear() {
reset();
r.right = 0;
r.bottom = 0;
}
struct HEEraseAuxEntry {
int actor;
int32 x1, y1, x2, y2;
};

struct AuxEntry {
int actorNum;
int subIndex;
struct HEAnimAuxEntry {
int actor;
int auxIndex;
};

struct HEAnimAuxData {
byte *auxDefaultSearchBlock;
byte *externalDataPtr;
const byte *auxDataBlock;
int actor;
};

struct HEAuxFileRelInfo {
int globFileOffset;
Common::File fileHandle;
int globType;
int globNum;
int roomNum;
};

class ActorHE : public Actor {
Expand Down Expand Up @@ -78,7 +81,8 @@ class ActorHE : public Actor {
bool _heTalking;
byte _heFlags;

AuxBlock _auxBlock;
int _auxActor;
int32 _auxEraseX1, _auxEraseY1, _auxEraseX2, _auxEraseY2;

struct {
int16 posX;
Expand Down
216 changes: 157 additions & 59 deletions engines/scumm/akos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,13 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
uint i, extra;
byte result = 0;
int xMoveCur, yMoveCur;
uint32 heCondMaskIndex[32];
bool useCondMask;
uint32 sequenceLayerIndirection[32];
bool useConditionalTable = false;
int lastDx, lastDy;

lastDx = lastDy = 0;
for (i = 0; i < 32; ++i) {
heCondMaskIndex[i] = i;
sequenceLayerIndirection[i] = i;
}

if (_skipLimbs)
Expand All @@ -333,7 +333,6 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
if (cost.animType[limb] == AKAT_Empty || cost.stopped & (1 << limb))
return 0;

useCondMask = false;
p = _aksq + cost.curpos[limb];

code = p[0];
Expand All @@ -348,11 +347,11 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
uint j = 0;
extra = p[3];
uint8 n = extra;
assert(n <= ARRAYSIZE(heCondMaskIndex));
assert(n <= ARRAYSIZE(sequenceLayerIndirection));
while (n--) {
heCondMaskIndex[j++] = _aksq[s++];
sequenceLayerIndirection[j++] = _aksq[s++];
}
useCondMask = true;
useConditionalTable = true;
p += extra + 2;
code = (code == AKC_CondDrawMany) ? AKC_DrawMany : AKC_RelativeOffsetDrawMany;
}
Expand Down Expand Up @@ -398,7 +397,7 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {

extra = p[2];
p += 3;
uint32 decFlag = heCondMaskIndex[0];
uint32 decFlag = sequenceLayerIndirection[0];

for (i = 0; i != extra; i++) {
code = p[4];
Expand Down Expand Up @@ -428,10 +427,10 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {

uint16 shadowMask = 0;

if (!useCondMask || !_akct) {
if (!useConditionalTable || !_akct) {
decFlag = 1;
} else {
uint32 cond = READ_LE_UINT32(_akct + cost.heCondMaskTable[limb] + heCondMaskIndex[i] * 4);
uint32 cond = READ_LE_UINT32(_akct + cost.heCondMaskTable[limb] + sequenceLayerIndirection[i] * 4);
if (cond == 0) {
decFlag = 1;
} else {
Expand Down Expand Up @@ -476,7 +475,7 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
result |= paintCelMajMin(xMoveCur, yMoveCur);
break;
case AKOS_TRLE_CODEC:
result |= paintCelTRLE(xMoveCur, yMoveCur);
result |= paintCelTRLE(a->_number, a->_drawToBackBuf, xMoveCur, yMoveCur, _width, _height, _akpl[0], _xmap, 0);
break;
default:
error("akos_drawLimb: invalid _codec %d", _codec);
Expand Down Expand Up @@ -1153,57 +1152,153 @@ byte AkosRenderer::paintCelMajMin(int xMoveCur, int yMoveCur) {
return 0;
}

byte AkosRenderer::paintCelTRLE(int xMoveCur, int yMoveCur) {
#ifdef ENABLE_HE
Common::Rect src, dst;

if (!_mirror) {
dst.left = (_actorX - xMoveCur - _width) + 1;
byte AkosRenderer::hePaintCel(int actor, int drawToBack, int celX, int celY, int celWidth, int celHeight, byte tcolor, bool allowFlip, const byte *shadowTablePtr,
void (*drawPtr)(ScummEngine *vm, Wiz *wiz, WizRawPixel *, int, int, Common::Rect *, const byte *, int, int, Common::Rect *, byte, const byte *shadowTablePtr, const WizRawPixel *conversionTable, int32 specialRenderFlags),
const WizRawPixel *conversionTable, int32 specialRenderFlags) {

int plotX, plotY;
bool xFlipFlag, yFlipFlag;
Common::Rect destRect;
Common::Rect sourceRect;
Common::Rect clipRect;
int destBufferWidth, destBufferHeight;
WizRawPixel *destBuffer;
Wiz *wiz = ((ScummEngine_v71he *)_vm)->_wiz;
Actor *a = _vm->derefActor(actor, "hePaintCel");

if (allowFlip) {
yFlipFlag = false;
xFlipFlag = _mirror;
} else {
dst.left = _actorX + xMoveCur;
xFlipFlag = yFlipFlag = false;
}

src.top = src.left = 0;
src.right = _width;
src.bottom = _height;
// Find cel's "plot" position with flipping etc...
plotY = (int32)_actorY + (int32)celY;
plotX = (xFlipFlag) ? (_actorX - celX - celWidth + 1) : (_actorX + celX);

dst.top = _actorY + yMoveCur;
dst.right = dst.left + _width;
dst.bottom = dst.top + _height;
// Find which buffer to plot into. back or forground (STAMP ACTOR)...
VirtScreen *pvs = &_vm->_virtscr[kMainVirtScreen];
destBufferWidth = pvs->w;
destBufferHeight = pvs->h;

int diff;
diff = dst.left - _clipOverride.left;
if (diff < 0) {
src.left -= diff;
dst.left -= diff;
}
diff = dst.right - _clipOverride.right;
if (diff > 0) {
src.right -= diff;
dst.right -= diff;
if (drawToBack) {
destBuffer = (WizRawPixel *)pvs->getBackPixels(0, 0);
} else {
destBuffer = (WizRawPixel *)pvs->getPixels(0, 0);
}
diff = dst.top - _clipOverride.top;
if (diff < 0) {
src.top -= diff;
dst.top -= diff;

// Setup clipping rectangle(s)...
wiz->makeSizedRect(&sourceRect, celWidth, celHeight);
wiz->makeSizedRect(&clipRect, destBufferWidth, destBufferHeight);
wiz->makeSizedRectAt(&destRect, plotX, plotY, celWidth, celHeight);

// Check to see if the actor has a clipping rect...
if ((((ActorHE *)a)->_clipOverride.left < ((ActorHE *)a)->_clipOverride.right) &&
(((ActorHE *)a)->_clipOverride.top < ((ActorHE *)a)->_clipOverride.bottom)) {
// The original evaluates this as '>', but for some reason we need actor clipping
// rectangles to max out at 640x480, instead of 639x479; this *should* not be an issue...
if (destBufferHeight >= ((ActorHE *)a)->_clipOverride.bottom) {
clipRect.left = ((ActorHE *)a)->_clipOverride.left;
clipRect.right = ((ActorHE *)a)->_clipOverride.right;
clipRect.top = ((ActorHE *)a)->_clipOverride.top;
clipRect.bottom = ((ActorHE *)a)->_clipOverride.bottom;
} else {
warning(
"AkosRenderer::hePaintCel(): Actor %d invalid clipping rect (%-3d,%3d,%-3d,%3d)", a->_number,
((ActorHE *)a)->_clipOverride.left, ((ActorHE *)a)->_clipOverride.top,
((ActorHE *)a)->_clipOverride.right, ((ActorHE *)a)->_clipOverride.bottom);
}
}
diff = dst.bottom - _clipOverride.bottom;
if (diff > 0) {
src.bottom -= diff;
dst.bottom -= diff;

// Clip the coords...
wiz->clipRectCoords(&sourceRect, &destRect, &clipRect);

if (wiz->isRectValid(destRect)) {
// Mark the dest area as the changed section...
_vm->markRectAsDirty(kMainVirtScreen, destRect, actor);

if (destRect.top < a->_top)
a->_top = destRect.top;
if (destRect.bottom > a->_bottom)
a->_bottom = destRect.bottom + 1;

_drawTop = a->_top;
_drawBottom = a->_bottom;

//SetActorUpdateArea(actor, destRect.x1, destRect.y1, destRect.x2, destRect.y2);

// Get final plot point and flip source coords if necessary.
if (yFlipFlag) {
wiz->swapRectY(&sourceRect);
sourceRect.top = (celHeight - 1) - sourceRect.top;
sourceRect.bottom = (celHeight - 1) - sourceRect.bottom;
}
if (xFlipFlag) {
wiz->swapRectX(&sourceRect);
sourceRect.left = (celWidth - 1) - sourceRect.left;
sourceRect.right = (celWidth - 1) - sourceRect.right;
}

// Call the decompression routine...
if (drawPtr) {
(*drawPtr)(_vm, wiz,
destBuffer, destBufferWidth, destBufferHeight, &destRect,
_srcPtr, celWidth, celHeight, &sourceRect, tcolor,
shadowTablePtr, conversionTable, specialRenderFlags);
}

return 2;
}

if (dst.isValidRect() == false)
return 0;
return 0;
}

static void heTRLEPaintPrim(ScummEngine *vm, Wiz *wiz, WizRawPixel *dstDataPtr, int dstWid, int dstHei, Common::Rect *dstRect, const byte *srcDataPtr, int srcWid, int srcHei, Common::Rect *srcRect, byte tColor, const byte *shadowTablePtr, const WizRawPixel *conversionTable, int32 specialRenderFlags) {
if (vm->_game.heversion > 99) {
int plotX, plotY;

// Convert incoming src rect to flags and adjust dest position for sub rect
int32 additionalRenderFlags = 0;

if (srcRect->left < srcRect->right) {
plotX = dstRect->left - srcRect->left;
} else {
plotX = dstRect->left - srcRect->right;
additionalRenderFlags |= kWRFHFlip;
}

markRectAsDirty(dst);
if (srcRect->top < srcRect->bottom) {
plotY = dstRect->top - srcRect->top;
} else {
plotY = dstRect->top - srcRect->bottom;
additionalRenderFlags |= kWRFVFlip;
}

if (_drawTop > dst.top)
_drawTop = dst.top;
if (_drawBottom < dst.bottom)
_drawBottom = dst.bottom;
// Finally call the drawing primitive
wiz->trleFLIPDecompressImage(
dstDataPtr, srcDataPtr, dstWid, dstHei,
plotX, plotY, srcWid, srcHei, dstRect,
(specialRenderFlags & kWRFSpecialRenderBitMask) | additionalRenderFlags,
nullptr, conversionTable, nullptr);

const uint8 *palPtr = NULL;
} else {
wiz->auxDecompTRLEPrim(
dstDataPtr, dstWid, dstRect, srcDataPtr, srcRect, conversionTable);
}
}

static void heTRLEPaintPrimShadow(ScummEngine *vm, Wiz *wiz, WizRawPixel *dstDataPtr, int dstWid, int dstHei, Common::Rect *dstRect, const byte *srcDataPtr, int srcWid, int srcHei, Common::Rect *srcRect, byte tColor, const byte *shadowTablePtr, const WizRawPixel *conversionTable, int32 specialRenderFlags) {
wiz->auxDecompMixColorsTRLEPrim(
dstDataPtr, dstWid, dstRect, srcDataPtr, srcRect, shadowTablePtr,
conversionTable);
}
#endif

byte AkosRenderer::paintCelTRLE(int actor, int drawToBack, int celX, int celY, int celWidth, int celHeight, byte tcolor, const byte *shadowTablePtr, int32 specialRenderFlags) {
#ifdef ENABLE_HE
const uint8 *palPtr = nullptr;
if (_vm->_game.features & GF_16BIT_COLOR) {
palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768;
if (_paletteNum) {
Expand All @@ -1217,15 +1312,18 @@ byte AkosRenderer::paintCelTRLE(int xMoveCur, int yMoveCur) {
palPtr = _vm->_hePalettes + _vm->_hePaletteSlot + 768;
}

byte *dstPtr = (byte *)_out.getBasePtr(dst.left, dst.top);
if (_shadowMode == 3) {
Wiz::decompressWizImage<kWizXMap>(dstPtr, _out.pitch, kDstScreen, _srcPtr, src, 0, palPtr, _xmap, _vm->_bytesPerPixel);
if (!shadowTablePtr) {
return hePaintCel(
actor, drawToBack, celX, celY, celWidth, celHeight, tcolor, false, nullptr,
heTRLEPaintPrim,
(const WizRawPixel *)palPtr,
specialRenderFlags);
} else {
if (palPtr != NULL) {
Wiz::decompressWizImage<kWizRMap>(dstPtr, _out.pitch, kDstScreen, _srcPtr, src, 0, palPtr, NULL, _vm->_bytesPerPixel);
} else {
Wiz::decompressWizImage<kWizCopy>(dstPtr, _out.pitch, kDstScreen, _srcPtr, src, 0, NULL, NULL, _vm->_bytesPerPixel);
}
return hePaintCel(
actor, drawToBack, celX, celY, celWidth, celHeight, tcolor, false, shadowTablePtr,
heTRLEPaintPrimShadow,
(const WizRawPixel *)palPtr,
specialRenderFlags);
}
#endif
return 0;
Expand Down Expand Up @@ -1361,7 +1459,7 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int limb, const byte *aksq, con
curState += aksq[curState + 2];
break;
case AKC_DisplayAuxFrame:
akos_queCommand(7, a, GW(2), 0);
akos_queCommand(AKQC_DisplayAuxFrame, a, GW(2), 0);
curState += 4;
break;
default:
Expand Down Expand Up @@ -1677,7 +1775,7 @@ void ScummEngine_v6::akos_processQueue() {
case AKQC_DisplayAuxFrame:
#ifdef ENABLE_HE
assert(_game.heversion >= 71);
((ScummEngine_v71he *)this)->queueAuxEntry(a->_number, param1);
((ScummEngine_v71he *)this)->heQueueAnimAuxFrame(a->_number, param1);
#endif
break;
case AKQC_StartTalkie:
Expand Down