C 将调色板与SDL一起使用

C 将调色板与SDL一起使用,c,sdl,C,Sdl,我正在用SDL和C作为个人项目和学习体验,从头开始创建Gameboy彩色游戏的PC端口。这个游戏使用调色板交换来创建效果,我也希望能够做到这一点。我读过SDL有一些调色板函数,但它们被贬低了,几乎没有功能 既然我不能使用这些,那么在我的例子中,模拟调色板交换的最佳方法是什么?不推荐使用?你能给我一个到来源的链接吗 可能(未测试)由于您的桌面配置,您不能直接将其用作输出表面,但SDL支持AIK 8位索引调色板表面,您可以创建一个索引屏幕外表面,调整调色板,然后将其blit到输出表面 编辑 这是一个

我正在用SDL和C作为个人项目和学习体验,从头开始创建Gameboy彩色游戏的PC端口。这个游戏使用调色板交换来创建效果,我也希望能够做到这一点。我读过SDL有一些调色板函数,但它们被贬低了,几乎没有功能


既然我不能使用这些,那么在我的例子中,模拟调色板交换的最佳方法是什么?

不推荐使用?你能给我一个到来源的链接吗

可能(未测试)由于您的桌面配置,您不能直接将其用作输出表面,但SDL支持AIK 8位索引调色板表面,您可以创建一个索引屏幕外表面,调整调色板,然后将其blit到输出表面

编辑

这是一个SDL1.2的工作示例,遗憾的是,这里使用的gif没有正确转换调色板,因此循环显示为一些闪光,我没有寻找更好的

请注意,您不能直接插入曲面调色板,需要使用
SDL\u SetColors()

SDL2.0添加了一些函数来处理调色板,但我希望它能工作(未经测试)

测试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;
}
#包括“SDL.h”
#包括“SDL_image.h”
无效循环(SDL_颜色*颜色,int优先,int n颜色){
int i;
SDL_彩色tmp;
tmp=颜色[第一];
对于(i=first+1;i字节/像素);
printf(“bpp%d\n”,gif->format->BitsPerPixel);
ncolors=gif->格式->调色板->ncolors;
printf(“n颜色%d\n”,n颜色);
调色板=malloc(sizeof(SDL_颜色)*n颜色);/*错误检查*/
对于(i=0;i格式->调色板->颜色[i];
printf(“[%d]r=%d,g=%d,b=%d\n”,i,调色板[i].r,调色板[i].g,
[i].b);
}
而(!gameover){
if(SDL_事件和事件)){
if(event.type==SDL\u QUIT)
gameover=1;
}
循环(调色板,192,64);
SDL_设置颜色(gif、调色板、0、ncolors);
SDL_BlitSurface(gif、NULL、out、NULL);
SDL_(out,0,0,0,0);
}
免费(调色板);
SDL_自由曲面(gif);
错误:
SDL_退出();
返回0;
}
生成文件:

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
CC=gcc
#CFLAGS+=$(shell sdl配置--CFLAGS)
#LIBS+=$(shell sdl配置--LIBS)
CFLAGS+=$(外壳程序包配置SDL_映像--CFLAGS)
LIBS+=$(外壳程序包配置SDL_映像--LIBS)
#CFLAGS+=-Wno开关
全部:Grafx2.gif测试
测试o:测试c
$(CC)-墙壁-氧气$(CFLAGS)-c-o$@$<
测试:test.o
$(CC)-o$@$<$(LIBS)
Grafx2.gif:
wgethttp://upload.wikimedia.org/wikipedia/commons/7/77/Grafx2.gif
.假冒:干净
清洁:
-rm-f测试*.o
  • 仅使用256色
  • 屏幕=SDL_设置视频模式(640、480、8、SDL_调色板); SDL_设置调色板(屏幕,SDL_LOGPAL | SDL_PHYSPAL,颜色,0,256); 第条邮政—

  • 如果所有选项板的组合超过256色,则必须使用像素着色器
  • 屏幕=SDL_设置视频模式(640480 32,SDL_OPENGL | SDL_全屏); 使用像素着色器。
    文章帖子-

    我知道OP不再寻找答案,但这可能会帮助其他人

    SDL_曲面
    有一个
    SDL_像素格式
    ,它有一个
    SDL_调色板
    ,您可以在其中设置颜色。然后只需显示曲面即可

    进一步阅读:


    好的,再看一眼,它们看起来并没有被弃用,但我确实读到很多人对它们有问题。我会试试你的建议。谢谢!如果我没有明确提及,问题作者会收到答案编辑通知吗?@VelovixThank you!这是在深夜在3DS上写的XD没有问题,现在已修复。谢谢或者答案!我已经离开这个项目很久了(毕竟,这个问题已经有四年了:)。我希望你的答案能帮助其他人。