SDL_CreateRGBSurfaceFrom / SDL_BlitSurface - I see old frames on my emulator

2

I'm working on a Space Invaders emulator and for display output I'm using SDL2.

The problem is that on the output window I see all the frames since emulation starts!

Basically the important piece of code is this:

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();
}

where Intel8080 is my CPU emulator code and mainObject.frameBuffer32 is the Space Invaders' video RAM that I converted from 1bpp to 32bpp in order to use SDL_CreateRGBSurfaceFrom function.

Emulation's working fine but I see all the frames generated since emulator starts!

I tried to change Alpha value in the 4 bytes of each RGBA pixel but nothing changes

c++
emulation
sdl-2
framebuffer
asked on Stack Overflow Dec 14, 2018 by Francesco • edited Jun 28, 2019 by Cactus

1 Answer

1

This is happening because it looks like you're rendering the game without first clearing the window. Basically, you should fill the entire window with a color and then render on top of it constantly. The idea is that filling the window with a specific color before rendering over it is the equivalent of erasing the previous frame (most modern computers are powerful enough to handle this).

You might want to read-up on SDL's SDL_FillRect function, it'll allow you to fill the entire screen with a specific color.

Rendering pseudocode:

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);

    [...]
}
answered on Stack Overflow Dec 14, 2018 by micka190

User contributions licensed under CC BY-SA 3.0