417
edits
(Added AGIOBJS.OVL's disassembly.) |
(Added reverse engineered C version of AGIOBJS.OVL.) |
||
Line 14: | Line 14: | ||
The only coded changes are in AGIOBJS.OVL. Data files have more differences though. | The only coded changes are in AGIOBJS.OVL. Data files have more differences though. | ||
===Reverse engineered C version of AGI256-2's AGIOBJS.OVL=== | |||
Things may be wrong, misleading etc. Caveat emptor. | |||
This is not a straight assembly to C conversion of the source data. | |||
The routine has been modified to look better, agi256_2 parameter | |||
has been added and possibly other things. | |||
It should give you an idea how it works though. | |||
<pre> | |||
struct blitStruct { | |||
uint8 b0; | |||
uint8 b1; | |||
uint8 notEgo; // Sort of a guess based on variable's usage, may also be dontUpdateEgoVisibility or something like that | |||
uint16 xPos; | |||
uint16 yPos; // Is this named correctly? | |||
uint8 b7; | |||
uint8 b8; | |||
uint8 b9; | |||
uint8 b10; | |||
uint8 b11; | |||
uint8 b12; | |||
uint8 b13; | |||
uint8 b14; | |||
uint8 b15; | |||
struct celStruct *celPtr; // Offset into segment DS really, 16 bits | |||
uint8 b18; | |||
uint8 b19; | |||
uint8 b20; | |||
uint8 b21; | |||
uint8 b22; | |||
uint8 b23; | |||
uint8 b24; | |||
uint8 b25; | |||
uint8 b26; | |||
uint8 b27; | |||
uint8 b28; | |||
uint8 b29; | |||
uint8 b30; | |||
uint8 b31; | |||
uint8 b32; | |||
uint8 b33; | |||
uint8 b34; | |||
uint8 b35; | |||
uint8 celPriority; | |||
}; | |||
struct celStruct { | |||
uint8 width; // This is a guess | |||
uint8 height; | |||
union { | |||
uint8 flags; // Uses values from enum flagsEnum | |||
uint8 transparentColor; // Only lower 4 bits | |||
}; | |||
uint8 rleData[?]; | |||
}; | |||
enum flagsEnum { | |||
F_MIRROR = 1 << 7; | |||
}; | |||
#define _WIDTH 160 | |||
#define _HEIGHT 168 | |||
uint16 screenOffset(uint8 x, uint8 y) { | |||
return y * (_WIDTH * 2) + x; | |||
} | |||
void agi256BlitCel(struct blitStruct *s, bool agi256_2) { | |||
uint8 *pic = &agi256PicSeg[0]; | |||
const uint16 endPos = (_WIDTH * 2) * (_HEIGHT - 1); // I would have put (((_WIDTH * 2) * (_HEIGHT - 1)) - _WIDTH) here | |||
bool celInvisible = true; | |||
uint8 height = s->celPtr->height; | |||
uint8 celPriority = s->celPriority; | |||
if (!agi256_2 && s->celPtr->flags & F_MIRROR) // Test for mirroring | |||
blitMirrorCell(); | |||
uint8 *rleData = s->celPtr->rleData; | |||
uint16 pos = screenOffset(s->xPos, s->yPos - height + 1); | |||
uint8 transparentColor = s->celPtr->transparentColor; | |||
do { | |||
uint16 oldPos = pos; | |||
while (uint8 rleByte = *(rleData++)) { // rleByte != 0 | |||
uint8 runColor = agi256_2 ? rleByte : rleByte >> 4; | |||
uint8 runLength = agi256_2 ? 1 : rleByte & 0x0f; | |||
if (runColor == transparentColor) { // Check for transparency | |||
pos += runLength; | |||
} else do { | |||
uint8 pixelPriority = pic[pos] >> 4; // Read pixel's priority/control line info | |||
if (pixelPriority < 3) { | |||
pixelPriority = 0; | |||
for (uint16 ySearchPos = pos + _WIDTH * 2; | |||
ySearchPos < endPos && (pixelPriority = pic[ySearchPos] >> 4) < 3; | |||
ySearchPos += _WIDTH * 2); | |||
} | |||
if (celPriority >= pixelPriority) { | |||
pic[pos + _WIDTH] = runColor; | |||
celInvisible = false; | |||
} | |||
pos++; | |||
} while (--runLength > 0); | |||
} | |||
pos = oldPos + _WIDTH * 2; | |||
} while (--height > 0); | |||
if (!s->notEgo) | |||
setFlag(f1, celInvisible); | |||
} | |||
</pre> | |||
===Disassembly of AGIOBJS.OVL showing differences between AGI256 and AGI256-2=== | ===Disassembly of AGIOBJS.OVL showing differences between AGI256 and AGI256-2=== |
edits