SDL_MapRGB returns same value for different arguments with 8 bits-per-pixel surface

I’m using SDL 1.2. Windows 7. Code::Blocks. I’m calling this function, SDL_MapRGB:

https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlmaprgb.html

The response from these functions is not what I expect. Can anyone help me understand the relation between my input and the output? Here’s my code, and output is below that:

#include <stdlib.h>
#include <SDL/SDL.h>

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_VIDEO);

    // Make printf show
    freopen ("CON", "w", stdout);
    freopen ("CON", "r", stdin);
    freopen ("CON", "w", stderr);

    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE | SDL_DOUBLEBUF);

    Uint32 x = 0;

    bool done = false;

    while(!done) {
        SDL_Event event;

        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                done = true;
                break;
            }
        }

        for(int i = 0; i < 64; i += 8) {
            x = SDL_MapRGB(screen->format, i, 0, 0);
            printf("i = %i, x = %u\n", i, x);
        }

        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
        SDL_Flip(screen);
    }

    SDL_FreeSurface(screen);
    SDL_Quit();

    return 0;
}

And here is some output:

i = 0, x = 0
i = 8, x = 0
i = 16, x = 0
i = 24, x = 32
i = 32, x = 32
i = 40, x = 32
i = 48, x = 32
i = 56, x = 64

Thoughts?

Mmm. Okay. I get results more like what I expect if I change:

SDL_SetVideoMode(640, 480, 8, ...)

To:

SDL_SetVideoMode(640, 480, 32, ...)

I can now successfully round-trip this data, which is what I was trying to do originally:

#include <stdlib.h>
#include <SDL/SDL.h>

int main(int argc, char** argv) {
    SDL_Init(SDL_INIT_VIDEO);

    // Make printf show
    freopen ("CON", "w", stdout);
    freopen ("CON", "r", stdin);
    freopen ("CON", "w", stderr);

    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE | SDL_DOUBLEBUF);

    Uint32 x = 0;

    Uint8 r;
    Uint8 g;
    Uint8 b;

    bool done = false;

    while(!done) {
        SDL_Event event;

        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                done = true;
                break;
            }
        }

        for(int i = 0; i < 64; i += 8) {
            x = SDL_MapRGB(screen->format, i, 0, 0);
            printf("i = %i, x = %u\n", i, x);
            SDL_GetRGB(x, screen->format, &r, &g, &g);
            printf("r = %i\ng = %i\n%b = %i\n", r, g, b);
        }

        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
        SDL_Flip(screen);
    }

    SDL_FreeSurface(screen);
    SDL_Quit();

    return 0;
}

Output:

i = 0, x = 0
r = 0
g = 0
b = 0
i = 8, x = 524288
r = 8
g = 0
b = 0
i = 16, x = 1048576
r = 16
g = 0
b = 0
i = 24, x = 1572864
r = 24
g = 0
b = 0

New question: why? Isn’t that what surface->format is supposed to help with? Obviously I’m missing something.