我使用GDB,发现SDL_Init和SDL_CreateWindow可以工作,但是当代码到达SDL_CreateRenderer时,它调用它并挂起,它永远不会返回,GDB只是等待。另外,该程序的 CPU 使用率从标准的 0.something 到 4%(我可以听到 CPU 风扇加速,所以它可能类似于无限循环?),当我输入“exit”时,它会尝试退出(通过
exit(0);
)但无济于事。 (我有另一个线程接受 std 输入并处理它。)
SDL初始化部分如下所示:
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Could not initiate the window for VGA module! SDL Error: %s\n", SDL_GetError());
return;
}
window = SDL_CreateWindow("PT16B00 CPU - Emulator - VGA Module",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT, 0);
if (window == NULL) {
printf("VGA module: Window could not be created! SDL Error: %s\n", SDL_GetError());
return;
}
renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL) {
printf("VGA module: Renderer could not be created! SDL Error: %s\n", SDL_GetError());
return;
}
screen_texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING,
SCREEN_WIDTH, SCREEN_HEIGHT);
if (screen_texture == NULL) {
printf("VGA module: Texture could not be created! SDL Error: %s\n", SDL_GetError());
return;
}
我也尝试过使用
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
和
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);
但没有任何效果。
我有事件轮询循环; SDL_GetNumRendererDrivers() 返回 3; SDL_CreateWindow() 打开一个窗口,SDL_CreateRenderer() 在进入“无限循环”之前关闭它(如果是这种情况)。
我发现一些不相关的代码中的以下行使 SDL_CreateRenderer() 冻结。
return (uint16_t) ( ((uint16_t)(dev_name[0]) << 8) + (uint16_t)(dev_name[0+1]) );
上面代码中的0
是实际变量的占位符,但它仍然会产生问题。 dev_name
声明为:
const unsigned char dev_name[] = "FB_OUT_DEV";
还有,刚回来
return (uint16_t)(dev_name[0]);
或
return 70;
仍然破坏了SDL_CreateRenderer()。 (70 表示 ASCII 'F')
即使使用
-Wall
标志,编译器也不会产生错误/警告...
删除该行后(或使用 return 0;
,SDL_CreateRenderer() 可以工作)。
不相关的函数怎么会导致库函数无法工作呢?在 SDL_CreateRenderer() 之前或之后都不会调用包含此 return 语句的函数。当主代码的状态机收到调用它的指令时,它才会被调用仅(这实际上可能永远不会发生......)。
该函数也不为空,还有其他返回语句,它们没有问题,只有这个。我无法提供最小的可重现示例,因为我自己不知道如何从头开始重现它。最小的 SDL 示例使用与我在该项目中使用的代码相同的代码(即使我使用两个线程)也能完美运行。
uint16_t read(uint32_t address) {
// return the length of the device name/id
if (address == vga_module->address) {
return sizeof(dev_name)-1;
}
// return the device name/id
if (address < vga_module->address + sizeof(dev_name)) {
uint8_t index = (address - vga_module->address - 1) * 2;
return ((uint16_t)(dev_name[index]) << 8) + (uint16_t)(dev_name[index+1]);
}
// return the mode of the VGA device
if (address < vga_module->address + sizeof(dev_name) + 1) {
return mode;
}
// return the FB address
if (address < vga_module->address + sizeof(dev_name) + 1 + 2) {
if (!(address - vga_module->address - sizeof(dev_name) - 1)) {
return fb_address & 0xFFFF;
}
return fb_address & 0xFFFF0000;
}
return 0;
}
使SDL_CreateRenderer()
不冻结的唯一方法是更改线路
return ((uint16_t)(dev_name[index]) << 8) + (uint16_t)(dev_name[index+1]);
通过将函数名称更改为
return 0;
,将
更改为
vga_read
OR。我的猜测是,CreateRenderer 函数使用了一些
read()
方法,我不小心覆盖/造成了命名冲突。注意如何命名变量和函数! :D