DM: Add F0115_DUNGEONVIEW_DrawObjectsCreaturesProjectilesExplosions_CPSEF
This commit is contained in:
parent
d312ac086d
commit
bf4ae50e6b
4 changed files with 913 additions and 6 deletions
|
@ -468,18 +468,30 @@ public:
|
|||
}; // @ JUNK
|
||||
|
||||
class Projectile {
|
||||
public:
|
||||
Thing _nextThing;
|
||||
Thing _object;
|
||||
byte _kineticEnergy;
|
||||
byte _damageEnergy;
|
||||
uint16 _timerIndex;
|
||||
public:
|
||||
explicit Projectile(uint16 *rawDat) : _nextThing(rawDat[0]), _object(rawDat[1]), _kineticEnergy(rawDat[2]),
|
||||
_damageEnergy(rawDat[3]), _timerIndex(rawDat[4]) {}
|
||||
|
||||
Thing getNextThing() { return _nextThing; }
|
||||
}; // @ PROJECTILE
|
||||
|
||||
#define kExplosionType_Fireball 0 // @ C000_EXPLOSION_FIREBALL
|
||||
#define kExplosionType_Slime 1 // @ C001_EXPLOSION_SLIME
|
||||
#define kExplosionType_LightningBolt 2 // @ C002_EXPLOSION_LIGHTNING_BOLT
|
||||
#define kExplosionType_HarmNonMaterial 3 // @ C003_EXPLOSION_HARM_NON_MATERIAL
|
||||
#define kExplosionType_OpenDoor 4 // @ C004_EXPLOSION_OPEN_DOOR
|
||||
#define kExplosionType_PoisonBolt 6 // @ C006_EXPLOSION_POISON_BOLT
|
||||
#define kExplosionType_PoisonCloud 7 // @ C007_EXPLOSION_POISON_CLOUD
|
||||
#define kExplosionType_Smoke 40 // @ C040_EXPLOSION_SMOKE
|
||||
#define kExplosionType_Fluxcage 50 // @ C050_EXPLOSION_FLUXCAGE
|
||||
#define kExplosionType_RebirthStep1 100 // @ C100_EXPLOSION_REBIRTH_STEP1
|
||||
#define kExplosionType_RebirthStep2 101 // @ C101_EXPLOSION_REBIRTH_STEP2
|
||||
|
||||
class Explosion {
|
||||
Thing _nextThing;
|
||||
uint16 _attributes;
|
||||
|
@ -487,6 +499,9 @@ public:
|
|||
explicit Explosion(uint16 *rawDat) : _nextThing(rawDat[0]), _attributes(rawDat[1]) {}
|
||||
|
||||
Thing getNextThing() { return _nextThing; }
|
||||
uint16 getType() { return _attributes & 0x7F; }
|
||||
uint16 getAttack() { return (_attributes >> 8) & 0xFF; }
|
||||
uint16 getCentered() { return (_attributes >> 7) & 0x1; }
|
||||
}; // @ EXPLOSION
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
#include "gfx.h"
|
||||
#include "dungeonman.h"
|
||||
#include "group.h"
|
||||
#include "timeline.h"
|
||||
|
||||
|
||||
namespace DM {
|
||||
|
@ -988,7 +990,7 @@ void DisplayMan::blitToBitmap(byte *srcBitmap, uint16 srcWidth, uint16 srcHeight
|
|||
|
||||
void DisplayMan::blitBoxFilledWithMaskedBitmapToScreen(byte* src, byte* mask, byte* tmp, Box& box,
|
||||
int16 lastUnitIndex, int16 firstUnitIndex, int16 destPixelWidth, Color transparent,
|
||||
int16 xPos, int16 yPos, int16 height2, Viewport& viewport) {
|
||||
int16 xPos, int16 yPos, int16 destHeight, int16 height2, Viewport& viewport) {
|
||||
blitBoxFilledWithMaskedBitmap(src, _vgaBuffer, mask, tmp, box, lastUnitIndex, firstUnitIndex, _screenWidth, transparent, xPos, yPos, _screenHeight, height2, viewport);
|
||||
}
|
||||
|
||||
|
@ -1959,13 +1961,853 @@ int16 gCenteredExplosionCoordinates[15][2] = { // @ G0225_aai_Graphic558_Centere
|
|||
{-53, 60}, /* D0L */
|
||||
{276, 60}}; /* D0R */
|
||||
|
||||
void DisplayMan::drawObjectsCreaturesProjectilesExplosions(Thing thingParam, direction directionParam, int16 mapXpos,
|
||||
#define kBlitDoNotUseMask 0x0080 // @ MASK0x0080_DO_NOT_USE_MASK
|
||||
|
||||
void DisplayMan::cthulhu(Thing thingParam, direction directionParam, int16 mapXpos,
|
||||
int16 mapYpos, int16 viewSquareIndex, uint16 orderedViewCellOrdinals) {
|
||||
|
||||
DungeonMan &dunMan = *_vm->_dungeonMan;
|
||||
|
||||
// AL_0 shared
|
||||
uint16 &AL_0_creatureIndexRed = *(uint16*)&thingParam;
|
||||
uint16 &AL_0_creatureGraphicInfoRed = *(uint16*)&thingParam;
|
||||
uint16 &AL_0_creaturePosX = *(uint16*)&thingParam;
|
||||
// AL_1 shared
|
||||
int16 &AL_1_viewSquareExplosionIndex = viewSquareIndex;
|
||||
// AL_2 shared
|
||||
int16 L0126_i_Multiple;
|
||||
int16 &AL_2_viewCell = L0126_i_Multiple;
|
||||
int16 &AL_2_cellPurpleMan = L0126_i_Multiple;
|
||||
int16 &AL_2_explosionSize = L0126_i_Multiple;
|
||||
// AL_4 shared
|
||||
int16 L0127_i_Multiple;
|
||||
int16 &AL_4_thingType = L0127_i_Multiple;
|
||||
int16 &AL_4_nativeBitmapIndex = L0127_i_Multiple;
|
||||
int16 &AL_4_xPos = L0127_i_Multiple;
|
||||
int16 &AL_4_groupCells = L0127_i_Multiple;
|
||||
int16 &AL_4_normalizdByteWidth = L0127_i_Multiple;
|
||||
int16 &AL_4_yPos = L0127_i_Multiple;
|
||||
int16 &AL_4_projectileAspect = L0127_i_Multiple;
|
||||
int16 &AL_4_explosionType = L0127_i_Multiple;
|
||||
int16 &AL_4_explosionAspectIndex = L0127_i_Multiple;
|
||||
// AL_6 shared
|
||||
byte *L0128_puc_Multiple;
|
||||
byte *&AL_6_bitmapRedBanana = L0128_puc_Multiple;
|
||||
|
||||
ObjectAspect *objectAspect;
|
||||
uint32 remainingViewCellOrdinalsToProcess;
|
||||
byte* paletteChanges;
|
||||
byte* bitmapGreenAnt;
|
||||
byte* coordinateSet;
|
||||
int16 derivedBitmapIndex;
|
||||
|
||||
int16 byteWidth;
|
||||
int16 heightRedEagle;
|
||||
int16 viewLane; /* The lane (center/left/right) that the specified square is part of */
|
||||
int16 cellYellowBear;
|
||||
int16 paddingPixelCount;
|
||||
int16 heightGreenGoat;
|
||||
bool useAlcoveObjectImage; /* C1_TRUE for objects that have a special graphic when drawn in an alcove, like the Chest */
|
||||
bool flipHorizontal;
|
||||
bool drawingGrabbableObject;
|
||||
Box boxByteGreen;
|
||||
Thing firstThingToDraw; /* Initialized to thingParam and never changed afterwards. Used as a backup of the specified first object to draw */
|
||||
|
||||
int16 cellCounter;
|
||||
uint16 objectShiftIndex;
|
||||
|
||||
uint16 L0150_ui_Multiple;
|
||||
uint16 &AL_8_shiftSetIndex = L0150_ui_Multiple;
|
||||
uint16 &AL_8_projectileScaleIndex = L0150_ui_Multiple;
|
||||
|
||||
Thing groupThing;
|
||||
Group* group;
|
||||
ActiveGroup* activeGroup;
|
||||
CreatureInfo* creatureInfo;
|
||||
CreatureAspect* creatureAspectStruct;
|
||||
int16 creatureSize;
|
||||
int16 creatureDirectionDelta;
|
||||
int16 creatureGraphicInfoGreen;
|
||||
int16 creatureAspectInt;
|
||||
int16 creatureIndexGreen;
|
||||
int16 transparentColor;
|
||||
int16 sourceByteWidth;
|
||||
int16 sourceHeight;
|
||||
int16 creaturePaddingPixelCount;
|
||||
bool twoHalfSquareCreaturesFrontView;
|
||||
bool drawingLastBackRowCell;
|
||||
bool useCreatureSideBitmap;
|
||||
bool useCreatureBackBitmap;
|
||||
bool useCreatureSpecialD2FrontBitmap;
|
||||
bool useCreatureAttackBitmap;
|
||||
bool useFlippedHorizontallyCreatureFrontImage;
|
||||
|
||||
/* Set to C1_TRUE when the last creature that the function should draw is being drawn. This is used to avoid processing the code to draw creatures for the remaining square cells */
|
||||
bool drawCreaturesCompleted;
|
||||
|
||||
int16 doorFrontViewDrawingPass; /* Value 0, 1 or 2 */
|
||||
int16 scale;
|
||||
bool derivedBitmapInCache;
|
||||
Projectile* projectile;
|
||||
byte projectileCoordinates[2];
|
||||
int16 projectilePosX;
|
||||
int16 projectileDirection;
|
||||
int16 projectileAspectType;
|
||||
int16 projectileBitmapIndexData;
|
||||
bool doNotScaleWithKineticEnergy;
|
||||
|
||||
/* When true, the code section to draw an object is called (with a goto) to draw the projectile, then the code section goes back to projectile processing with another goto */
|
||||
bool drawProjectileAsObject;
|
||||
|
||||
bool sqaureHasProjectile;
|
||||
uint16 currentViewCellToDraw;
|
||||
bool projectileFlipVertical;
|
||||
bool projectileAspectTypeHasBackGraphicAndRotation;
|
||||
bool flipVertical;
|
||||
Explosion* explosion;
|
||||
Explosion* fluxcageExplosion;
|
||||
int16* explosionCoordinates;
|
||||
int16 explosionScale;
|
||||
bool squareHasExplosion;
|
||||
bool rebirthExplosion;
|
||||
bool smoke;
|
||||
FieldAspect fieldAspect;
|
||||
|
||||
|
||||
if (thingParam == Thing::_endOfList)
|
||||
return;
|
||||
|
||||
group = 0;
|
||||
groupThing = Thing::_none;
|
||||
drawCreaturesCompleted = sqaureHasProjectile = squareHasExplosion = false;
|
||||
cellCounter = 0;
|
||||
firstThingToDraw = thingParam;
|
||||
if (getFlag(orderedViewCellOrdinals, kCellOrder_DoorFront)) { /* If the function call is to draw objects on a door square viewed from the front */
|
||||
/* Two function calls are made in that case to draw objects on both sides of the door frame.
|
||||
The door and its frame are drawn between the two calls. This value indicates the drawing pass so that
|
||||
creatures are drawn in the right order and so that Fluxcages are not drawn twice */
|
||||
doorFrontViewDrawingPass = (orderedViewCellOrdinals & 0x1) + 1;
|
||||
orderedViewCellOrdinals >>= 4; /* Remove the first nibble that was used for the door front view pass */
|
||||
} else {
|
||||
doorFrontViewDrawingPass = 0; /* The function call is not to draw objects on a door square viewed from the front */
|
||||
}
|
||||
|
||||
bool drawAlcoveObjects = !(remainingViewCellOrdinalsToProcess = orderedViewCellOrdinals);
|
||||
uint16 viewSquareIndexBackup = viewSquareIndex;
|
||||
viewLane = (viewSquareIndex + 3) % 3;
|
||||
|
||||
|
||||
do {
|
||||
/* Draw objects */
|
||||
if (drawAlcoveObjects) {
|
||||
AL_2_viewCell = kViewCellAlcove; /* Index of coordinates to draw objects in alcoves */
|
||||
cellYellowBear = returnOppositeDir(directionParam); /* Alcove is on the opposite direction of the viewing direction */
|
||||
objectShiftIndex = 2;
|
||||
} else {
|
||||
AL_2_viewCell = _vm->ordinalToIndex((int16)remainingViewCellOrdinalsToProcess & 0x000F); /* View cell is the index of coordinates to draw object */
|
||||
currentViewCellToDraw = AL_2_viewCell;
|
||||
remainingViewCellOrdinalsToProcess >>= 4; /* Proceed to the next cell ordinal */
|
||||
cellCounter++;
|
||||
cellYellowBear = (AL_2_viewCell + directionParam) % 3; /* Convert view cell to absolute cell */
|
||||
thingParam = firstThingToDraw;
|
||||
viewSquareIndex = viewSquareIndexBackup; /* Restore value as it may have been modified while drawing a creature */
|
||||
objectShiftIndex = 0;
|
||||
}
|
||||
|
||||
objectShiftIndex += (cellYellowBear & 0x0001) << 3;
|
||||
drawProjectileAsObject = false;
|
||||
do {
|
||||
if ((AL_4_thingType = thingParam.getType()) == kGroupThingType) {
|
||||
groupThing = thingParam;
|
||||
continue;
|
||||
}
|
||||
if (AL_4_thingType == kProjectileThingType) {
|
||||
sqaureHasProjectile = true;
|
||||
continue;
|
||||
}
|
||||
if (AL_4_thingType == kExplosionThingType) {
|
||||
squareHasExplosion = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Square where objects are visible and object is located on cell being processed */
|
||||
if ((viewSquareIndex >= kViewSquare_D3C) && (viewSquareIndex <= kViewSquare_D0C) && (thingParam.getCell() == cellYellowBear)) {
|
||||
objectAspect = &(gObjectAspects[gObjectInfo[dunMan.getObjectInfoIndex(thingParam)]._objectAspectIndex]);
|
||||
AL_4_nativeBitmapIndex = kFirstObjectGraphicIndice + objectAspect->_firstNativeBitmapRelativeIndex;
|
||||
if (useAlcoveObjectImage = (drawAlcoveObjects && getFlag(objectAspect->_graphicInfo, kObjectAlcoveMask) && !viewLane)) {
|
||||
AL_4_nativeBitmapIndex++;
|
||||
}
|
||||
coordinateSet = gObjectCoordinateSets[objectAspect->_coordinateSet][viewSquareIndex][AL_2_viewCell];
|
||||
if (!coordinateSet[1]) /* If object is not visible */
|
||||
continue;
|
||||
T0115015_DrawProjectileAsObject:
|
||||
flipHorizontal = getFlag(objectAspect->_graphicInfo, kObjectFlipOnRightMask) &&
|
||||
!useAlcoveObjectImage &&
|
||||
((viewLane == kViewLaneRight) || (!viewLane && ((AL_2_viewCell == kViewCellFrontRight) || (AL_2_viewCell == kViewCellBackRight))));
|
||||
/* Flip horizontally if object graphic requires it and is not being drawn in an alcove and the object is
|
||||
either on the right lane or on the right column of the center lane */
|
||||
paddingPixelCount = 0;
|
||||
|
||||
if ((viewSquareIndex == kViewSquare_D0C) || ((viewSquareIndex >= kViewSquare_D1C) && (AL_2_viewCell >= kViewCellBackRight))) {
|
||||
/* If object is in the center lane (only D0C or D1C with condition above) and is not a projectile */
|
||||
drawingGrabbableObject = (!viewLane && !drawProjectileAsObject);
|
||||
AL_8_shiftSetIndex = kShiftSet_D0BackD1Front;
|
||||
AL_6_bitmapRedBanana = getBitmap(AL_4_nativeBitmapIndex); /* Use base graphic, no resizing */
|
||||
byteWidth = objectAspect->_width;
|
||||
heightRedEagle = objectAspect->_height;
|
||||
if (flipHorizontal) {
|
||||
memcpy(_tmpBitmap, AL_6_bitmapRedBanana, byteWidth * heightRedEagle * sizeof(byte));
|
||||
flipBitmapHorizontal(_tmpBitmap, byteWidth, heightRedEagle);
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
} else {
|
||||
drawingGrabbableObject = false;
|
||||
derivedBitmapIndex = kDerivedBitmapFirstObject + objectAspect->_firstDerivedBitmapRelativeIndex;
|
||||
if ((viewSquareIndex >= kViewSquare_D1C) || ((viewSquareIndex >= kViewSquare_D2C) && (AL_2_viewCell >= kViewCellBackRight))) {
|
||||
derivedBitmapIndex++;
|
||||
AL_8_shiftSetIndex = kShiftSet_D1BackD2Front;
|
||||
byteWidth = getScaledDimension(objectAspect->_width, kScale20_D2);
|
||||
heightRedEagle = getScaledDimension(objectAspect->_height, kScale20_D2);
|
||||
paletteChanges = gPalChangesFloorOrn_D2;
|
||||
} else {
|
||||
AL_8_shiftSetIndex = kShiftSet_D2BackD3Front;
|
||||
byteWidth = getScaledDimension(objectAspect->_width, kScale16_D3);
|
||||
heightRedEagle = getScaledDimension(objectAspect->_height, kScale16_D3);
|
||||
paletteChanges = gPalChangesFloorOrn_D3;
|
||||
}
|
||||
if (flipHorizontal) {
|
||||
derivedBitmapIndex += 2;
|
||||
paddingPixelCount = (7 - ((byteWidth / 2 - 1) & 0x0007)) << 1;
|
||||
} else if (useAlcoveObjectImage) {
|
||||
derivedBitmapIndex += 4;
|
||||
}
|
||||
|
||||
if (isDerivedBitmapInCache(derivedBitmapIndex)) {
|
||||
AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
|
||||
} else {
|
||||
bitmapGreenAnt = getBitmap(AL_4_nativeBitmapIndex);
|
||||
blitToBitmapShrinkWithPalChange(bitmapGreenAnt, objectAspect->_width, objectAspect->_height, AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex),
|
||||
byteWidth, heightRedEagle, paletteChanges);
|
||||
if (flipHorizontal) {
|
||||
flipBitmapHorizontal(AL_6_bitmapRedBanana, byteWidth, heightRedEagle);
|
||||
}
|
||||
warning("IGNORED CODE: F0493_CACHE_AddDerivedBitmap");
|
||||
}
|
||||
}
|
||||
AL_4_xPos = coordinateSet[0];
|
||||
boxByteGreen._y2 = coordinateSet[1] + 1;
|
||||
if (!drawProjectileAsObject) { /* If drawing an object that is not a projectile */
|
||||
AL_4_xPos += gShiftSets[AL_8_shiftSetIndex][gObjectPileShiftSetIndices[objectShiftIndex][0]];
|
||||
boxByteGreen._y2 += gShiftSets[AL_8_shiftSetIndex][gObjectPileShiftSetIndices[objectShiftIndex][1]];
|
||||
objectShiftIndex++; /* The next object drawn will use the next shift values */
|
||||
if (drawAlcoveObjects) {
|
||||
if (objectShiftIndex >= 14) {
|
||||
objectShiftIndex = 2;
|
||||
}
|
||||
} else {
|
||||
objectShiftIndex &= 0x000F;
|
||||
}
|
||||
}
|
||||
boxByteGreen._y1 = boxByteGreen._y2 - (heightRedEagle - 1) - 1;
|
||||
if (boxByteGreen._y2 > 136) {
|
||||
boxByteGreen._y2 = 136;
|
||||
}
|
||||
boxByteGreen._x2 = MIN(224, AL_4_xPos + byteWidth);
|
||||
if (boxByteGreen._x1 = MAX(0, AL_4_xPos - byteWidth + 1)) {
|
||||
if (flipHorizontal) {
|
||||
AL_4_xPos = paddingPixelCount;
|
||||
} else {
|
||||
AL_4_xPos = 0;
|
||||
}
|
||||
} else {
|
||||
AL_4_xPos = byteWidth - AL_4_xPos - 1;
|
||||
}
|
||||
|
||||
if (drawingGrabbableObject) {
|
||||
bitmapGreenAnt = AL_6_bitmapRedBanana;
|
||||
Box *AL_6_boxPtrRed = &dunMan._dungeonViewClickableBoxes[AL_2_viewCell];
|
||||
if (AL_6_boxPtrRed->_x1 == 255) { /* If the grabbable object is the first */
|
||||
*AL_6_boxPtrRed = boxByteGreen;
|
||||
|
||||
if ((heightGreenGoat = AL_6_boxPtrRed->_y2 - AL_6_boxPtrRed->_y1) < 15) { /* If the box is too small then enlarge it a little */
|
||||
heightGreenGoat = heightGreenGoat >> 1;
|
||||
AL_6_boxPtrRed->_y1 += heightGreenGoat - 7;
|
||||
if (heightGreenGoat < 4) {
|
||||
AL_6_boxPtrRed->_y2 -= heightGreenGoat - 3;
|
||||
}
|
||||
}
|
||||
} else { /* If there are several grabbable objects then enlarge the box so it includes all objects */
|
||||
AL_6_boxPtrRed->_x1 = MIN(AL_6_boxPtrRed->_x1, boxByteGreen._x1);
|
||||
AL_6_boxPtrRed->_x2 = MIN(AL_6_boxPtrRed->_x2, boxByteGreen._x2);
|
||||
AL_6_boxPtrRed->_y1 = MIN(AL_6_boxPtrRed->_y1, boxByteGreen._y1);
|
||||
AL_6_boxPtrRed->_y2 = MIN(AL_6_boxPtrRed->_y2, boxByteGreen._y2);
|
||||
}
|
||||
AL_6_bitmapRedBanana = bitmapGreenAnt;
|
||||
dunMan._pileTopObject[AL_2_viewCell] = thingParam; /* The object is at the top of the pile */
|
||||
}
|
||||
blitToScreen(AL_6_bitmapRedBanana, byteWidth, AL_4_xPos, 0, boxByteGreen, kColorFlesh, gDungeonViewport);
|
||||
|
||||
if (drawProjectileAsObject)
|
||||
goto T0115171_BackFromT0115015_DrawProjectileAsObject;
|
||||
}
|
||||
} while ((thingParam = dunMan.getNextThing(thingParam)) != Thing::_endOfList);
|
||||
if (AL_2_viewCell == kViewCellAlcove)
|
||||
break; /* End of processing when drawing objects in an alcove */
|
||||
if (viewSquareIndex < kViewSquare_D3C)
|
||||
break; /* End of processing if square is too far away at D4 */
|
||||
/* Draw creatures */
|
||||
|
||||
/* If (draw cell on the back row or second cell being processed) and (no more cells to draw or next cell to draw is a cell on the front row) */
|
||||
drawingLastBackRowCell = ((AL_2_viewCell <= kViewCellFrontRight) || (cellCounter == 1))
|
||||
&& (!remainingViewCellOrdinalsToProcess || ((remainingViewCellOrdinalsToProcess & 0x0000000F) >= 3));
|
||||
|
||||
if ((groupThing == Thing::_none) || drawCreaturesCompleted)
|
||||
goto T0115129_DrawProjectiles; /* Skip code to draw creatures */
|
||||
if (group == nullptr) { /* If all creature data and info has not already been gathered */
|
||||
group = (Group*)dunMan.getThingData(groupThing);
|
||||
activeGroup = &_vm->_groupMan->_activeGroups[group->getActiveGroupIndex()];
|
||||
creatureInfo = &gCreatureInfo[group->_type];
|
||||
creatureAspectStruct = &gCreatureAspects[creatureInfo->_creatureAspectIndex];
|
||||
creatureSize = getFlag(creatureInfo->_attributes, kMaskCreatureInfo_size);
|
||||
creatureGraphicInfoGreen = creatureInfo->_graphicInfo;
|
||||
}
|
||||
objectAspect = (ObjectAspect*)creatureAspectStruct;
|
||||
if (AL_0_creatureIndexRed = _vm->_groupMan->getCreatureOrdinalInCell(group, cellYellowBear)) { /* If there is a creature on the cell being processed */
|
||||
AL_0_creatureIndexRed--; /* Convert ordinal to index */
|
||||
creatureIndexGreen = AL_0_creatureIndexRed;
|
||||
} else if (creatureSize == kMaskCreatureSizeHalf) {
|
||||
AL_0_creatureIndexRed = 0;
|
||||
creatureIndexGreen = -1;
|
||||
} else {
|
||||
goto T0115129_DrawProjectiles; /* No creature to draw at cell, skip to projectiles */
|
||||
}
|
||||
|
||||
creatureDirectionDelta = (directionParam - _vm->_groupMan->getCreatureValue(activeGroup->_directions, AL_0_creatureIndexRed)) % 3;
|
||||
twoHalfSquareCreaturesFrontView = false;
|
||||
if ((AL_4_groupCells = activeGroup->_cells) == kCreatureTypeSingleCenteredCreature) { /* If there is a single centered creature in the group */
|
||||
if (remainingViewCellOrdinalsToProcess || (doorFrontViewDrawingPass == 1))
|
||||
/* Do not draw a single centered creature now, wait until second pass (for a front view door)
|
||||
or until all cells have been drawn so the creature is drawn over all the objects on the floor */
|
||||
goto T0115129_DrawProjectiles;
|
||||
drawCreaturesCompleted = true;
|
||||
if ((creatureSize == kMaskCreatureSizeHalf) && (creatureDirectionDelta & 0x0001)) { /* Side view of half square creature */
|
||||
AL_2_viewCell = kHalfSizedViewCell_CenterColumn;
|
||||
} else {
|
||||
AL_2_viewCell = kHalfSizedViewCell_FrontRow;
|
||||
}
|
||||
} else if ((creatureSize == kMaskCreatureSizeHalf) && (drawingLastBackRowCell || !remainingViewCellOrdinalsToProcess || (creatureIndexGreen < 0))) {
|
||||
if (drawingLastBackRowCell && (doorFrontViewDrawingPass != 2)) {
|
||||
if ((creatureIndexGreen >= 0) && (creatureDirectionDelta & 0x0001)) {
|
||||
AL_2_viewCell = kHalfSizedViewCell_BackRow; /* Side view of a half square creature on the back row. Drawn during pass 1 for a door square */
|
||||
} else {
|
||||
goto T0115129_DrawProjectiles;
|
||||
}
|
||||
} else if ((doorFrontViewDrawingPass != 1) && !remainingViewCellOrdinalsToProcess) {
|
||||
if (creatureDirectionDelta & 0x0001) {
|
||||
if (creatureIndexGreen >= 0) {
|
||||
AL_2_viewCell = kHalfSizedViewCell_FrontRow; /* Side view of a half square creature on the front row. Drawn during pass 2 for a door square */
|
||||
} else {
|
||||
goto T0115129_DrawProjectiles;
|
||||
}
|
||||
} else {
|
||||
drawCreaturesCompleted = true;
|
||||
if (creatureIndexGreen < 0) {
|
||||
creatureIndexGreen = 0;
|
||||
}
|
||||
twoHalfSquareCreaturesFrontView = group->getCount();
|
||||
if (((AL_4_groupCells = _vm->_groupMan->getCreatureValue(AL_4_groupCells, AL_0_creatureIndexRed)) == directionParam)
|
||||
|| (AL_4_groupCells == returnPrevVal(directionParam))) {
|
||||
AL_2_viewCell = kHalfSizedViewCell_LeftColumn;
|
||||
} else {
|
||||
AL_2_viewCell = kHalfSizedViewCell_RightColumn;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
goto T0115129_DrawProjectiles;
|
||||
}
|
||||
|
||||
} else if (creatureSize != kMaskCreatureSizeQuarter)
|
||||
goto T0115129_DrawProjectiles;
|
||||
|
||||
|
||||
creatureAspectInt = activeGroup->_aspect[creatureIndexGreen];
|
||||
if (viewSquareIndex > kViewSquare_D0C) {
|
||||
viewSquareIndex--;
|
||||
}
|
||||
T0115077_DrawSecondHalfSquareCreature:
|
||||
coordinateSet = gCreatureCoordinateSets[((CreatureAspect*)objectAspect)->getCoordSet()][viewSquareIndex][AL_2_viewCell];
|
||||
if (!coordinateSet[1])
|
||||
goto T0115126_CreatureNotVisible;
|
||||
AL_0_creatureGraphicInfoRed = creatureGraphicInfoGreen;
|
||||
AL_4_nativeBitmapIndex = kFirstCreatureGraphicIndice + ((CreatureAspect*)objectAspect)->_firstNativeBitmapRelativeIndex; /* By default, assume using the front image */
|
||||
derivedBitmapIndex = ((CreatureAspect*)objectAspect)->_firstDerivedBitmapIndex;
|
||||
if (useCreatureSideBitmap = getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskSide) && (creatureDirectionDelta & 0x0001)) {
|
||||
useCreatureAttackBitmap = useFlippedHorizontallyCreatureFrontImage = useCreatureBackBitmap = false;
|
||||
AL_4_nativeBitmapIndex++; /* Skip the front image. Side image is right after the front image */
|
||||
derivedBitmapIndex += 2;
|
||||
sourceByteWidth = byteWidth = ((CreatureAspect*)objectAspect)->_byteWidthSide;
|
||||
sourceHeight = heightRedEagle = ((CreatureAspect*)objectAspect)->_heightSide;
|
||||
} else {
|
||||
useCreatureBackBitmap = getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskBack) && (creatureDirectionDelta == 0);
|
||||
if (useCreatureAttackBitmap = !useCreatureBackBitmap && getFlag(creatureAspectInt, kMaskActiveGroupIsAttacking)
|
||||
&& getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskAttack)) {
|
||||
|
||||
useFlippedHorizontallyCreatureFrontImage = false;
|
||||
sourceByteWidth = byteWidth = ((CreatureAspect*)objectAspect)->_byteWidthAttack;
|
||||
sourceHeight = heightRedEagle = ((CreatureAspect*)objectAspect)->_heightAttack;
|
||||
AL_4_nativeBitmapIndex++; /* Skip the front image */
|
||||
derivedBitmapIndex += 2;
|
||||
if (getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskSide)) {
|
||||
AL_4_nativeBitmapIndex++; /* If the creature has a side image, it preceeds the attack image */
|
||||
derivedBitmapIndex += 2;
|
||||
}
|
||||
if (getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskBack)) {
|
||||
AL_4_nativeBitmapIndex++; /* If the creature has a back image, it preceeds the attack image */
|
||||
derivedBitmapIndex += 2;
|
||||
}
|
||||
} else {
|
||||
sourceByteWidth = byteWidth = ((CreatureAspect*)objectAspect)->_byteWidthFront;
|
||||
sourceHeight = heightRedEagle = ((CreatureAspect*)objectAspect)->_heightFront;
|
||||
if (useCreatureBackBitmap) {
|
||||
useFlippedHorizontallyCreatureFrontImage = false;
|
||||
if (getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskSide)) {
|
||||
AL_4_nativeBitmapIndex += 2; /* If the creature has a side image, it preceeds the back image */
|
||||
derivedBitmapIndex += 4;
|
||||
} else {
|
||||
AL_4_nativeBitmapIndex++; /* If the creature does not have a side image, the back image follows the front image */
|
||||
derivedBitmapIndex += 2;
|
||||
}
|
||||
} else {
|
||||
if (useFlippedHorizontallyCreatureFrontImage = getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskFlipNonAttack)
|
||||
&& getFlag(creatureAspectInt, kMaskActiveGroupFlipBitmap)) {
|
||||
derivedBitmapIndex += 2;
|
||||
if (getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskSide)) {
|
||||
derivedBitmapIndex += 2;
|
||||
}
|
||||
if (getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskBack)) {
|
||||
derivedBitmapIndex += 2;
|
||||
}
|
||||
if (getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskAttack)) {
|
||||
derivedBitmapIndex += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (viewSquareIndex >= kViewSquare_D1C) { /* Creature is on D1 */
|
||||
creaturePaddingPixelCount = 0;
|
||||
AL_8_shiftSetIndex = kShiftSet_D0BackD1Front;
|
||||
transparentColor = ((CreatureAspect*)objectAspect)->getTranspColour();
|
||||
if (useCreatureSideBitmap) {
|
||||
AL_6_bitmapRedBanana = getBitmap(AL_4_nativeBitmapIndex);
|
||||
if (creatureDirectionDelta == 1) {
|
||||
memcpy(_tmpBitmap, AL_6_bitmapRedBanana, byteWidth * heightRedEagle * sizeof(byte));
|
||||
flipBitmapHorizontal(_tmpBitmap, byteWidth, heightRedEagle);
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
} else {
|
||||
if (useCreatureBackBitmap || !useFlippedHorizontallyCreatureFrontImage) {
|
||||
AL_6_bitmapRedBanana = getBitmap(AL_4_nativeBitmapIndex);
|
||||
if (useCreatureAttackBitmap && getFlag(creatureAspectInt, kMaskActiveGroupFlipBitmap)) {
|
||||
memcpy(_tmpBitmap, AL_6_bitmapRedBanana, byteWidth * heightRedEagle * sizeof(byte));
|
||||
flipBitmapHorizontal(_tmpBitmap, byteWidth, heightRedEagle);
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
} else { /* Use first additional derived graphic: front D1 */
|
||||
if (isDerivedBitmapInCache(derivedBitmapIndex)) { /* If derived graphic is already in memory */
|
||||
AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
|
||||
} else {
|
||||
bitmapGreenAnt = getBitmap(AL_4_nativeBitmapIndex);
|
||||
if (getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskFlipNonAttack)) {
|
||||
AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
|
||||
memcpy(AL_6_bitmapRedBanana, bitmapGreenAnt, byteWidth * heightRedEagle * sizeof(byte));
|
||||
flipBitmapHorizontal(AL_6_bitmapRedBanana, byteWidth, heightRedEagle);
|
||||
}
|
||||
warning("IGNORED CODE: F0493_CACHE_AddDerivedBitmap");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { /* Creature is on D2 or D3 */
|
||||
if (useFlippedHorizontallyCreatureFrontImage) {
|
||||
derivedBitmapIndex++; /* Skip front D1 image in additional graphics */
|
||||
}
|
||||
if (viewSquareIndex >= kViewSquare_D2C) { /* Creature is on D2 */
|
||||
derivedBitmapIndex++; /* Skip front D3 image in additional graphics */
|
||||
AL_8_shiftSetIndex = kShiftSet_D1BackD2Front;
|
||||
useCreatureSpecialD2FrontBitmap = getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskSpecialD2Front)
|
||||
&& !useCreatureSideBitmap && !useCreatureBackBitmap && !useCreatureAttackBitmap;
|
||||
paletteChanges = gPalChangesCreature_D2;
|
||||
scale = kScale20_D2;
|
||||
} else { /* Creature is on D3 */
|
||||
AL_8_shiftSetIndex = kShiftSet_D2BackD3Front;
|
||||
useCreatureSpecialD2FrontBitmap = false;
|
||||
paletteChanges = gPalChangesCreature_D3;
|
||||
scale = kScale16_D3;
|
||||
}
|
||||
byteWidth = getScaledDimension(sourceByteWidth, scale);
|
||||
heightRedEagle = getScaledDimension(sourceHeight, scale);
|
||||
transparentColor = paletteChanges[((CreatureAspect*)objectAspect)->getTranspColour()] / 10;
|
||||
if (derivedBitmapInCache = isDerivedBitmapInCache(derivedBitmapIndex)) {
|
||||
AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
|
||||
} else {
|
||||
bitmapGreenAnt = getBitmap(AL_4_nativeBitmapIndex);
|
||||
AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
|
||||
blitToBitmapShrinkWithPalChange(bitmapGreenAnt, sourceByteWidth, sourceHeight, AL_6_bitmapRedBanana, byteWidth, heightRedEagle, paletteChanges);
|
||||
warning("IGNORED CODE: F0493_CACHE_AddDerivedBitmap");
|
||||
}
|
||||
if ((useCreatureSideBitmap && (creatureDirectionDelta == 1)) || /* If creature is viewed from the right, the side view must be flipped */
|
||||
(useCreatureAttackBitmap && getFlag(creatureAspectInt, kMaskActiveGroupFlipBitmap)) ||
|
||||
(useCreatureSpecialD2FrontBitmap && getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskSpecialD2FrontIsFlipped)) ||
|
||||
(useFlippedHorizontallyCreatureFrontImage && getFlag(AL_0_creatureGraphicInfoRed, kCreatureInfoGraphicMaskFlipNonAttack))) { /* If the graphic should be flipped */
|
||||
if (!useFlippedHorizontallyCreatureFrontImage || !derivedBitmapInCache) {
|
||||
AL_4_normalizdByteWidth = byteWidth;
|
||||
warning("SUPER WARNING: we might need getNormalizedByteWidthM77");
|
||||
if (!useFlippedHorizontallyCreatureFrontImage) {
|
||||
memcpy(_tmpBitmap, AL_6_bitmapRedBanana, AL_4_normalizdByteWidth * heightRedEagle * sizeof(byte));
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
flipBitmapHorizontal(AL_6_bitmapRedBanana, AL_4_normalizdByteWidth, heightRedEagle);
|
||||
}
|
||||
creaturePaddingPixelCount = (7 - ((byteWidth / 2 - 1) & 0x0007)) << 1;
|
||||
} else {
|
||||
creaturePaddingPixelCount = 0;
|
||||
}
|
||||
}
|
||||
AL_4_yPos = coordinateSet[1];
|
||||
AL_4_yPos += gShiftSets[AL_8_shiftSetIndex][getVerticalOffsetM23(creatureAspectInt)];
|
||||
boxByteGreen._y2 = MIN(AL_4_yPos, (int16)135) + 1;
|
||||
boxByteGreen._y1 = MIN(0, AL_4_yPos - (heightRedEagle - 1));
|
||||
AL_4_xPos = coordinateSet[0];
|
||||
AL_4_xPos += gShiftSets[AL_8_shiftSetIndex][getHorizontalOffsetM22(creatureAspectInt)];
|
||||
if (viewLane == kViewLaneLeft) {
|
||||
AL_4_xPos -= 100;
|
||||
} else {
|
||||
if (viewLane) { /* Lane right */
|
||||
AL_4_xPos += 100;
|
||||
}
|
||||
}
|
||||
if (boxByteGreen._x2 = 1 + MIN(MAX(0, AL_4_xPos + byteWidth), 223) <= 1)
|
||||
goto T0115126_CreatureNotVisible;
|
||||
if (boxByteGreen._x1 = MIN(MAX(0, AL_4_xPos - byteWidth + 1), 223)) {
|
||||
if (boxByteGreen._x1 == 223)
|
||||
goto T0115126_CreatureNotVisible;
|
||||
AL_0_creaturePosX = creaturePaddingPixelCount;
|
||||
} else {
|
||||
AL_0_creaturePosX = creaturePaddingPixelCount + (byteWidth - AL_4_xPos - 1);
|
||||
}
|
||||
warning("SUPER WARNINIG: we might nee noralized with on byteWidth");
|
||||
blitToScreen(AL_6_bitmapRedBanana, byteWidth, AL_0_creaturePosX, 0, boxByteGreen, (Color)transparentColor, gDungeonViewport);
|
||||
|
||||
T0115126_CreatureNotVisible:
|
||||
if (twoHalfSquareCreaturesFrontView) {
|
||||
twoHalfSquareCreaturesFrontView = false;
|
||||
creatureAspectInt = activeGroup->_aspect[!creatureIndexGreen]; /* Aspect of the other creature in the pair */
|
||||
if (AL_2_viewCell == kHalfSizedViewCell_RightColumn) {
|
||||
AL_2_viewCell = kHalfSizedViewCell_LeftColumn;
|
||||
} else {
|
||||
AL_2_viewCell = kHalfSizedViewCell_RightColumn;
|
||||
}
|
||||
goto T0115077_DrawSecondHalfSquareCreature;
|
||||
}
|
||||
/* Draw projectiles */
|
||||
T0115129_DrawProjectiles:
|
||||
if (!sqaureHasProjectile
|
||||
|| ((viewSquareIndex = viewSquareIndexBackup) > kViewSquare_D0C)
|
||||
/* If there is no projectile to draw or if projectiles are not visible on the specified square or on the cell being drawn */
|
||||
|| (!(projectilePosX = gObjectCoordinateSets[0][viewSquareIndex][AL_2_viewCell = currentViewCellToDraw][0])))
|
||||
continue;
|
||||
thingParam = firstThingToDraw; /* Restart processing list of objects from the beginning. The next loop draws only projectile objects among the list */
|
||||
|
||||
do {
|
||||
if ((thingParam.getType() == kProjectileThingType) && (thingParam.getCell() == cellYellowBear)) {
|
||||
projectile = (Projectile*)dunMan.getThingData(thingParam);
|
||||
if ((AL_4_projectileAspect = dunMan.getProjectileAspect(projectile->_object)) < 0) { /* Negative value: projectile aspect is the ordinal of a PROJECTIL_ASPECT */
|
||||
objectAspect = (ObjectAspect*)&gProjectileAspect[_vm->ordinalToIndex(-AL_4_projectileAspect)];
|
||||
AL_4_nativeBitmapIndex = ((ProjectileAspect*)objectAspect)->_firstNativeBitmapRelativeIndex + kFirstProjectileGraphicIndice;
|
||||
projectileAspectType = getFlag(((ProjectileAspect*)objectAspect)->_graphicInfo, kProjectileAspectTypeMask);
|
||||
if (((doNotScaleWithKineticEnergy = !getFlag(((ProjectileAspect*)objectAspect)->_graphicInfo, kProjectileScaleWithKineticEnergyMask))
|
||||
|| (projectile->_kineticEnergy == 255)) && (viewSquareIndex == kViewSquare_D0C)) {
|
||||
scale = 0; /* Use native bitmap without resizing */
|
||||
byteWidth = ((ProjectileAspect*)objectAspect)->_width;
|
||||
heightRedEagle = ((ProjectileAspect*)objectAspect)->_height;
|
||||
} else {
|
||||
AL_8_projectileScaleIndex = ((viewSquareIndex / 3) << 1) + (AL_2_viewCell >> 1);
|
||||
scale = gProjectileScales[AL_8_projectileScaleIndex];
|
||||
if (!doNotScaleWithKineticEnergy) {
|
||||
scale = (scale * MAX(96, projectile->_kineticEnergy + 1)) >> 8;
|
||||
}
|
||||
byteWidth = getScaledDimension(((ProjectileAspect*)objectAspect)->_width, scale);
|
||||
heightRedEagle = getScaledDimension(((ProjectileAspect*)objectAspect)->_height, scale);
|
||||
}
|
||||
if (projectileAspectTypeHasBackGraphicAndRotation = (projectileAspectType == kProjectileAspectHasBackGraphicRotation)) {
|
||||
projectileFlipVertical = ((mapXpos + mapYpos) & 0x0001);
|
||||
}
|
||||
if (projectileAspectType == kProjectileAspectHasNone) {
|
||||
projectileBitmapIndexData = 0;
|
||||
flipVertical = flipHorizontal = false;
|
||||
} else {
|
||||
if (isOrientedWestEast((direction)(projectileDirection = _vm->_timeline->_events[projectile->_timerIndex]._C._projectile.getDir()))
|
||||
!= isOrientedWestEast(directionParam)) {
|
||||
if (projectileAspectType == kProjectileAspectHasRotation) {
|
||||
projectileBitmapIndexData = 1;
|
||||
} else {
|
||||
projectileBitmapIndexData = 2;
|
||||
}
|
||||
if (projectileAspectTypeHasBackGraphicAndRotation) {
|
||||
flipHorizontal = !AL_2_viewCell || (AL_2_viewCell == kViewCellBackLeft);
|
||||
if (!(flipVertical = projectileFlipVertical)) {
|
||||
flipHorizontal = !flipHorizontal;
|
||||
}
|
||||
} else {
|
||||
flipVertical = false;
|
||||
flipHorizontal = (returnNextVal(directionParam) == projectileDirection);
|
||||
}
|
||||
} else {
|
||||
/* If the projectile does not have a back graphic or has one but is not seen from the back or if it has a back graphic and rotation and should be flipped vertically */
|
||||
if ((projectileAspectType >= kProjectileAspectHasRotation)
|
||||
|| ((projectileAspectType == kProjectileAspectBackGraphic)
|
||||
&& (projectileDirection != directionParam)) || (projectileAspectTypeHasBackGraphicAndRotation && projectileFlipVertical)) {
|
||||
projectileBitmapIndexData = 0;
|
||||
} else {
|
||||
projectileBitmapIndexData = 1;
|
||||
}
|
||||
flipVertical = projectileAspectTypeHasBackGraphicAndRotation && (AL_2_viewCell < kViewCellBackRight);
|
||||
flipHorizontal = getFlag(((ProjectileAspect*)objectAspect)->_graphicInfo, kProjectileSideMask)
|
||||
&& !((viewLane == kViewLaneRight) || (!viewLane && ((AL_2_viewCell == kViewCellFrontRight) || (AL_2_viewCell == kViewCellBackRight))));
|
||||
}
|
||||
}
|
||||
AL_4_nativeBitmapIndex += projectileBitmapIndexData;
|
||||
paddingPixelCount = 0;
|
||||
if (!scale) {
|
||||
AL_6_bitmapRedBanana = getBitmap(AL_4_nativeBitmapIndex);
|
||||
} else {
|
||||
if (flipHorizontal) {
|
||||
paddingPixelCount = (7 - ((byteWidth / 2 - 1) & 0x0007)) << 1;
|
||||
}
|
||||
derivedBitmapIndex = kDerivedBitmapFirstProjectile + ((ProjectileAspect*)objectAspect)->_firstNativeBitmapRelativeIndex + (projectileBitmapIndexData * 6);
|
||||
if (doNotScaleWithKineticEnergy && isDerivedBitmapInCache(derivedBitmapIndex) + AL_8_projectileScaleIndex) {
|
||||
AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
|
||||
} else {
|
||||
bitmapGreenAnt = getBitmap(AL_4_nativeBitmapIndex);
|
||||
if (doNotScaleWithKineticEnergy) {
|
||||
AL_6_bitmapRedBanana = getDerivedBitmap(derivedBitmapIndex);
|
||||
} else {
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
blitToBitmapShrinkWithPalChange(bitmapGreenAnt, ((ProjectileAspect*)objectAspect)->_width, ((ProjectileAspect*)objectAspect)->_height,
|
||||
AL_6_bitmapRedBanana, byteWidth, heightRedEagle, _palChangesProjectile[AL_8_projectileScaleIndex >> 1]);
|
||||
if (doNotScaleWithKineticEnergy) {
|
||||
warning("IGNORED CODE F0493_CACHE_AddDerivedBitmap");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (flipHorizontal || flipVertical) {
|
||||
warning("might need noralized bytewidth");
|
||||
AL_4_normalizdByteWidth = byteWidth;
|
||||
if (AL_6_bitmapRedBanana != _tmpBitmap) {
|
||||
memcpy(_tmpBitmap, AL_6_bitmapRedBanana, AL_4_normalizdByteWidth * heightRedEagle * sizeof(byte));
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
if (flipVertical) {
|
||||
flipBitmapVertical(AL_6_bitmapRedBanana, AL_4_normalizdByteWidth, heightRedEagle);
|
||||
}
|
||||
if (flipHorizontal) {
|
||||
flipBitmapHorizontal(AL_6_bitmapRedBanana, AL_4_normalizdByteWidth, heightRedEagle);
|
||||
}
|
||||
}
|
||||
boxByteGreen._y2 = (heightRedEagle >> 1) + 47 + 1;
|
||||
boxByteGreen._y1 = 47 - (heightRedEagle >> 1) + !(heightRedEagle & 0x0001);
|
||||
boxByteGreen._x2 = MIN(223, projectilePosX + byteWidth) + 1;
|
||||
if (boxByteGreen._x1 = MAX(0, projectilePosX - byteWidth + 1)) {
|
||||
if (flipHorizontal) {
|
||||
AL_4_xPos = paddingPixelCount;
|
||||
} else {
|
||||
AL_4_xPos = 0;
|
||||
}
|
||||
} else {
|
||||
/* BUG0_06 Graphical glitch when drawing projectiles or explosions. If a projectile or explosion bitmap
|
||||
is cropped because it is only partly visible on the left side of the viewport (boxByteGreen.X1 = 0) and
|
||||
the bitmap is flipped horizontally (flipHorizontal = C1_TRUE) then a wrong part of the bitmap is drawn on
|
||||
screen. To fix this bug, "+ paddingPixelCount" must be added to the second parameter of this function call */
|
||||
AL_4_xPos = MAX(paddingPixelCount, (int16)(byteWidth - projectilePosX - 1));
|
||||
}
|
||||
blitToScreen(AL_6_bitmapRedBanana, byteWidth, AL_4_xPos, 0, boxByteGreen, kColorFlesh, gDungeonViewport);
|
||||
} else { /* Positive value: projectile aspect is the index of a OBJECT_ASPECT */
|
||||
useAlcoveObjectImage = false;
|
||||
projectileCoordinates[0] = projectilePosX;
|
||||
projectileCoordinates[1] = 47;
|
||||
coordinateSet = projectileCoordinates;
|
||||
objectAspect = &gObjectAspects[AL_4_projectileAspect];
|
||||
AL_4_nativeBitmapIndex = objectAspect->_firstNativeBitmapRelativeIndex + kFirstObjectGraphicIndice;
|
||||
drawProjectileAsObject = true;
|
||||
/* Go to code section to draw an object. Once completed, it jumps back to T0115171_BackFromT0115015_DrawProjectileAsObject below */
|
||||
goto T0115015_DrawProjectileAsObject;
|
||||
}
|
||||
}
|
||||
T0115171_BackFromT0115015_DrawProjectileAsObject:;
|
||||
} while ((thingParam = dunMan.getNextThing(thingParam)) != Thing::_endOfList);
|
||||
|
||||
} while (remainingViewCellOrdinalsToProcess);
|
||||
|
||||
|
||||
/* Draw explosions */
|
||||
if (!squareHasExplosion)
|
||||
return;
|
||||
fluxcageExplosion = 0;
|
||||
AL_1_viewSquareExplosionIndex = viewSquareIndexBackup + 3; /* Convert square index to square index for explosions */
|
||||
uint16 explosionScaleIndex = AL_1_viewSquareExplosionIndex / 3;
|
||||
thingParam = firstThingToDraw; /* Restart processing list of things from the beginning. The next loop draws only explosion things among the list */
|
||||
do {
|
||||
if (thingParam.getType() == kExplosionThingType) {
|
||||
AL_2_cellPurpleMan = thingParam.getCell();
|
||||
explosion = (Explosion*)dunMan.getThingData(thingParam);
|
||||
if ((rebirthExplosion = ((unsigned int)(AL_4_explosionType = explosion->getType()) >= kExplosionType_RebirthStep1))
|
||||
&& ((AL_1_viewSquareExplosionIndex < kViewSquare_D3C_Explosion)
|
||||
|| (AL_1_viewSquareExplosionIndex > kViewSquare_D1C_Explosion)
|
||||
|| (AL_2_cellPurpleMan != cellYellowBear))) /* If explosion is rebirth and is not visible */
|
||||
continue;
|
||||
smoke = false;
|
||||
if ((AL_4_explosionType == kExplosionType_Fireball) || (AL_4_explosionType == kExplosionType_LightningBolt) || (AL_4_explosionType == kExplosionType_RebirthStep2)) {
|
||||
AL_4_explosionAspectIndex = kExplosionAspectFire;
|
||||
} else {
|
||||
if ((AL_4_explosionType == kExplosionType_PoisonBolt) || (AL_4_explosionType == kExplosionType_PoisonCloud)) {
|
||||
AL_4_explosionAspectIndex = kExplosionAspectPoison;
|
||||
} else {
|
||||
if (AL_4_explosionType == kExplosionType_Smoke) {
|
||||
smoke = true;
|
||||
AL_4_explosionAspectIndex = kExplosionAspectSmoke;
|
||||
} else {
|
||||
if (AL_4_explosionType == kExplosionType_RebirthStep1) {
|
||||
objectAspect = (ObjectAspect*)&gProjectileAspect[_vm->ordinalToIndex(-dunMan.getProjectileAspect(Thing::_explLightningBolt))];
|
||||
AL_6_bitmapRedBanana = getBitmap(((ProjectileAspect*)objectAspect)->_firstNativeBitmapRelativeIndex + (kFirstProjectileGraphicIndice + 1));
|
||||
explosionCoordinates = gRebirthStep1ExplosionCoordinates[AL_1_viewSquareExplosionIndex - 3];
|
||||
byteWidth = getScaledDimension((((ProjectileAspect*)objectAspect)->_width), explosionCoordinates[2]);
|
||||
heightRedEagle = getScaledDimension((((ProjectileAspect*)objectAspect)->_height), explosionCoordinates[2]);
|
||||
if (AL_1_viewSquareExplosionIndex != kViewSquare_D1C_Explosion) {
|
||||
blitToBitmapShrinkWithPalChange(AL_6_bitmapRedBanana,
|
||||
((ProjectileAspect*)objectAspect)->_width, ((ProjectileAspect*)objectAspect)->_height, _tmpBitmap,
|
||||
byteWidth, heightRedEagle, gPalChangesNoChanges);
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
goto T0115200_DrawExplosion;
|
||||
}
|
||||
if (AL_4_explosionType == kExplosionType_Fluxcage) {
|
||||
if (AL_1_viewSquareExplosionIndex >= kViewSquare_D3L_Explosion) {
|
||||
fluxcageExplosion = explosion;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
AL_4_explosionAspectIndex = kExplosionAspectSpell;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (AL_1_viewSquareExplosionIndex == kViewSquare_D0C_Explosion) {
|
||||
if (smoke) {
|
||||
AL_4_explosionAspectIndex--; /* Smoke uses the same graphics as Poison Cloud, but with palette changes */
|
||||
}
|
||||
AL_4_explosionAspectIndex = AL_4_explosionAspectIndex * 3; /* 3 graphics per explosion pattern */
|
||||
if (AL_2_explosionSize = (explosion->getAttack() >> 5)) {
|
||||
AL_4_explosionAspectIndex++; /* Use second graphic in the pattern for medium explosion attack */
|
||||
if (AL_2_explosionSize > 3) {
|
||||
AL_4_explosionAspectIndex++; /* Use third graphic in the pattern for large explosion attack */
|
||||
}
|
||||
}
|
||||
warning("IGNORED CODE: F0491_CACHE_IsDerivedBitmapInCache");
|
||||
AL_6_bitmapRedBanana = getBitmap(AL_4_explosionAspectIndex + kFirstExplosionPatternGraphicIndice);
|
||||
if (smoke) {
|
||||
blitToBitmapShrinkWithPalChange(AL_6_bitmapRedBanana, 48, 32, _tmpBitmap, 48, 32, gPalChangeSmoke);
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
blitBoxFilledWithMaskedBitmapToScreen(AL_6_bitmapRedBanana, nullptr, getDerivedBitmap(kDerivedBitmapViewport), gBoxExplosionPattern_D0C,
|
||||
_vm->_rnd->getRandomNumber(4) + 87, _vm->_rnd->getRandomNumber(64),
|
||||
224, (Color)(kBlitDoNotUseMask | kColorFlesh), 0, 0, 136, 93);
|
||||
warning("IGNORED CODE: F0493_CACHE_AddDerivedBitmap");
|
||||
warning("IGNORED CODE: F0493_CACHE_AddDerivedBitmap");
|
||||
} else {
|
||||
if (rebirthExplosion) {
|
||||
explosionCoordinates = gRebirthStep2ExplosionCoordinates[AL_1_viewSquareExplosionIndex - 3];
|
||||
explosionScale = explosionCoordinates[2];
|
||||
} else {
|
||||
if (explosion->getCentered()) {
|
||||
explosionCoordinates = gCenteredExplosionCoordinates[AL_1_viewSquareExplosionIndex];
|
||||
} else {
|
||||
if ((AL_2_cellPurpleMan == directionParam) || (AL_2_cellPurpleMan == returnPrevVal(directionParam))) {
|
||||
AL_2_viewCell = kViewCellFronLeft;
|
||||
} else {
|
||||
AL_2_viewCell = kViewCellFrontRight;
|
||||
}
|
||||
explosionCoordinates = gExplosionCoordinates[AL_1_viewSquareExplosionIndex][AL_2_viewCell];
|
||||
}
|
||||
explosionScale = MAX(4, (MAX(48, explosion->getAttack() + 1) * gExplosionBaseScales[explosionScaleIndex]) >> 8) & (int16)0xFFFE;
|
||||
}
|
||||
AL_6_bitmapRedBanana = getExplosionBitmap(AL_4_explosionAspectIndex, explosionScale, byteWidth, heightRedEagle);
|
||||
T0115200_DrawExplosion:
|
||||
flipVertical = _vm->_rnd->getRandomNumber(2);
|
||||
paddingPixelCount = 0;
|
||||
if (flipHorizontal = _vm->_rnd->getRandomNumber(2)) {
|
||||
paddingPixelCount = (7 - ((byteWidth / 2 - 1) & 0x0007)) << 1; /* Number of unused pixels in the units on the right of the bitmap */
|
||||
}
|
||||
boxByteGreen._y2 = MIN(135, explosionCoordinates[1] + (heightRedEagle >> 1)) + 1;
|
||||
AL_4_yPos = MAX(0, explosionCoordinates[1] - (heightRedEagle >> 1) + !(heightRedEagle & 0x0001));
|
||||
if (AL_4_yPos >= 136)
|
||||
continue;
|
||||
boxByteGreen._y1 = AL_4_yPos;
|
||||
if ((AL_4_xPos = MIN(223, explosionCoordinates[0] + byteWidth)) < 0)
|
||||
continue;
|
||||
boxByteGreen._x2 = AL_4_xPos + 1;
|
||||
AL_4_xPos = explosionCoordinates[0];
|
||||
if (boxByteGreen._x1 = MIN(MAX(0, AL_4_xPos - byteWidth + 1), 223)) {
|
||||
AL_4_xPos = paddingPixelCount;
|
||||
} else {
|
||||
/* BUG0_07 Graphical glitch when drawing explosions. If an explosion bitmap is cropped because it is only partly visible on the
|
||||
left side of the viewport (boxByteGreen.X1 = 0) and the bitmap is not flipped horizontally (flipHorizontal = C0_FALSE) then the
|
||||
variable paddingPixelCount is not set before being used here. Its previous value (defined while drawing something else) is used
|
||||
and may cause an incorrect bitmap to be drawn */
|
||||
AL_4_xPos = MIN(paddingPixelCount,(int16)( byteWidth / 2 - AL_4_xPos - 1));
|
||||
|
||||
/* BUG0_06 Graphical glitch when drawing projectiles or explosions. If a projectile or explosion bitmap is cropped because it is
|
||||
only partly visible on the left side of the viewport (boxByteGreen.X1 = 0) and the bitmap is flipped horizontally (flipHorizontal = C1_TRUE)
|
||||
then a wrong part of the bitmap is drawn on screen. To fix this bug, "+ paddingPixelCount" must be added to the second parameter of this function call */
|
||||
}
|
||||
if (boxByteGreen._x2 - 1 <= boxByteGreen._x1)
|
||||
continue;
|
||||
warning("might need M77_NORMALIZED_BYTE_WIDTH");
|
||||
byteWidth = byteWidth;
|
||||
if (flipHorizontal || flipVertical) {
|
||||
memcpy(_tmpBitmap, AL_6_bitmapRedBanana, byteWidth * heightRedEagle);
|
||||
AL_6_bitmapRedBanana = _tmpBitmap;
|
||||
}
|
||||
if (flipHorizontal) {
|
||||
flipBitmapHorizontal(AL_6_bitmapRedBanana, byteWidth, heightRedEagle);
|
||||
}
|
||||
if (flipVertical) {
|
||||
flipBitmapVertical(AL_6_bitmapRedBanana, byteWidth, heightRedEagle);
|
||||
}
|
||||
blitToScreen(AL_6_bitmapRedBanana, byteWidth, AL_4_xPos, 0, boxByteGreen, kColorFlesh, gDungeonViewport);
|
||||
}
|
||||
}
|
||||
} while ((thingParam = dunMan.getNextThing(thingParam)) != Thing::_endOfList);
|
||||
/* Fluxcage is an explosion displayed as a field (like teleporters), above all other graphics */
|
||||
if ((fluxcageExplosion != 0) && (doorFrontViewDrawingPass != 1) && !_doNotDrawFluxcagesDuringEndgame) {
|
||||
AL_1_viewSquareExplosionIndex -= 3; /* Convert square index for explosions back to square index */
|
||||
fieldAspect = gFieldAspects[viewSquareIndex];
|
||||
(fieldAspect._nativeBitmapRelativeIndex)++; /* NativeBitmapRelativeIndex is now the index of the Fluxcage field graphic */
|
||||
drawField(&fieldAspect, *(Box*)&gFrameWalls[viewSquareIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
uint16 DisplayMan::getNormalizedByteWidthM77(uint16 byteWidth) {
|
||||
return (byteWidth + 7) & 0xFFF8;
|
||||
}
|
||||
|
||||
uint16 DisplayMan::getVerticalOffsetM23(uint16 val) {
|
||||
return (val >> 3) & 0x7;
|
||||
}
|
||||
|
||||
uint16 DisplayMan::getHorizontalOffsetM22(uint16 val) {
|
||||
return (val & 0x7);
|
||||
}
|
||||
|
||||
bool DisplayMan::isDerivedBitmapInCache(int16 derivedBitmapIndex) {
|
||||
if (_derivedBitmaps == nullptr) {
|
||||
_derivedBitmaps[derivedBitmapIndex] = new byte[_derivedBitmapByteCount[derivedBitmapIndex]];
|
||||
|
|
|
@ -37,6 +37,44 @@
|
|||
namespace DM {
|
||||
|
||||
|
||||
/* View lanes */
|
||||
#define kViewLaneCenter 0 // @ C0_VIEW_LANE_CENTER
|
||||
#define kViewLaneLeft 1 // @ C1_VIEW_LANE_LEFT
|
||||
#define kViewLaneRight 2 // @ C2_VIEW_LANE_RIGHT
|
||||
|
||||
#define kHalfSizedViewCell_LeftColumn 0 // @ C00_VIEW_CELL_LEFT_COLUMN
|
||||
#define kHalfSizedViewCell_RightColumn 1 // @ C01_VIEW_CELL_RIGHT_COLUMN
|
||||
#define kHalfSizedViewCell_BackRow 2 // @ C02_VIEW_CELL_BACK_ROW
|
||||
#define kHalfSizedViewCell_CenterColumn 3 // @ C03_VIEW_CELL_CENTER_COLUMN
|
||||
#define kHalfSizedViewCell_FrontRow 4 // @ C04_VIEW_CELL_FRONT_ROW
|
||||
|
||||
/* Shift sets */
|
||||
#define kShiftSet_D0BackD1Front 0 // @ C0_SHIFT_SET_D0_BACK_OR_D1_FRONT
|
||||
#define kShiftSet_D1BackD2Front 1 // @ C1_SHIFT_SET_D1_BACK_OR_D2_FRONT
|
||||
#define kShiftSet_D2BackD3Front 2 // @ C2_SHIFT_SET_D2_BACK_OR_D3_FRONT
|
||||
|
||||
#define kCellOrder_DoorFront 0x0008 // @ MASK0x0008_DOOR_FRONT
|
||||
#define kCellOrder_Alcove 0x0000 // @ C0000_CELL_ORDER_ALCOVE
|
||||
#define kCellOrder_BackLeft 0x0001 // @ C0001_CELL_ORDER_BACKLEFT
|
||||
#define kCellOrder_BackRight 0x0002 // @ C0002_CELL_ORDER_BACKRIGHT
|
||||
#define kCellOrder_DoorPass1_BackLeft 0x0018 // @ C0018_CELL_ORDER_DOORPASS1_BACKLEFT
|
||||
#define kCellOrder_BackLeft_BackRight 0x0021 // @ C0021_CELL_ORDER_BACKLEFT_BACKRIGHT
|
||||
#define kCellOrder_DoorPass1_BackRight 0x0028 // @ C0028_CELL_ORDER_DOORPASS1_BACKRIGHT
|
||||
#define kCellOrder_BackRight_FrontRight 0x0032 // @ C0032_CELL_ORDER_BACKRIGHT_FRONTRIGHT
|
||||
#define kCellOrder_DoorPass2_FrontRight 0x0039 // @ C0039_CELL_ORDER_DOORPASS2_FRONTRIGHT
|
||||
#define kCellOrder_BackLeft_FrontLeft 0x0041 // @ C0041_CELL_ORDER_BACKLEFT_FRONTLEFT
|
||||
#define kCellOrder_DoorPass2_FrontLeft 0x0049 // @ C0049_CELL_ORDER_DOORPASS2_FRONTLEFT
|
||||
#define kCellOrder_DoorPass1_BackRight_BackLeft 0x0128 // @ C0128_CELL_ORDER_DOORPASS1_BACKRIGHT_BACKLEFT
|
||||
#define kCellOrder_DoorPass1_BackLeft_BackRight 0x0218 // @ C0218_CELL_ORDER_DOORPASS1_BACKLEFT_BACKRIGHT
|
||||
#define kCellOrder_BackLeft_BackRight_FrontRight 0x0321 // @ C0321_CELL_ORDER_BACKLEFT_BACKRIGHT_FRONTRIGHT
|
||||
#define kCellOrder_BackRight_FrontLeft_FrontRight 0x0342 // @ C0342_CELL_ORDER_BACKRIGHT_FRONTLEFT_FRONTRIGHT
|
||||
#define kCellOrder_DoorPass2_FrontLeft_FrontRight 0x0349 // @ C0349_CELL_ORDER_DOORPASS2_FRONTLEFT_FRONTRIGHT
|
||||
#define kCellOrder_BackRight_BackLeft_FrontLeft 0x0412 // @ C0412_CELL_ORDER_BACKRIGHT_BACKLEFT_FRONTLEFT
|
||||
#define kCellOrder_BackLeft_FrontRight_FrontLeft 0x0431 // @ C0431_CELL_ORDER_BACKLEFT_FRONTRIGHT_FRONTLEFT
|
||||
#define kCellOrder_DoorPass2_FrontRight_FrontLeft 0x0439 // @ C0439_CELL_ORDER_DOORPASS2_FRONTRIGHT_FRONTLEFT
|
||||
#define kCellOrder_BackLeft_BackRight_FrontLeft_FrontRight 0x3421 // @ C3421_CELL_ORDER_BACKLEFT_BACKRIGHT_FRONTLEFT_FRONTRIGHT
|
||||
#define kCellOrder_BackRight_BackLeft_FrontRight_FrontLeft 0x4312 // @ C4312_CELL_ORDER_BACKRIGHT_BACKLEFT_FRONTRIGHT_FRONTLEFT
|
||||
|
||||
|
||||
#define kFloorSetGraphicCount 2 // @ C002_FLOOR_SET_GRAPHIC_COUNT
|
||||
#define kWallSetGraphicCount 13 // @ C013_WALL_SET_GRAPHIC_COUNT
|
||||
|
@ -167,7 +205,11 @@ enum GraphicIndice {
|
|||
kFloorOrn_15_D3L_footprints = 241, // @ C241_GRAPHIC_FLOOR_ORNAMENT_15_D3L_FOOTPRINTS
|
||||
kFieldMask_D3R_GraphicIndice = 69, // @ C069_GRAPHIC_FIELD_MASK_D3R
|
||||
kFieldTeleporterGraphicIndice = 73, // @ C073_GRAPHIC_FIELD_TELEPORTER
|
||||
kFirstExplosionGraphicIndice = 348 // @ C348_GRAPHIC_FIRST_EXPLOSION
|
||||
kFirstExplosionGraphicIndice = 348, // @ C348_GRAPHIC_FIRST_EXPLOSION
|
||||
kFirstObjectGraphicIndice = 360, // @ C360_GRAPHIC_FIRST_OBJECT
|
||||
kFirstCreatureGraphicIndice = 446, // @ C446_GRAPHIC_FIRST_CREATURE
|
||||
kFirstProjectileGraphicIndice = 316, // @ C316_GRAPHIC_FIRST_PROJECTILE
|
||||
kFirstExplosionPatternGraphicIndice = 351 // @ C351_GRAPHIC_FIRST_EXPLOSION_PATTERN
|
||||
};
|
||||
|
||||
extern uint16 gPalSwoosh[16];
|
||||
|
@ -284,6 +326,7 @@ public:
|
|||
FieldAspect(uint16 native, uint16 base, uint16 transparent, byte mask, uint16 byteWidth, uint16 height, uint16 xPos, uint16 bitplane)
|
||||
: _nativeBitmapRelativeIndex(native), _baseStartUnitIndex(base), _transparentColor(transparent), _mask(mask),
|
||||
_pixelWidth(byteWidth * 2), _height(height), _xPos(xPos), _bitplaneWordCount(bitplane) {}
|
||||
FieldAspect() {}
|
||||
}; // @ FIELD_ASPECT
|
||||
|
||||
|
||||
|
@ -455,7 +498,7 @@ public:
|
|||
int16 xPos, int16 yPos, int16 destHeight, int16 height2, Viewport &viewport = gDefultViewPort); // @ F0133_VIDEO_BlitBoxFilledWithMaskedBitmap
|
||||
void blitBoxFilledWithMaskedBitmapToScreen(byte *src, byte *mask, byte *tmp, Box &box, int16 lastUnitIndex,
|
||||
int16 firstUnitIndex, int16 destPixelWidth, Color transparent,
|
||||
int16 xPos, int16 yPos, int16 height2, Viewport &viewport = gDungeonViewport); // @ F0133_VIDEO_BlitBoxFilledWithMaskedBitmap
|
||||
int16 xPos, int16 yPos, int16 destHeight, int16 height2, Viewport &viewport = gDungeonViewport); // @ F0133_VIDEO_BlitBoxFilledWithMaskedBitmap
|
||||
|
||||
void flipBitmapHorizontal(byte *bitmap, uint16 width, uint16 height);
|
||||
void flipBitmapVertical(byte *bitmap, uint16 width, uint16 height);
|
||||
|
@ -473,9 +516,12 @@ public:
|
|||
|
||||
int16 getScaledBitmapPixelCount(int16 pixelWidth, int16 pixelHeight, int16 scale); // @ F0459_START_GetScaledBitmapByteCount
|
||||
int16 getScaledDimension(int16 dimension, int16 scale); // @ M78_SCALED_DIMENSION
|
||||
void drawObjectsCreaturesProjectilesExplosions(Thing thingParam, direction directionParam,
|
||||
void cthulhu(Thing thingParam, direction directionParam,
|
||||
int16 mapXpos, int16 mapYpos, int16 viewSquareIndex,
|
||||
uint16 orderedViewCellOrdinals); // @ F0115_DUNGEONVIEW_DrawObjectsCreaturesProjectilesExplosions_CPSEF
|
||||
uint16 getNormalizedByteWidthM77(uint16 byteWidth); // @ M77_NORMALIZED_BYTE_WIDTH
|
||||
uint16 getVerticalOffsetM23(uint16 val); // @ M23_VERTICAL_OFFSET
|
||||
uint16 getHorizontalOffsetM22(uint16 val); // @ M22_HORIZONTAL_OFFSET
|
||||
|
||||
int16 _championPortraitOrdinal; // @ G0289_i_DungeonView_ChampionPortraitOrdinal
|
||||
int16 _currMapAlcoveOrnIndices[kAlcoveOrnCount]; // @ G0267_ai_CurrentMapAlcoveOrnamentIndices
|
||||
|
|
|
@ -82,6 +82,10 @@ enum CreatureType {
|
|||
#define kMaskCreatureInfo_archenemy 0x2000 // @ MASK0x2000_ARCHENEMY
|
||||
#define kMaskCreatureInfo_magicmap 0x4000 // @ MASK0x4000_MAGICMAP
|
||||
|
||||
|
||||
#define kMaskActiveGroupFlipBitmap 0x0040 // @ MASK0x0040_FLIP_BITMAP
|
||||
#define kMaskActiveGroupIsAttacking 0x0080 // @ MASK0x0080_IS_ATTACKING
|
||||
|
||||
class ActiveGroup {
|
||||
public:
|
||||
int _groupThingIndex;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue