-3

Background: I have a buggy program that decompiles a specific set of files. The bugs are NOT related to the records it is decompiling, just some ancillary things. I am porting the program to AHK to clean up the bugs and add some features.

Issue: Each specific file that it decompiles refers to a mapping structure for each record within that file. Most of these are easy to determine. I've encountered a bitfield expression in one of them and I'm a little confused on how to read it:

#if 1
    unsigned char vCombinedBits1;
    unsigned char vCombinedBits2;
#else
    unsigned char iPadding1_1 : 3;
    unsigned char vdirect : 1;

    unsigned char vitemspecific : 1;
    unsigned char vdamagerelated : 1;
    unsigned char vSigned : 1;
    unsigned char vSendmyspOther : 1;

    unsigned char iPading1 : 1;
    unsigned char iPading1_1 : 1;
    unsigned char vCSvSigned : 1;
    unsigned char vSaved : 1;

    unsigned char vfCallback : 1;
    unsigned char vfMin : 1;
    unsigned char vUpdateAnimRate : 1;
    unsigned char iPadding1_2 : 1;
#endif

I'm not a stranger to If/Else logic but I am a stranger to Visual C++.

My assumed end result of this, based on this and that: Essentially, I'll just read both bytes without regard to the vCombinedBits1 value and map each bit to the variable I need.

Am I correct in assuming that a sample of 0x01 0x14 (0000 0001 0001 0100) will map like this: iPadding1_1 = 0 iPadding1_1 = 0 iPadding1_1 = 0 vdirect = 0

vitemspecific = 0 vdamagerelated =0 vSigned =0 vSendmyspOther = 1

iPading1 = 0 iPading1_1 = 0 vCSvSigned = 0 vSaved = 1

vfCallback = 0 vfMin = 1 vUpdateAnimRate =0 iPadding1_2 =0 ?

Entire structure found here, #if starts at line 649

Qriist
  • 11

2 Answers2

0

The #if 1 means "include everything that follows, up to the #else"; the two lines that follow it are part of the code. Since the #if condition is true, the #else means "ignore everything that follows, up to the #end; the remaining lines are not part of the code. It's as if that code had been written

unsigned char vCombinedBits1;
unsigned char vCombinedBits2;
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
  • So no matter what, I will read both bytes and map accordingly? Is my sample map correct? – Qriist Sep 09 '18 at 21:20
  • The names used in your sample map don’t exist. There are only two names defined by that code: `vCombinedBits1` and `vCombinedBits2`. – Pete Becker Sep 09 '18 at 21:45
0

Essentially, I'll just read both bytes without regard to the vCombinedBits1 value and map each bit to the variable I need.

OK.

Am I correct in assuming that a sample of 0x01 0x14 (0000 0001 0001 0100) will map like this: ...

Not quite. Ordering of bits in bit fields depends on specific compiler (TL;DR) and you assume big-endian order. But in case of VC++ compiler, it is little-endian. To tell whether your assumtion is correct we need to see a sample of actual data with decoding to bits. If you want this code portable to any (unknown) compiler and architecture, do not use bit fields for decoding external data.

Amen!

ddbug
  • 1,392
  • 1
  • 11
  • 25
  • These are binary files that are created by a third party program (for use in that program) from tab-delimited text files. It always compiles in the same manner for any given values for any given field. The VC++ prog that I am porting reads these bins and recreates the source text files. Based on this, I believe that the ordering of the variables above directly corresponds to the bits encountered, as they are encountered. – Qriist Sep 09 '18 at 21:31
  • So if you know that the 3rd party program outputs big endian bit order, and have a sample of source and output, you can test your decoding. Either it matches, or not. 50-50%. – ddbug Sep 09 '18 at 21:38
  • Yep, got it figured out. Thanks for the insight! – Qriist Sep 09 '18 at 21:39