Kosmo零
Kosmo零

Reputation: 4151

How to compose uint value from single bit (representing value1) and 23 bits (representing value2)?

Some game that I currently reverse engineer store two values in 3 bytes. first value size is 1 bit and second value size is 23 bits.

[0][000 0001 0001 0111 1001 0000] 0 stone, 71568 att

[1][000 0000 0010 1001 0000 0111] 1 stone, 10511 att

I found a way to read them like this:

    public byte AddedStonesCount
    {
        get
        {
            byte[] att_plus_stones_count_as_bytes = new byte[4];
            Buffer.BlockCopy(this.Data, 21, att_plus_stones_count_as_bytes, 0, 3);
            uint att_plus_stones_count = BitConverter.ToUInt32(att_plus_stones_count_as_bytes, 0);

            return (byte)(att_plus_stones_count >> 23);
        }
        set
        {
        
        }
    }
    public uint Attack
    {
        get
        {
            byte[] att_plus_stones_count_as_bytes = new byte[4];
            Buffer.BlockCopy(this.Data, 21, att_plus_stones_count_as_bytes, 0, 3);
            uint att_plus_stones_count = BitConverter.ToUInt32(att_plus_stones_count_as_bytes, 0);

            return att_plus_stones_count << 9 >> 9;
        }
        set
        {
        
        }
    }

But I also need a way to change them. That's where something always goes wrong for me. I tried doing att & 0x800000 to get 1 0000 0000 0000 0000 0000 added with attack, but strangely it give me 0 instead of the value I expect.

I doing some tests here:

        uint test = 0x80290F; //8399119 - here we store 1 stone added and 10511 attack power
        uint test_composition = 10511 & (0x800000); //this does not give me 8399119 :/

        BitArray ba = new BitArray(BitConverter.GetBytes(test));

        string test_original = string.Empty;
        for (int i = 0; i < ba.Length; i++)
            test_original += ba.Get(i) ? 1 : 0;

        uint att = test << 9 >> 9;

        BitArray ba_att = new BitArray(BitConverter.GetBytes(att));
        string test_att = string.Empty;
        for (int i = 0; i < ba_att.Length; i++)
            test_att += ba_att.Get(i) ? 1 : 0;

        uint stones = test >> 23;

Help...

For example, when pet has attack = 10511 and amount of stones added = 1, then end value should be 8399119.

Upvotes: 0

Views: 57

Answers (1)

Klaus G&#252;tter
Klaus G&#252;tter

Reputation: 11997

To set bit#23 according to stones (0 or 1) and the bits#0...22 according to attack, use the bitwise OR operator:

(stones << 23) | attack

Upvotes: 2

Related Questions