SDL is flickering

Started by
5 comments, last by samuraicrow 16 years, 3 months ago
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?
This is supposed to be handwritten...
Advertisement
Are you sure you use both SDL_DOUBLEBUF and SDL_HWSURFACE flags?
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->sprite->GetOffX();
o_rect.h=o_list->sprite->GetOffY();
if (o_list->slopeX<0) o_rect.x=o_list->x-((o_list->sprite->GetOffX()-o_list->w)/2);
else o_rect.x=o_list->slopeX-((o_list->sprite->GetOffX()-o_list->w)/2);
if (o_list->slopeY<0) o_rect.y=o_list->y-(o_list->sprite->GetOffY()-o_list->h);
else o_rect.y=o_list->slopeY-(o_list->sprite->GetOffY()-o_list->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->sprite->SetPosition( pos_x+(o_rect.x-cam_x), pos_y+(o_rect.y-cam_y) );
o_list->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.
This is supposed to be handwritten...
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->sprite->GetOffX();          o_rect.h=o_list->sprite->GetOffY();          if (o_list->slopeX<0) o_rect.x=o_list->x-((o_list->sprite->GetOffX()-o_list->w)/2);          else o_rect.x=o_list->slopeX-((o_list->sprite->GetOffX()-o_list->w)/2);          if (o_list->slopeY<0) o_rect.y=o_list->y-(o_list->sprite->GetOffY()-o_list->h);          else o_rect.y=o_list->slopeY-(o_list->sprite->GetOffY()-o_list->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->sprite->SetPosition( pos_x+(o_rect.x-cam_x), pos_y+(o_rect.y-cam_y) );               o_list->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.

.

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.
This is supposed to be handwritten...
Is it running in full screen or windowed mode? Waiting for vsync is only supported in full screen mode.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
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.)

This topic is closed to new replies.

Advertisement