2

I have 2x structs, one for color (PixelColor) and the second for holding an array of available colors (Palette).

typedef struct{
    int r;
    int g;
    int b;
    int a;
}PixelColor;

typedef struct{
    int size;
    PixelColor *palette;
}Palette;

One game's global palette and one for objects that reference colors in the global palette.

PixelColor ShovelKnightColors[] = {
    {0, 0, 0, 255}, 
    {44, 44, 44, 255}, 
    {96, 96, 96, 255}, 
    {200, 192, 192, 255}, 
    {0, 64, 88, 255}, 
    ...
};
Palette GamePalette = {59, ShovelKnightColors};
PixelColor CharacterColors[4];
//This doesn't work
CharacterColors[0] = GamePalette.palette[0];
CharacterColors[1] = GamePalette.palette[17];
CharacterColors[2] = GamePalette.palette[24];
CharacterColors[3] = GamePalette.palette[37];

Palette CharacterPalette = {4, CharactersColors};

I'm probably missing a fundamental thing, but I tried any idea I had. As an example:

PixelColor CharacterColors[] = {
    GamePalette.palette[0], 
    GamePalette.palette[17], 
    GamePalette.palette[24],
    GamePalette.palette[37]
}

All this is outside the main function, just to learn things I don't know about initiation. Please suggest a way to get closest to the initial idea of referencing the same values, because the goal is to create an ESP32 microcontroller project.

2
  • 1
    why not: PixelColor CharacterColors[4] = {GamePalette.palette[0], GamePalette.palette[17], GamePalette.palette[24], GamePalette.palette[37]}; (notice the 4 which is missing from your example) Commented Nov 23, 2020 at 12:10
  • I already tried and I got error: initializer element is not constant. This is before main() Commented Nov 23, 2020 at 12:13

1 Answer 1

2

The problem with your code has to do with the fact that you have arrays inside your structs, and arrays need to be initialized.

My suggestion would be to create a FillPalette() function that would do the appropriate memory allocation each time:

void FillPalette(Palette *p, int size, PixelColor pixelColors[])
{
    p->size = size;
    p->palette = malloc( sizeof(PixelColor) * size );

    for(int i = 0; i < size; ++i)
    {
        p->palette[ i ].r = pixelColors[ i ].r; 
        p->palette[ i ].g = pixelColors[ i ].g;
        p->palette[ i ].b = pixelColors[ i ].b;
        p->palette[ i ].a = pixelColors[ i ].a;
    }
}

Another possibility, in order to avoid the for loop, is to use memcopy once the array has been initialized.

Anyway, remember to clear the palette when is not going to be used anymore:

void ClearPalette(Palette *p)
{
    p->size = 0;
    free( p->palette );
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! This looks like an elegant solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.