Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using color palettes with SDL

Tags:

c

sdl

I'm creating a PC port of a Gameboy Color game from scratch using SDL and C as a personal project and learning experience. The game uses palette swaps to create effects, and I'd like to be able to do the same. I've read that there are palette functions for SDL, but that they're depreciated and barely functional.

Since I can't use those, what would be the best way to emulate a palette swap in my case?

like image 568
Velovix Avatar asked Feb 05 '26 21:02

Velovix


1 Answers

Deprecated? Can you give a link to the source?

Maybe (untested) you can't use it directly as the output surface because of your desktop configuration but AFAIK 8-bit indexed color palette surfaces are supported by SDL, you can create one indexed offscreen surface, adjust the palette, and then blit it to the output surface.

edit

That's an SDL1.2 working example, sadly the gif used here doesn't have the palette converted correctly so the cycle just appear as some flash, I didn't look for any better.

Note that you can't poke directly into the surface palette, need to use SDL_SetColors()

The SDL2.0 add some function to handle the palette but I expect it to work (untested).

test.c:

#include "SDL.h"
#include "SDL_image.h"

void cycle(SDL_Color *colors, int first, int ncolors) {
    int i;
    SDL_Color tmp;
    tmp = colors[first];
    for (i=first+1; i < first+ncolors; i++)
        colors[i-1] = colors[i];
    colors[i-1] = tmp;
}

int main (int argc, char *argv[]) {
    SDL_Surface *out, *gif;
    SDL_Event event;
    int gameover = 0, i;
    int ncolors;
    SDL_Color *palette;

    SDL_Init(SDL_INIT_VIDEO);
    out = SDL_SetVideoMode(640, 480, 0, 0);
    gif = IMG_Load("Grafx2.gif");
    if (gif == NULL) {
        fprintf(stderr,"IMG_Load(): %s\n",IMG_GetError());
        goto err; /* <- evil */
    }
    printf("Bpp %d\n", gif->format->BytesPerPixel);
    printf("bpp %d\n", gif->format->BitsPerPixel);
    ncolors = gif->format->palette->ncolors;
    printf("ncolors %d\n", ncolors);
    palette = malloc(sizeof(SDL_Color)*ncolors); /* error check */
    for (i=0; i < ncolors; i++) {
        palette[i] = gif->format->palette->colors[i];
        printf("[%d] r=%d, g=%d, b=%d\n", i, palette[i].r, palette[i].g,
               palette[i].b);
    }
    while (!gameover) {
        if (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT)
                gameover = 1;
        }
        cycle(palette, 192, 64);
        SDL_SetColors(gif, palette, 0, ncolors);
        SDL_BlitSurface(gif, NULL, out, NULL);
        SDL_UpdateRect(out, 0, 0, 0, 0);
    }
    free(palette);
    SDL_FreeSurface(gif);
 err:
    SDL_Quit();
    return 0;
}

Makefile:

CC = gcc

# CFLAGS += $(shell sdl-config --cflags)
# LIBS += $(shell sdl-config --libs)

CFLAGS += $(shell pkg-config SDL_image --cflags)
LIBS += $(shell pkg-config SDL_image --libs)

# CFLAGS += -Wno-switch

all: Grafx2.gif test

test.o: test.c
    $(CC) -Wall -O2 $(CFLAGS) -c -o $@ $<

test: test.o
    $(CC) -o $@ $< $(LIBS)

Grafx2.gif:
    wget http://upload.wikimedia.org/wikipedia/commons/7/77/Grafx2.gif

.PHONY: clean
clean:
    -rm -f test *.o
like image 126
Alex Avatar answered Feb 08 '26 13:02

Alex



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!