Just a small update on the matter.
With the help of an SDL contributor (@Guldoman), I updated the code with some minor changes:
//gcc palette.c -o palette -lSDL
#include <SDL/SDL.h>
#define WIDTH 320
#define HEIGHT 200
#define PALETTE_SIZE 64
#define COLOR_ROWS 16
//Default palette
static SDL_Color nes_palette[PALETTE_SIZE] = {
//3
{124,124,124}, {0,0,252}, {0,0,188}, {68,40,188}, {148,0,132}, {168,0,32}, {168,16,0}, {136,20,0},
{80,48,0}, {0,120,0}, {0,104,0}, {0,88,0}, {0,64,88}, {0,0,0}, {0,0,0}, {0,0,0},
//2
{188,188,188}, {0,120,248}, {0,88,248}, {104,68,252}, {216,0,204}, {228,0,88}, {248,56,0}, {228,92,16},
{172,124,0}, {0,184,0}, {0,168,0}, {0,168,68}, {0,136,136}, {0,0,0}, {0,0,0}, {0,0,0},
//1
{248,248,248}, {60,188,252}, {104,136,252}, {152,120,248}, {248,120,248}, {248,88,152}, {248,120,88}, {252,160,68},
{248,184,0}, {184,248,24}, {88,216,84}, {88,248,152}, {0,232,216}, {120,120,120}, {0,0,0}, {0,0,0},
//0
{252,252,252}, {164,228,252}, {184,184,248}, {216,184,248}, {248,184,248}, {248,164,192}, {240,208,176}, {252,224,168},
{248,216,120}, {216,248,120}, {184,248,184}, {184,248,216}, {0,252,252}, {248,216,248}, {0,0,0}, {0,0,0}
};
// Smile pixel representation
int smile[16][16] = {
{0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0},
{0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1},
{1,1,0,1,1,1,0,0,0,0,1,1,0,0,1,1},
{1,1,0,0,1,1,0,0,0,0,1,1,0,0,1,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1},
{1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1},
{1,1,0,0,0,1,1,1,1,1,1,0,0,1,1,0},
{0,1,1,0,0,0,0,0,0,0,0,0,1,1,1,0},
{0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0},
{0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0},
{0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0},
};
void fade(SDL_Surface *surface)
{
int row = 0;
for (int i = PALETTE_SIZE - COLOR_ROWS; i >= 0; i -= COLOR_ROWS)
{
// Ensure we are only setting up to 16 colors at a time
SDL_SetPalette(surface, SDL_LOGPAL, &nes_palette[i], 0, COLOR_ROWS);
for(int k=0; k<COLOR_ROWS; k++)
{
printf("%d %d %d\n", surface->format->palette->colors[i+k].r, surface->format->palette->colors[i+k].g, surface->format->palette->colors[i+k].b);
}
SDL_Flip(surface); // Update the screen
SDL_Delay(1000); // Delay to control the speed of the shade effect
}
// Finally, set to all black
SDL_Color black_palette[COLOR_ROWS];
memset(black_palette, 0, sizeof(SDL_Color) * COLOR_ROWS);
SDL_SetPalette(surface, SDL_LOGPAL, black_palette, 0, COLOR_ROWS);
SDL_Flip(surface);
SDL_Delay(200); // Final delay before exiting
}
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO);
SDL_Surface *screen = SDL_SetVideoMode(WIDTH, HEIGHT, 8, SDL_SWSURFACE);
// Set initial palette to palette 3
SDL_SetPalette(screen, SDL_LOGPAL, &nes_palette[PALETTE_SIZE-COLOR_ROWS], 0, COLOR_ROWS);
// Draw the background
//~ SDL_FillRect(screen, NULL, 4); // Index 4 is our "background" in *each* palette
SDL_FillRect(screen, NULL, (int)SDL_MapRGB(screen->format, 248,184,248));
Uint8 *pixels = (Uint8 *) screen->pixels;
int smile_x = (WIDTH - 16) / 2;
int smile_y = (HEIGHT - 16) / 2;
//~ SDL_Surface *image = SDL_LoadBMP("ninja-gaiden.bmp");
//~ SDL_BlitSurface(image, NULL, screen, NULL);
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
if (smile[y][x] == 1) {
// Set smile pixel color to yellow
pixels[(smile_y + y) * WIDTH + (smile_x + x)] = 9; // Index 9 is our "foreground" color in each palette
}
}
}
SDL_Flip(screen);
SDL_Delay(1000);
fade(screen);
SDL_Delay(2000); // Wait before quitting
SDL_Quit();
return 0;
}
Essentially, the main changes is in the use of SDL_SetPalette.
According to the documentation, the third parameter expects a pointer to a color list, followed by the fist color index and the number of colors to follow.
I intended the "firstcolor" argument as the color position index inside the colors list (nes_palette), but seems more to be a further color indexing procedure.
So, switching the arguments as follow, has do the trick:
SDL_SetPalette(screen, SDL_LOGPAL, &nes_palette[PALETTE_SIZE-COLOR_ROWS], 0, COLOR_ROWS);
And updated the fade cycle as well
for (int i = PALETTE_SIZE - COLOR_ROWS; i >= 0; i -= COLOR_ROWS)
{
// Ensure we are only setting up to 16 colors at a time
SDL_SetPalette(surface, SDL_LOGPAL, &nes_palette[i], 0, COLOR_ROWS);
for(int k=0; k<COLOR_ROWS; k++)
{
printf("%d %d %d\n", surface->format->palette->colors[i+k].r, surface->format->palette->colors[i+k].g, surface->format->palette->colors[i+k].b);
}
SDL_Flip(surface); // Update the screen
SDL_Delay(1000); // Delay to control the speed of the shade effect
}
Pointing to the first color we want to use from the array, and sets the firstcolor parameter to 0, along with the number of colors available after, seems to works right.

I also found this interesting project, with a set of cool palette effects, that seems to use a similar approach to mine
amroibrahim/PaletteCycling