Sign in to follow this  
Omega55

SDL is flickering

Recommended Posts

I'm doing platformer at the moment, and so it requires a bit of pixel-perfect scrolling. Problem is, when I scroll I see annoying flickers, which doesn't happen when the game isn't scrolling. I tried all the possible video surfaces I can use, from a software surface to a double buffered hardware surface. I'm also using SDL_Flip(), which I thought waits for the vertical retrace (when using the double-buffered hardware) so that I don't see flickering. Anyone got remedies for this?

Share this post


Link to post
Share on other sites
Yeah, it's still flickering. I even drew on a software surface then blitted that on the screen (also software), it's still flickering. I'm wondering maybe it's because of my drawing functions, so here it is:


void viewport::Draw(SDL_Surface* screen) {
SDL_Rect rect;
int tileX=floor(cam_x/TILEWIDTH);int tileY=floor(cam_y/TILEHEIGHT);
int offX=cam_x-(floor(cam_x/TILEWIDTH)*TILEWIDTH);int offY=cam_y-(floor(cam_y/TILEHEIGHT)*TILEHEIGHT);
int w=width;int h=height;
if (offX>0) w++;
if (offY>0) h++;
for (int y=0;y<h;y++) {
for (int x=0;x<w;x++) {
rect.x=0;rect.y=0;rect.w=TILEWIDTH;rect.h=TILEHEIGHT;
if ( (x+tileX)*TILEWIDTH<cam_x ) { rect.x=offX;rect.w=TILEWIDTH-offX; }
if ( (y+tileY)*TILEHEIGHT<cam_y ) { rect.y=offY;rect.h=TILEHEIGHT-offY; }
if ( (x+tileX+1)*TILEWIDTH>cam_x+width*TILEWIDTH ) { rect.w=offX; }
if ( (y+tileY+1)*TILEHEIGHT>cam_y+height*TILEHEIGHT) { rect.h=offY; }
hook->tiles.images.SetPosition( pos_x+((x*TILEWIDTH))-offX, pos_y+((y*TILEHEIGHT))-offY );
hook->tiles.images.Draw(screen, hook->tiles.templates[hook->array[y+tileY][x+tileX]].num,
rect.x, rect.y, rect.w, rect.h);
}
}
}

void board_viewport::Draw(SDL_Surface* screen) {
viewport::Draw(screen);
vector<object*> o_list=board_hook->GetObjectList();
SDL_Rect rect, s_rect, o_rect;
int offX=cam_x-(floor(cam_x/TILEWIDTH)*TILEWIDTH);int offY=cam_y-(floor(cam_y/TILEHEIGHT)*TILEHEIGHT);
s_rect.x=cam_x;
s_rect.y=cam_y;
s_rect.w=width*TILEWIDTH;
s_rect.h=height*TILEHEIGHT;
for (int i=0;i<o_list.size();i++) {
o_rect.w=o_list[i]->sprite->GetOffX();
o_rect.h=o_list[i]->sprite->GetOffY();
if (o_list[i]->slopeX<0) o_rect.x=o_list[i]->x-((o_list[i]->sprite->GetOffX()-o_list[i]->w)/2);
else o_rect.x=o_list[i]->slopeX-((o_list[i]->sprite->GetOffX()-o_list[i]->w)/2);
if (o_list[i]->slopeY<0) o_rect.y=o_list[i]->y-(o_list[i]->sprite->GetOffY()-o_list[i]->h);
else o_rect.y=o_list[i]->slopeY-(o_list[i]->sprite->GetOffY()-o_list[i]->h);
if ( Collide(o_rect, s_rect) ) { //do collision detection
rect.x=0;rect.y=0;rect.w=o_rect.w;rect.h=o_rect.h;
if ( o_rect.x<cam_x ) {
rect.x=cam_x-o_rect.x;
rect.w-=rect.x;
}
if ( o_rect.y<cam_y ) {
rect.y=cam_y-o_rect.y;
rect.h-=rect.y;
}
if ( o_rect.x+o_rect.w>cam_x+width*TILEWIDTH ) {
rect.w-=(o_rect.x+o_rect.w)-(cam_x+width*TILEWIDTH);
}
if ( o_rect.y+o_rect.h>cam_y+height*TILEHEIGHT) {
rect.h-=(o_rect.y+o_rect.h)-(cam_y+height*TILEHEIGHT);
}
o_list[i]->sprite->SetPosition( pos_x+(o_rect.x-cam_x), pos_y+(o_rect.y-cam_y) );
o_list[i]->sprite->Draw(screen, rect.x, rect.y, rect.w, rect.h);
}
}
}

Note: I'm using a tile and sprite class I've created myself. The Draw() function has x, y, w, and h arguments for clipping purposes.

Share this post


