Open main menu

Difference between revisions of "AGI/Specifications/Other/AGI256-2/Implementation Details"

Added reverse engineered C version of AGIOBJS.OVL.
(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===
417

edits