PDA

View Full Version : Why bitshift to get to the x,y,z co-ords


moofta
04-25-2014, 10:50 AM
OK, so I have been hitting my head against the packet structs trying to update EQExtractor2 to match Live. There has been some trial and error, and also some blatant ripping off of ShowEQ (who seem to have it working ), and of course also ripping off Derisions work. PASt that, I must admit this is stretching my ability, but please be gentle :P

I can basically get enough of OP_PlayerProfile working, and OP_ZoneEntry is going OK until I get to the co-ordinates. Here's is the part of the ShowEQ spawnStruct relating to locs:-


union
{
struct
{
unsigned pitch:12;
signed deltaX:13; // change in x
unsigned padding01:7;
signed z:19; // z coord (3rd loc value)
signed deltaHeading:10; // change in heading
unsigned padding02:3;
signed x:19; // x coord (1st loc value)
signed deltaZ:13; // change in z
unsigned heading:12; // heading
signed deltaY:13; // change in y
unsigned padding03:7;
signed animation:10; // velocity
signed y:19; // y coord (2nd loc value)
unsigned padding04:3;
};
int32_t posData[5];
};


In the below code Postion1 relates to posData[0], Position2 to posData[1] and so on.



float XPos = Utils.EQ19ToFloat((Int32)(Position3) & 0x7FFFF); //Moofta-Verified
float YPos = Utils.EQ19ToFloat((Int32) (Position5 >> 10) & 0x7FFFF); //Moofta-Verified
float ZPos = Utils.EQ19ToFloat((Int32) ((Position4 >> 13) & 0x7FFFF));
//heading is definitely NOT Position3 unlike last patch that worked
float Heading = Utils.EQ19ToFloat((Int32)(Position3) & 0x3FF);


As you can see, X and Y use a bitwise AND (0x7FFFF), which is then converted using EQ19ToFloat (more on that later). That makes a kind of sense to me, since in the struct x,y,z are using the first 19 bits (at least that's how I read the 19 of "signed y:19;" ).

1. What doesn't make sense to me, is the bitshift of >> 10 or 13. Can anyone explain this to my tiny little brain? Is it because they padded out 10/13 bits then stored the number using the last 19? Presumably, therefore, the maximum shift would be 13 if we're using 19 bits?

2. I don't understand the EQ19ToFloat method really. If the 19th bit of EQ19Value is 0, it divides the value by 1<<3 (which is always 8? If so, why not use use 8 ). If it is 1, then it subtracts from EQ19Value the difference between the max value of 19 bits (0x7FFFF) +1. Why? NFC.


public static float EQ19ToFloat(Int32 EQ19Value)
{
if ((EQ19Value & 0x40000) > 0)
EQ19Value = -(0x7FFFF - EQ19Value + 1);
return (float)EQ19Value / (float)(1<<3);
}


I basically bruteforced the remaining Position* s from no bitshift up to >> 13 and no dice. I even thought f*ckit and bruted the bitwise AND all the way up to 32 bits. No dice. So I'm missing something, and I suspect it's my incomplete knowledge causing that. Any ideas/comments/welcome (other than "give up, retard" that is).

Hepl em!!1