This function was one I didn't care to reverse, but it caught my attention of some reason or another. This function is called in the player nametags function(as well as many other functions). I'm working on the nametags function because it has the engine world space to screen space, which I'm using for CE Forge. I will be posting that next when it's done. This is for Halo CE 1.08.
Thnx to OllyDbg, IDA Pro, Hexrays, and Kornman00.
Needed structs/globals:
Code:
typedef signed int int32; typedef unsigned int uint32;
typedef signed short int16; typedef unsigned short uint16;
typedef signed char int8; typedef unsigned char uint8;
#define TAGINDEX 0x00816D04
#define INVALID -1
struct Identity
{
union
{
uint32 Ident;
struct
{
int16 Index;
int16 Salt;
};
};
};
struct TagInstance
{
union
{
uint32 TagGroup; // 0x00
uint8 TagGroupC[4]; // 0x00
};
union
{
uint32 TagChild; // 0x04
uint8 TagChildC[4]; // 0x04
};
union
{
uint32 TagParent; // 0x08
uint8 TagParentC[4]; // 0x08
};
Identity Tag; // 0x0C
uint8 *Name; // 0x10
void *Address; // 0x14
uint32 Location; // 0x18
uint32 _Unused; // 0x1C
}; // Size = 32 bytes(0x20)
struct TagBlock
{
uint32 Count; // 0x00
uint32 Address; // 0x04
uint32 Padding; // 0x08
}; // Size = 12 bytes(0x0C)
struct TagReference
{
uint32 TagGroup; // 0x00
uint8* Name; // 0x04
uint32 NameLength; // 0x08
Identity Tag; // 0x0C
}; // Size = 16 bytes(0x10)
struct Bitmap // 'bitm'
{
// Sprite Processing
uint32 SpriteBudgetSize;
uint32 SpriteBudgetCount;
// Post Processing
uint32 DetailFadeFactor;
uint32 SharpenAmount;
uint32 BumpHeight;
// Usage
uint16 Usage;
// Format
uint16 Format;
// Color Plate
uint16 ColorPlateWidth;
uint16 ColorPlateHeight;
uint32 CompressedColorPlateData;
uint8 Unknown[24];
// Processed Pixel Data
uint32 ProcessedPixelData;
uint8 Unknown2[20];
// ...More Sprite Processing
uint32 SpriteSpacing;
TagBlock Sequences;
TagBlock Bitmaps;
};
//----------------------------------------------
struct BitmapSequence
{
uint8 Name[32];
uint16 FirstBitmapIndex;
uint16 BitmapCount;
uint8 Unknown[12];
TagBlock Sprites;
};
//----------------------------------------------
struct BitmapSequenceSprite
{
float Unknown;
uint32 BitmapIndex;
float Left;
float Right;
float Top;
float Bottom;
float RegistrationPoint[2];
};
//----------------------------------------------
struct BitmapBitmap
{
uint32 Signature; // 'bitm'
uint16 Width;
uint16 Height;
uint16 Depth;
uint16 Type;
uint16 Format;
uint16 Flags;
uint16 RegistrationPointX;
uint16 RegistrationPointY;
uint16 MipMapCount;
uint32 PixelsOffset;
uint32 Size;
Identity BitmapIdent; // Maybe??
uint8 Unknown[12];
};
Code:
BitmapBitmap* GetBitmapBySequence(Identity BitmapIdentity, uint32 SpriteIndex, uint32 SequenceIndex)
{
uint16 BitmapIndex;
if(BitmapIdentity.Ident != INVALID)
{
uint32 BitmInstOffset = sizeof(TagInstance) * BitmapIdentity.Index;
TagInstance* BitmInstance = (TagInstance*)((uint32)*(Bitmap**)TAGINDEX + BitmInstOffset);
Bitmap* pBitmap = (Bitmap*)BitmInstance->Address;
if(!pBitmap)
return NULL;
if(pBitmap->Sequences.Count > 0)
{
uint32 BitmSeqOffset = sizeof(BitmapSequence) * (SequenceIndex % pBitmap->Sequences.Count);
BitmapSequence* BitmSequence = (BitmapSequence*)(pBitmap->Sequences.Address + BitmSeqOffset);
if(BitmSequence->BitmapCount <= 0)
{
if(BitmSequence->Sprites.Count)
{
uint32 BitmSeqSpriteOffset = sizeof(BitmapSequenceSprite) * SpriteIndex;
BitmapSequenceSprite* BitmSeqSprite = (BitmapSequenceSprite*)((uint32)BitmSequence->Sprites.Address + BitmSeqSpriteOffset);
BitmapIndex = BitmSeqSprite->BitmapIndex;
}
else
BitmapIndex = SpriteIndex;
}
else
BitmapIndex = BitmSequence->FirstBitmapIndex + (SpriteIndex % BitmSequence->BitmapCount);
}
else
BitmapIndex = SpriteIndex;
if(BitmapIndex == INVALID)
BitmapIndex = SpriteIndex;
if(BitmapIndex >= 0 && BitmapIndex < pBitmap->Bitmaps.Count)
{
uint32 BitmBitmOffset = sizeof(BitmapBitmap) * BitmapIndex;
return (BitmapBitmap*)(pBitmap->Bitmaps.Address + BitmBitmOffset);
}
}
return NULL;
}
Original Disassembly:
Code:
CPU Disasm
Address Command
0043F290 PUSH EBX
0043F291 XOR EBX,EBX
0043F293 CMP EAX,-1
0043F296 JE 0043F325
0043F29C MOV ECX,DWORD PTR DS:[816D04]
0043F2A2 AND EAX,0000FFFF
0043F2A7 SHL EAX,5
0043F2AA PUSH ESI
0043F2AB MOV ESI,DWORD PTR DS:[ECX+EAX+14]
0043F2AF TEST ESI,ESI
0043F2B1 JE SHORT 0043F320
0043F2B3 MOV ECX,DWORD PTR DS:[ESI+54]
0043F2B6 TEST ECX,ECX
0043F2B8 PUSH EBP
0043F2B9 JLE SHORT 0043F300
0043F2BB MOVSX EAX,WORD PTR SS:[Arg1]
0043F2C0 CDQ
0043F2C1 IDIV ECX
0043F2C3 MOV EBP,DWORD PTR DS:[ESI+58]
0043F2C6 MOV ECX,EDX
0043F2C8 SHL ECX,6
0043F2CB MOV AX,WORD PTR DS:[EBP+ECX+22]
0043F2D0 ADD ECX,EBP
0043F2D2 TEST AX,AX
0043F2D5 JLE SHORT 0043F2E6
0043F2D7 MOVSX EBP,AX
0043F2DA MOVSX EAX,DI
0043F2DD CDQ
0043F2DE IDIV EBP
0043F2E0 ADD DX,WORD PTR DS:[ECX+20]
0043F2E4 JMP SHORT 0043F2FA
0043F2E6 MOV EAX,DWORD PTR DS:[ECX+34]
0043F2E9 TEST EAX,EAX
0043F2EB JE SHORT 0043F300
0043F2ED MOV EAX,DWORD PTR DS:[ECX+38]
0043F2F0 MOVSX EDX,DI
0043F2F3 SHL EDX,5
0043F2F6 MOV DX,WORD PTR DS:[EAX+EDX]
0043F2FA CMP DX,0FFFF
0043F2FE JNE SHORT 0043F302
0043F300 MOV EDX,EDI
0043F302 TEST DX,DX
0043F305 POP EBP
0043F306 JL SHORT 0043F320
0043F308 MOV ECX,DWORD PTR DS:[ESI+60]
0043F30B MOVSX EAX,DX
0043F30E CMP EAX,ECX
0043F310 JGE SHORT 0043F320
0043F312 MOV ECX,DWORD PTR DS:[ESI+64]
0043F315 LEA EAX,[EAX*2+EAX]
0043F318 SHL EAX,4
0043F31B POP ESI
0043F31C ADD EAX,ECX
0043F31E POP EBX
0043F31F RETN
0043F320 POP ESI
0043F321 MOV EAX,EBX
0043F323 POP EBX
0043F324 RETN
0043F325 MOV EAX,EBX
0043F327 POP EBX
0043F328 RETN
Bookmarks