Johnny did a marvelous job reverse engineering some of the Ecco aspects. The problem was that there was never much of it documented and with Dark Sea long gone there isn't really a good reliable source of information for the others to pick up.
Since I am following up on some of the sections of Tides of Time, such as password system and related elements, I will be documenting my findings here.
The posts will not be following any structure in particular at the moment and I will merely be posting things as I run into and disassemble them.
This first message in the topic can serve as an index and I will likely put a table of contents here.
Ecco II Disassembly: Random Bits and Bobs
Re: Ecco II Disassembly: Random Bits and Bobs
First random bit of Ecco II code analysis.
The Asterite.
Curiously enough, he is actually stored as two halves inside two 32-bit variables at RAM addresses 0xD434 and 0xD438. Every globe is represented by a single bit in those: e.g., 0x0F is 4, 0xFF is 8, etc., up to 32 in each helix.
It is possible by manipulating those variables to spawn an "asymmetrical" Asterite, as well as making "holes" in him: the game does not mind this. However, none of the functions that I have met so far appear to be using this and in fact the one responsible for counting globe pairs will return -1 if pairs mismatch. It's possible that they were intending to manipulate individual globes, such as in Ecco 1, but feature ended up never used.
Storing data like this is very inefficient otherwise, but they can get away with this since that is really only used when saving the game in a password and restoring it from that.
The following is a reconstruction of the function at ROM offset 0xB0BA4 that counts the globes:
Function to populate Asterite at ROM offset 0xB0BD8:
Following that is a function at ROM offset 0xB0BFC that initializes Asterite, setting both globe variables to 1, but it also takes care to fill 196 bytes at 0xD35E with zeroes. It actually makes more sense to post the raw disassembly of it for now since it's very short:
Essentially a memset() and two assignments, really. I have not yet worked out what said location does exactly but so far my hunch is that the actual globe objects are to be stored there for animating them. This array is referenced in a lot of functions:
The Asterite.
Curiously enough, he is actually stored as two halves inside two 32-bit variables at RAM addresses 0xD434 and 0xD438. Every globe is represented by a single bit in those: e.g., 0x0F is 4, 0xFF is 8, etc., up to 32 in each helix.
Code: Select all
// Global variables to store Asterite's status
// RAM addresses 0xD434 and 0xD438
uint32_t gAsteriteGlobesLeft, gAsteriteGlobesRight;Storing data like this is very inefficient otherwise, but they can get away with this since that is really only used when saving the game in a password and restoring it from that.
The following is a reconstruction of the function at ROM offset 0xB0BA4 that counts the globes:
Code: Select all
int countAsteriteGlobePairs(void) {
int retval = -1;
uint32_t MASK = 0x80000000;
int16_t globeCount = 0;
if (gAsteriteGlobesLeft == gAsteriteGlobesRight) {
for (uint16_t i = 32; i > 0; i--) {
if ((gAsteriteGlobesLeft & MASK) != 0) {
globeCount++;
}
MASK = MASK >> 1;
}
retval = globeCount;
}
return retval;
}Code: Select all
void setAsteriteGlobes(uint8_t numPairs) {
uint8_t i;
uint32_t MASK = 1;
gAsteriteGlobesLeft = 0;
for(i = numPairs; i > 0; i--) {
gAsteriteGlobesLeft |= MASK;
MASK = MASK << 1;
}
gAsteriteGlobesRight = gAsteriteGlobesLeft;
return;
}Code: Select all
clearAsteriteGlobes:
moveq #0x0,D1
lea (DAT_ffffd35e).w,A1
movea.w #0x31,A0
moveq #0x0,D0
.loop:
move.l D0,(A1)+
addq.w #0x1,D1w
cmp.w A0w,D1w
blt.b .loop
moveq #0x1,D0
move.l D0,(gAsteriteGlobesLeft).w
move.l D0,(gAsteriteGlobesRight).w
rts
Code: Select all
fClearAsteriteGlobes:000b0bfe(*),
fClearAsteriteGlobes:000b0c08(W),
FUN_000b1536:000b1542(*),
FUN_000b1536:000b154e(*),
FUN_000b1554:000b1562(*),
FUN_000b1554:000b156e(*),
FUN_000b1574:000b1580(*),
FUN_000b1574:000b158c(*),
FUN_000b1f60:000b20f8(*),
FUN_000b2208:000b2260(*)