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> - (1 - two_a_square) * b_square;