View Single Post
Compiler wierdness
Old
  (#1)
Lazy
Member
 
Lazy's Avatar
 
Status: Offline
Posts: 236
Join Date: Jan 2004
Location: Toronto, Ontario, Canada
Default Compiler wierdness - 23-09-2005

After a few days of on/off work I have for the most part figured out the half-life sprite file format.
It would have been done faster except I kept missing the fact that even the first frame has a frame header instead of using the sprite header, anyway...

Here is what I have so far...
Code:
// Should be at the start of the file, identifies this as a sprite
const int HL_SPR_IDENTITY = ( int ) ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'D' << 8 ) + ( 'I' );

// Half-life sprite file structure...
// ---------------------
// Header 42 bytes
// Palette 768 bytes
// Frame header 20 bytes
// Image data ( frame header->width * frame header->height )
// ...
// If you have more than one frame...
// Frame header 20 bytes
// Image data ( frame header->width * frame header->height )
// ...
// ... ect...

// Half-life sprite rendering modes, these determine how sprites are
// rendered by the engine.
enum hl_sprite_rendermodes_e {
   SPR_MODE_NORMAL = 0, // Normal rendering
   SPR_MODE_ADDITIVE,   // Black ( RGB 0, 0, 0 ) is transparent
   SPR_MODE_INDEXALPHA, // Last color in palette is the sprite's in-game color
   SPR_MODE_ALPHATEST   // Last color in palette is transparent
};

// Half-life sprite types, these determine how the sprite rotates
// when viewed by a player in-game.
enum hl_sprite_type_e {
   SPR_TYPE_ROTATE_Y_ONLY = 0,   // Sprite does not rotate on the X axis
SPR_TYPE_ONE_WAY,			 // Sprite faces one way and does not rotate ( NOTE: Not 100% sure on this )
SPR_TYPE_ROTATE_XY,		 // Sprite rotates to face the player on both the X and Y axis
SPR_TYPE_ONE_WAY2,		 // Odd, same as SPR_FACE_ONE_WAY except in a different direction
SPR_TYPE_ROTATE_XY2		 // Hmm, this seemingly does the same thing as SPR_FACE_ROTATE_XY
};

// Half-life sprite header.
// Still under research.
#pragma pack( 2 )
#pragma pack( show )
typedef struct hl_sprheader_s {
   char sprIdentify[ 4 ];  // 4 Character non null terminated file id. Should contain "IDSP"
   int iVersion;		   // Sprite version number. Should be 2.
   int iSpritetype;		// Type of sprite
   int iRendermode;		// Sprite render mode. See hl_sprite_rendermodes_e.
   int iUnknown4;		  // Offset? Actually no, it's something else...
   unsigned int iWidth;	// Width of sprite
   unsigned int iHeight;   // Height of sprite
   int iFramecount;		// Number of frames in sprite
   int iUnknown5;
   int iUnknown6;
   unsigned short iUnknown7;
} hl_sprheader_t;

// This structure seems to appear at the start of a new frame within the sprite.
// NOTES:
// This is a complete structure!
// Only alter when new type/use information is found.
typedef struct hl_sprframe_s {
   int iUnknown1;		  // Always seems to be 0
   int iUnknown2;		  // Always seems to be C0 FF FF FF
   int iUnknown3;		  // Always seems to be 1
   unsigned int iWidth;	// Width of frame
   unsigned int iHeight;   // Height of frame
} hl_sprframe_t;
There are quite a few unknowns but it doesn't look like they're needed to display the sprite.
But the problem I had was with the main sprite header ( hl_sprheader_t ).
What would happen is I added an unsigned short to the end of it because there are 2 still unknown bytes before the palette.
However, MSVC decided that it would make the short into 4 bytes.
That really threw everything off since the first 2 bytes of the palette were getting read into the header.

I guessed and found a solution with #pragma pack but it still doesn't feel right, can someone explain what is going on and if it will happen on a different compiler aswell?
  
Reply With Quote