I am working on a custom data structure and I am currently in the beta testing process: The data will be stored within an array and this array can be represented as a 4D, 2D
For example, like this:
for (int i = 0; i < 256; ++i) {
int cube = i / 64;
int slice = (i % 64) / 16;
int row = (i % 16) / 4;
int col = i % 4;
m_cr[i].A = cube / 2 * 8 + slice / 2 * 4 + row;
m_cr[i].B = cube % 2 * 8 + slice % 2 * 4 + col;
}
Having stared at the lookup table, for a few minutes (and only at the raw data in the lookup table, I couldn't follow the graphics), I believe that the following example will generate your lookup table.
As I told you in your first question, most of the question is irrelevant. If you got rid of the first 3/4th of your question, someone would've probably came up with an answer soon. Sometimes it does help to know a little bit of what the data means, but here it seems to be more of a distraction, than anything else.
Anyway, the first thing to do is to get rid of the enum
. It doesn't add any value, and just gets in the way. Just use natural hexadecimal numbers, that's all. Having said that, it should be trivial for you to adapt this with your own code:
#include <iostream>
int main()
{
for (int n=0; n<256; ++n)
{
int a = ((((n >> 5) & 1) << 2) | (n & 0x80) >> 4) | ((n >> 2) & 3);
int b = (n & 3) | (((n >> 4) & 1) << 2) |
(((n >> 6) & 1) << 3);
std::cout << n << ": a=" << a << " b=" << b << std::endl;
}
}
I have a nagging feeling that this can be simplified a little bit even more, perhaps someone else can contribute an improvement, but, in any case, the output from this seems to match the raw hexadecimal values, for both A
and B
, in your lookup table.
Start by changing HEX_ to an array. Then, look at individual blocks and turn them into loops. Since your .A
and .B
are mutually exclusive, we may handle them separately.
Here's a "function" you may use to help initialize A:
void InitializeA(CrossReference arr[])
{
InitializeABlock(arr, 0x00, 0x00);
InitializeABlock(arr, 0x10, 0x00);
InitializeABlock(arr, 0x20, 0x04);
InitializeABlock(arr, 0x30, 0x04);
InitializeABlock(arr, 0x40, 0x00);
InitializeABlock(arr, 0x50, 0x00);
InitializeABlock(arr, 0x60, 0x04);
InitializeABlock(arr, 0x70, 0x04);
InitializeABlock(arr, 0x80, 0x08);
InitializeABlock(arr, 0x90, 0x08);
InitializeABlock(arr, 0xA0, 0x10);
InitializeABlock(arr, 0xB0, 0x10);
InitializeABlock(arr, 0xC0, 0x08);
InitializeABlock(arr, 0xD0, 0x08);
InitializeABlock(arr, 0xE0, 0x10);
InitializeABlock(arr, 0xF0, 0x10);
}
void InitializeABlock(CrossReference arr[], int idxStart, int hexStart)
{
for(int j = hexStart; j < hexStart + 4; j++)
{
int baseIdx = idxStart + 4 * (j - hexStart);
for(int i = 0; i < 4; i++)
{
arr[baseIdx + i].A = j;
}
}
}
The implementation for B is very similar:
void InitializeB(CrossReference arr[])
{
InitializeBBlock(arr, 0x00, 0x00);
InitializeBBlock(arr, 0x10, 0x00);
InitializeBBlock(arr, 0x20, 0x04);
InitializeBBlock(arr, 0x30, 0x04);
InitializeBBlock(arr, 0x40, 0x00);
InitializeBBlock(arr, 0x50, 0x00);
InitializeBBlock(arr, 0x60, 0x04);
InitializeBBlock(arr, 0x70, 0x04);
InitializeBBlock(arr, 0x80, 0x08);
InitializeBBlock(arr, 0x90, 0x08);
InitializeBBlock(arr, 0xA0, 0x10);
InitializeBBlock(arr, 0xB0, 0x10);
InitializeBBlock(arr, 0xC0, 0x08);
InitializeBBlock(arr, 0xD0, 0x08);
InitializeBBlock(arr, 0xE0, 0x10);
InitializeBBlock(arr, 0xF0, 0x10);
}
void InitializeBBlock(CrossReference arr[], int idxStart, int hexStart)
{
for(int j = idxStart; j < idxStart + 4; j++)
{
int baseIdx = idxStart + 4 * (j - idxStart);
for(int i = 0; i < 4; i++)
{
arr[baseIdx + i].A = i + hexStart;
}
}
}
You may, of course, compress this further. ;)