SDL_UpdateRect without request

I have a scenario where I can blit an entire image to the screen, but
then update only certain rectangles in a time sequence to create an
animation. If I do this in a loop, it works fine. However, if I try
to do it using the SDL event mechanism or with SDL timers, the entire
screen gets updated. (The screen gets updated when video->pumpEvent()
is called by the event or timer subsystem.)

Is there some reason that updates happen automatically? Is there a
way to disable that, or is it a “feature” rather than a “bug”?

Thanks,

Derrell

I have a scenario where I can blit an entire image to the screen, but
then update only certain rectangles in a time sequence to create an
animation. If I do this in a loop, it works fine. However, if I try
to do it using the SDL event mechanism or with SDL timers, the entire
screen gets updated. (The screen gets updated when video->pumpEvent()
is called by the event or timer subsystem.)

Is there some reason that updates happen automatically? Is there a
way to disable that, or is it a “feature” rather than a “bug”?

Can you post a minimal complete example to show what you mean?
Also include your platform information.

-Sam Lantinga, Software Engineer, Blizzard Entertainment

Previously, I wrote:

I have a scenario where I can blit an entire image to the screen, but
then update only certain rectangles in a time sequence to create an
animation. If I do this in a loop, it works fine. However, if I try
to do it using the SDL event mechanism or with SDL timers, the entire
screen gets updated. (The screen gets updated when video->pumpEvent()
is called by the event or timer subsystem.)

Is there some reason that updates happen automatically? Is there a
way to disable that, or is it a “feature” rather than a “bug”?

To which Sam Lantinga replied:

Can you post a minimal complete example to show what you mean?
Also include your platform information.

Sure. You’ll notice in this program that the whole screen is painted
black (and updated). Then half of the screen is filled with blue, but
NOT updated. However, when SDL_PollEvents() is called the blue
half-screen gets painted to the screen even though I never did an
SDL_UpdateRects() telling it to. (I want to be able to update
portions of the screen based on received events; I don’t want the
screen to get updated without me explicitely telling it to – even
though I’ve blitted more then I’m updating.)

Environment is Linux, SDL-1.2.0, X Windows.----------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <SDL.h>

#ifndef FALSE

define FALSE (0)

define TRUE (! FALSE)

#endif

/*

  • SDL interprets each pixel as a 32-bit number, so our masks must depend
  • on the endianness (byte order) of the machine
    */
    #if SDL_BYTEORDER == SDL_BIG_ENDIAN
    static const Uint32 rmask = 0xff000000;
    static const Uint32 gmask = 0x00ff0000;
    static const Uint32 bmask = 0x0000ff00;
    static const Uint32 amask = 0x000000ff;
    #else
    static const Uint32 rmask = 0x000000ff;
    static const Uint32 gmask = 0x0000ff00;
    static const Uint32 bmask = 0x00ff0000;
    static const Uint32 amask = 0xff000000;
    #endif

int
main(int argc, char * argv[])
{
int bDone = FALSE;
Uint32 stoptime;
Uint32 currenttime;
const Sint32 width = 640;
const Sint32 height = 480;
const Sint32 depth = 32;
SDL_Event event;
SDL_Surface * pScreen;
SDL_Rect rect;

/* Initialize SDL */
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) != 0)
{
    fprintf(stderr, "Could not initialize SDL\n");
    return 1;
}

/* Ensure that we properly shut down SDL on exit */
atexit(SDL_Quit);

/* Initialize the display */
if ((pScreen =
     SDL_SetVideoMode(width, height, depth,
                      (SDL_SWSURFACE

#if 0
| SDL_DOUBLEBUF
| SDL_FULLSCREEN
#endif
))) == NULL)
{
fprintf(stderr,
“Could not set %dx%dx%d video mode: %s\n”,
width, height, depth, SDL_GetError());
return 1;
}

/* Disable the cursor */
(void) SDL_ShowCursor(SDL_DISABLE);

/* First, fill the screen with black */
SDL_FillRect(pScreen, NULL, 0);

/* Display it now! */
SDL_UpdateRect(pScreen, 0, 0, width, height);

/* Fill half the screen with blue, but don't update yet */
rect.x = 0;;
rect.y = 0;
rect.w = width / 2;
rect.h = height;

/* Blit it but no update yet */
SDL_FillRect(pScreen, &rect, 0xff);

/* Sleep for two seconds, showing only the black screen */
sleep(2);

/* Loop for up to 10 seconds, awaiting a keypress */
for (currenttime = SDL_GetTicks(),
         stoptime = currenttime + 10000;
     ! bDone && currenttime < stoptime;
     currenttime = SDL_GetTicks())
{
    /* This call will display the blue half screen, but shouldn't */
    if (SDL_PollEvent(&event))
    {
        switch (event.type)
        {
        case SDL_KEYDOWN:
        case SDL_QUIT:
            bDone = TRUE;
            break;

        default:
            printf("Got event %d\n", event.type);
            break;
        }
    }
}

return 0;

}