Я работаю над эмулятором Space Invaders и для вывода на дисплей использую SDL2.
Проблема в том, что в окне вывода я вижу все кадры, так как эмуляция начинается!
В основном, важная часть кода такова:
Intel8080 mainObject; // My Intel 8080 CPU emulator
mainObject.loadROM();
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//While application is running
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
}
if (mainObject.frameReady)
{
mainObject.frameReady = false;
gHelloWorld = SDL_CreateRGBSurfaceFrom(&mainObject.frameBuffer32, 256, 224, 32, 4 * 256, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
//Apply the image
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
//Update the surface
SDL_UpdateWindowSurface(gWindow);
}
mainObject.executeROM();
}
где Intel8080 — это код моего эмулятора ЦП, а mainObject.frameBuffer32 — видеопамять Space Invaders, которую я преобразовал из 1bpp в 32bpp для использования функции SDL_CreateRGBSurfaceFrom.
Эмуляция работает нормально, но я вижу все кадры, созданные с момента запуска эмулятора!
Я пытался изменить альфа-значение в 4 байтах каждого пикселя RGBA, но ничего не изменилось
Это происходит потому, что похоже, что вы рендерите игру без предварительной очистки окна. По сути, вы должны заполнить все окно цветом, а затем постоянно рендерить поверх него. Идея состоит в том, что заполнение окна определенным цветом перед его рендерингом эквивалентно стиранию предыдущего кадра (большинство современных компьютеров достаточно мощные, чтобы справиться с этим).
Вы можете прочитать о SDL SDL_FillRect функция, это позволит вам заполнить весь экран определенным цветом.
Рендеринг псевдокода:
while(someCondition)
{
[...]
// Note, I'm not sure if "gScreenSurface" is the proper variable to use here.
// I got it from reading your code.
SDL_FillRect(gScreenSurface, NULL, SDL_MapRGB(gScreenSurface->format, 0, 0, 0));
SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);
SDL_UpdateWindowSurface(gWindow);
[...]
}
Других решений пока нет …