Ok, said routine handles drawing unit graphics. For vehicles, there is a call for the chasis of the vehicle followed by a call for the turret. Changing the values can also make the unit look like a building. As a simple edit, I changed the push register to the one holding the y coordinate and watched the unit go through some interesting animations while moving up and down. (Blowing up, becoming a damaged building, etc.)
I've also found out from the graphics routine a few other things. It uses the same call to display the sticky foam and the EMP animation and that display was controlled by two flags. I've also found that both stickyfoam and EMP have seperate timers in the Unit record.
offset size Description
------ ----- -------------
0x4E 0x2 timerStickyfoam - number of game ticks before stickyfoam wears off
0x50 0x2 timerEMP - number of game ticks before EMP wears off
bit flags (at offset 0x44)
---------
bit # bitmask Description
----- --------- ------------
0x12 0x00040000 IsStickyfoamed - Set if unit is locked down by stickyfoam (Also needs timer set properly, timer>0)
0x13 0x00080000 IsEMPed - Set if unit is disabled by EMP (timer will cound down until worn off)
Note: There is a difference in how the timer values are handled between stickyfoam and EMP. It appeasr the EMP timer is handled properly as an unsigned value but the stickyfoam timer needs to be a positive signed short. Also, if the timer is initially zero when the flag is set, the EMP timer will wrap around and the unit will be EMPed for a very long time. But for stickyfoam, the timer wraps around to a garbage negative number and causes graphics glitches. (My Lynx looked like a university with a turret). You also lose control of the unit and the game may eventually crash.
As for that graphics function, there are 6 arguments. I've figured out a few of them.
0x403F20 DrawGraphic(int graphic, int unknown1, int pixelX, int pixelY, int unknown2, int unknown3)
Note: The pixelX and pixelY values are relative to the upper left corner of the map, and not the upper left corner of the visible portion of the map. Hence they should be treated as absolute map coordinates and not relative to the view pane.
I also suspect which graphic in an animation sequence in controlled by one of the parameters. Most likely unknown1 if that is the case. I'll look into it eventually.
The Vol loading code contains a bug! For the Index section ("voli"), it calculates the number of index entries by dividing the section size by 14 (sizeof(IndexEntry) = 14). It then allocates numIndexEntries*sizeof(IndexEntry) bytes to store the data. But, the problem is, it still reads in sectionSize bytes. This is actually an issue since the entries are not DWORD size aligned and the original Vol files contain an odd number of index entries in some of them. (Like in Sheets.vol, 15 entries). In those cases, it'll read more bytes than it's allocated buffer space for. In this case, it only reads an extra 2 bytes but it could read up to 13 bytes past the end of the buffer.
Well, looks like there is another possible exploit. :ph34r: Actually, you probably can't do much with this one since it probably just overwrites unallocated memory that really means nothing anyways. But still, it has the potential to cause problems.
Edit: My bad. The extra byets are padding bytes and the section size doesn't include them (Section size IS a multiple of 14). So there shouldn't be any problems..., with a properly structured file. If the section size isn't a multiple of 14 then that problem will exist.