Link to post
Share on other sites
Please use [ source lang="CPP" ] ... [ /source ] (no spaces). It makes that jumble actually readable. And by default, it assumes C++, so you only need to write [ source ] ... [ /source ].


 
void viewport::Draw(SDL_Surface* screen) {
SDL_Rect rect;
int tileX=floor(cam_x/TILEWIDTH);int tileY=floor(cam_y/TILEHEIGHT);
int offX=cam_x-(floor(cam_x/TILEWIDTH)*TILEWIDTH);int offY=cam_y-(floor(cam_y/TILEHEIGHT)*TILEHEIGHT);
int w=width;int h=height;
if (offX>0) w++;
if (offY>0) h++;
for (int y=0;y<h;y++) {
for (int x=0;x<w;x++) {
rect.x=0;rect.y=0;rect.w=TILEWIDTH;rect.h=TILEHEIGHT;
if ( (x+tileX)*TILEWIDTH<cam_x ) { rect.x=offX;rect.w=TILEWIDTH-offX; }
if ( (y+tileY)*TILEHEIGHT<cam_y ) { rect.y=offY;rect.h=TILEHEIGHT-offY; }
if ( (x+tileX+1)*TILEWIDTH>cam_x+width*TILEWIDTH ) { rect.w=offX; }
if ( (y+tileY+1)*TILEHEIGHT>cam_y+height*TILEHEIGHT) { rect.h=offY; }
hook->tiles.images.SetPosition( pos_x+((x*TILEWIDTH))-offX, pos_y+((y*TILEHEIGHT))-offY );
hook->tiles.images.Draw(screen, hook->tiles.templates[hook->array[y+tileY][x+tileX]].num,
rect.x, rect.y, rect.w, rect.h);
}
}
}

void board_viewport::Draw(SDL_Surface* screen) {
viewport::Draw(screen);
vector<object*> o_list=board_hook->GetObjectList();
SDL_Rect rect, s_rect, o_rect;
int offX=cam_x-(floor(cam_x/TILEWIDTH)*TILEWIDTH);int offY=cam_y-(floor(cam_y/TILEHEIGHT)*TILEHEIGHT);
s_rect.x=cam_x;
s_rect.y=cam_y;
s_rect.w=width*TILEWIDTH;
s_rect.h=height*TILEHEIGHT;
for (int i=0;i<o_list.size();i++) {
o_rect.w=o_list[i]->sprite->GetOffX();
o_rect.h=o_list[i]->sprite->GetOffY();
if (o_list[i]->slopeX<0) o_rect.x=o_list[i]->x-((o_list[i]->sprite->GetOffX()-o_list[i]->w)/2);
else o_rect.x=o_list[i]->slopeX-((o_list[i]->sprite->GetOffX()-o_list[i]->w)/2);
if (o_list[i]->slopeY<0) o_rect.y=o_list[i]->y-(o_list[i]->sprite->GetOffY()-o_list[i]->h);
else o_rect.y=o_list[i]->slopeY-(o_list[i]->sprite->GetOffY()-o_list[i]->h);
if ( Collide(o_rect, s_rect) ) { //do collision detection
rect.x=0;rect.y=0;rect.w=o_rect.w;rect.h=o_rect.h;
if ( o_rect.x<cam_x ) {
rect.x=cam_x-o_rect.x;
rect.w-=rect.x;
}
if ( o_rect.y<cam_y ) {
rect.y=cam_y-o_rect.y;
rect.h-=rect.y;
}
if ( o_rect.x+o_rect.w>cam_x+width*TILEWIDTH ) {
rect.w-=(o_rect.x+o_rect.w)-(cam_x+width*TILEWIDTH);
}
if ( o_rect.y+o_rect.h>cam_y+height*TILEHEIGHT) {
rect.h-=(o_rect.y+o_rect.h)-(cam_y+height*TILEHEIGHT);
}
o_list[i]->sprite->SetPosition( pos_x+(o_rect.x-cam_x), pos_y+(o_rect.y-cam_y) );
o_list[i]->sprite->Draw(screen, rect.x, rect.y, rect.w, rect.h);
}
}
}



Spacing, commenting, and other conventions would also help greatly. But I'm afraid I don't have the knowledge I need.

Share this post


Link to post
Share on other sites
Hidden
I had problems with screen tearing (if that's what you mean by "flickering") on some video cards (or monitors?) for my SDL game I did a year ago. I never actually managed to solved it. It worked fine on some computers, and less good on others. My game was locked at 60 FPS. I have a theory that may have had something to do with it. Perhaps you should investigate and see if that's what's causing it?

Share this post


Link to post
Sorry Splinter, didn't know that ;|

Kada I tried locking at certain FPSs (even not having the delay altogether) but it's still there. I might have to try your theory on my brother's computer.

Share this post


Link to post
Share on other sites
You might want to consider using OpenGL to do all of your graphics plotting as is illustrated in David Olofson's example code. (Scroll down to SmoothScroll-1.1.tar.gz to download the source and if you don't have an unpacker for .tar.gz files use SevenZip. Binaries for SmoothScroll-1.1 are in a separate .zip file for Windows users so you can try it out before you download the source and the unpacker.)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this