Weird drawing issue

I’ve run into quite an odd issue with it comes to drawing ovals. I had
originally a function to draw circles, but when it did, things wouldn’t
work correctly in my app after it did the drawing. Moving sprites would
stay on screen, the stars would dim and come back up, and I suspected
some really weird memory corruption at first. But I wrote a simple macro
ENSURE_ON_SCREEN(x, y) to make sure the drawing function didnt write
outside the surface … and yet the problem remains.

I guess I have two questions. First, does this sound like a good way to
do locking/unlocking? (maybe that’s my problem? i don’t know, this weird
graphics corruption occurs under x11, probably windows too, i dont
know):

if (SDL_MUSTLOCK(screen)) {
unsigned char unlocked = 1;
while (unlocked)
unlocked = SDL_LockSurface(screen);
}

… code touching surface …

if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);

and … if that checks out … is there anything wrong with the included
draw_oval function? I don’t know what’s wrong, but only calling this
function causes that weird sort of video corruption. (where “screen” is
the main video surface and ensure_blitted() is a function to keep track
of rects needing flipping)

#define ENSURE_ON_SCREEN(x, y) if (((x) >= 0) && ((y) >= 0) && ((x) <
800) && ((y) < 600))

/* bresenham’s oval algorithm, converted from a dos graphics book */
void draw_oval(int x, int y, int radius, float aspect, Uint32 color) {
int pitch_adjust;
int pixels[4][2];
int col, i, row;
float aspect_square;
long a_square, b_square, two_a_square, two_b_square, four_a_square,
four_b_square, d;

if (screen_bpp == 32)
	pitch_adjust = screen->pitch / sizeof(Uint32);
else if (screen_bpp == 16)
	pitch_adjust = screen->pitch / sizeof(Uint16);

if (SDL_MUSTLOCK(screen)) {
	unsigned char unlocked = 1;
	while (unlocked)
		unlocked = SDL_LockSurface(screen);
}

/* draw an oval */
aspect_square = aspect * aspect;
radius -= LINE_WIDTH / 2;
for (i = 1; i < LINE_WIDTH; i++) {
	b_square = radius * radius;
	a_square = b_square / aspect_square;
	row = radius;
	col = 0;
	two_a_square = a_square << 1;
	four_a_square = a_square << 2;
	four_b_square = b_square << 2;
	two_b_square = b_square << 1;
	d = two_a_square * ((row - 1) * (row)) + a_square + two_b_square * (1
  • a_square);
    while(a_square * (row) > b_square * (col)) {
    /* plot the pixels */
    pixels[0][0] = col+x;
    pixels[0][1] = row+y;
    pixels[1][0] = col+x;
    pixels[1][1] = y-row;
    pixels[2][0] = x-col;
    pixels[2][1] = row+y;
    pixels[3][0] = x-col;
    pixels[3][1] = y-row;
    if (screen_bpp == 32) {
    ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
    ((Uint32 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
    ((Uint32 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
    ((Uint32 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
    ((Uint32 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
    }
    } else if (screen_bpp == 16) {
    ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
    ((Uint16 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
    ((Uint16 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
    ((Uint16 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
    ((Uint16 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
    }
    }
    if (d >= 0) {
    row–;
    d -= four_a_square * (row);
    }
    d += two_b_square * (3 + (col << 1));
    col++;
    }
    d = two_b_square * (col + 1) * col + two_a_square * (row * (row - 2) +
    • (1 - two_a_square) * b_square;
      while((row) + 1) {
      /* plot the pixels */
      pixels[0][0] = col+x;
      pixels[0][1] = row+y;
      pixels[1][0] = col+x;
      pixels[1][1] = y-row;
      pixels[2][0] = x-col;
      pixels[2][1] = row+y;
      pixels[3][0] = x-col;
      pixels[3][1] = y-row;
      if (screen_bpp == 32) {
      ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
      ((Uint32 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
      ((Uint32 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
      ((Uint32 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
      ((Uint32 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
      }
      } else if (screen_bpp == 16) {
      ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
      ((Uint16 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
      ((Uint16 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
      ((Uint16 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
      ((Uint16 ) screen->pixels)[pixels[3][0] + (pixels[3][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
      }
      }
      /
      correct above code for book */
      if (d <= 0) {
      col++;
      d += four_b_square * col;
      }
      row–;
      d += two_a_square * (3 - (row << 1));
      }
      radius++;
      }

    if (SDL_MUSTLOCK(screen))
    SDL_UnlockSurface(screen);
    }–
    Chris Thielen <@Christopher_Thielen>

Oops, I found out what it was. It wasn’t SDL related, but it brings up
an SDL related question.

To anybody who blits, remembers the rects, and then calls
SDL_UpdateRects() to do their drawing (I’ve seen it in some examples but
I don’t know how many people use it), how do you handle the number of
rects needed? I have:

SDL_Rect blitted_rects[]

but the array size is too great, especially considering I need 200 or so
1x1 rectangles to remember as stars. Anybody have a good way to get
around it or does everybody just use a large array?On Sun, 2003-01-26 at 22:06, Chris Thielen wrote:

I’ve run into quite an odd issue with it comes to drawing ovals. I had
originally a function to draw circles, but when it did, things wouldn’t
work correctly in my app after it did the drawing. Moving sprites would
stay on screen, the stars would dim and come back up, and I suspected
some really weird memory corruption at first. But I wrote a simple macro
ENSURE_ON_SCREEN(x, y) to make sure the drawing function didnt write
outside the surface … and yet the problem remains.

I guess I have two questions. First, does this sound like a good way to
do locking/unlocking? (maybe that’s my problem? i don’t know, this weird
graphics corruption occurs under x11, probably windows too, i dont
know):

if (SDL_MUSTLOCK(screen)) {
unsigned char unlocked = 1;
while (unlocked)
unlocked = SDL_LockSurface(screen);
}

… code touching surface …

if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);

and … if that checks out … is there anything wrong with the included
draw_oval function? I don’t know what’s wrong, but only calling this
function causes that weird sort of video corruption. (where “screen” is
the main video surface and ensure_blitted() is a function to keep track
of rects needing flipping)

#define ENSURE_ON_SCREEN(x, y) if (((x) >= 0) && ((y) >= 0) && ((x) <
800) && ((y) < 600))

/* bresenham’s oval algorithm, converted from a dos graphics book */
void draw_oval(int x, int y, int radius, float aspect, Uint32 color) {
int pitch_adjust;
int pixels[4][2];
int col, i, row;
float aspect_square;
long a_square, b_square, two_a_square, two_b_square, four_a_square,
four_b_square, d;

if (screen_bpp == 32)
pitch_adjust = screen->pitch / sizeof(Uint32);
else if (screen_bpp == 16)
pitch_adjust = screen->pitch / sizeof(Uint16);

if (SDL_MUSTLOCK(screen)) {
unsigned char unlocked = 1;
while (unlocked)
unlocked = SDL_LockSurface(screen);
}

/* draw an oval */
aspect_square = aspect * aspect;
radius -= LINE_WIDTH / 2;
for (i = 1; i < LINE_WIDTH; i++) {
b_square = radius * radius;
a_square = b_square / aspect_square;
row = radius;
col = 0;
two_a_square = a_square << 1;
four_a_square = a_square << 2;
four_b_square = b_square << 2;
two_b_square = b_square << 1;
d = two_a_square * ((row - 1) * (row)) + a_square + two_b_square * (1

  • a_square);
    while(a_square * (row) > b_square * (col)) {
    /* plot the pixels */
    pixels[0][0] = col+x;
    pixels[0][1] = row+y;
    pixels[1][0] = col+x;
    pixels[1][1] = y-row;
    pixels[2][0] = x-col;
    pixels[2][1] = row+y;
    pixels[3][0] = x-col;
    pixels[3][1] = y-row;
    if (screen_bpp == 32) {
    ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
    ((Uint32 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
    ((Uint32 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
    ((Uint32 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
    ((Uint32 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
    }
    } else if (screen_bpp == 16) {
    ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
    ((Uint16 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
    ((Uint16 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
    ((Uint16 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
    }
    ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
    ((Uint16 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
    pitch_adjust)] = color;
    ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
    }
    }
    if (d >= 0) {
    row–;
    d -= four_a_square * (row);
    }
    d += two_b_square * (3 + (col << 1));
    col++;
    }
    d = two_b_square * (col + 1) * col + two_a_square * (row * (row - 2) +
    • (1 - two_a_square) * b_square;
      while((row) + 1) {
      /* plot the pixels */
      pixels[0][0] = col+x;
      pixels[0][1] = row+y;
      pixels[1][0] = col+x;
      pixels[1][1] = y-row;
      pixels[2][0] = x-col;
      pixels[2][1] = row+y;
      pixels[3][0] = x-col;
      pixels[3][1] = y-row;
      if (screen_bpp == 32) {
      ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
      ((Uint32 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
      ((Uint32 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
      ((Uint32 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
      ((Uint32 *) screen->pixels)[pixels[3][0] + (pixels[3][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
      }
      } else if (screen_bpp == 16) {
      ENSURE_ON_SCREEN(pixels[0][0], pixels[0][1]) {
      ((Uint16 *) screen->pixels)[pixels[0][0] + (pixels[0][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[0][0], pixels[0][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[1][0], pixels[1][1]) {
      ((Uint16 *) screen->pixels)[pixels[1][0] + (pixels[1][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[1][0], pixels[1][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[2][0], pixels[2][1]) {
      ((Uint16 *) screen->pixels)[pixels[2][0] + (pixels[2][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[2][0], pixels[2][1], 1, 1);
      }
      ENSURE_ON_SCREEN(pixels[3][0], pixels[3][1]) {
      ((Uint16 ) screen->pixels)[pixels[3][0] + (pixels[3][1] *
      pitch_adjust)] = color;
      ensure_blitted(pixels[3][0], pixels[3][1], 1, 1);
      }
      }
      /
      correct above code for book */
      if (d <= 0) {
      col++;
      d += four_b_square * col;
      }
      row–;
      d += two_a_square * (3 - (row << 1));
      }
      radius++;
      }

if (SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);
}

Chris Thielen <@Christopher_Thielen>

Use something like:

SDL_Rect *blitted_rects = (SDL_Rect *)malloc(max_rects * sizeof(SDL_Rect));

and realloc when you realize you need more. Also, it’s good practice to put
"assert((unsigned)i < max_rects)" wherever you access blitted_rects[i].

Regards,

DanielOn Monday 27 January 2003 07:23, Chris Thielen wrote:

Oops, I found out what it was. It wasn’t SDL related, but it brings up
an SDL related question.

To anybody who blits, remembers the rects, and then calls
SDL_UpdateRects() to do their drawing (I’ve seen it in some examples but
I don’t know how many people use it), how do you handle the number of
rects needed? I have:

SDL_Rect blitted_rects[]

but the array size is too great, especially considering I need 200 or so
1x1 rectangles to remember as stars. Anybody have a good way to get
around it or does everybody just use a large array?

200 rects to update? That seems like you are getting into a little much.
And, besides, isnt it likely that those rects will overlap one another?
I think you should look into condensing your rects into fewer (even one)
rect that covers all changed areas.