Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Would like some help with jittering

This thread is locked; no one can reply to it. rss feed Print
Would like some help with jittering
Cain
Member #6,095
August 2005

I seem to be having a problem getting my pong game (well not much of a game at this point) to render smoothly. I am using triple buffering and a timed loop but the ball seems to jitter as it moves but I don't have any flickering or tearing. I have tried slowing down/speeding up my logic fps but that doesn't seem to have any effect. The faster the computer the worse the jittering. I am using the triple buffer example as a guide for my ScreenBuffer class and the basic timed game loop in the Allegro FAQ for my run method in Pong.cpp.

Here's the relevant code. I have a Pong class that handles the game, a ScreenBuffer class that takes care of the triple buffering and a Ball class (subclass of GameObject) that is the ball. Right now all I have is a single ball that bounces around the screen.

Any help would be appreciated. Thanks.

Pong.cpp

1volatile int g_speedCounter=0;
2 
3//---------------------------------------------------------
4// incrementSpeedCounter
5//---------------------------------------------------------
6void incrementSpeedCounter()
7{
8 g_speedCounter++;
9}
10END_OF_FUNCTION(incrementSpeedCounter)
11//---------------------------------------------------------
12// Pong::run
13//---------------------------------------------------------
14void Pong::run()
15{
16 LOCK_VARIABLE(g_speedCounter);
17 LOCK_FUNCTION(incrementSpeedCounter);
18 
19 install_int_ex(incrementSpeedCounter, BPS_TO_TIMER(50));
20 
21 do
22 {
23 while (g_speedCounter > 0)
24 {
25 gameUpdate();
26 g_speedCounter--;
27 }
28 render();
29 
30 
31 } while (!keypressed());
32}
33//---------------------------------------------------------
34// Pong::render
35//---------------------------------------------------------
36void Pong::render()
37{
38 BITMAP* buffer = NULL;
39
40 buffer = m_screenBuffer->getBuffer();
41
42 if(buffer)
43 {
44 acquire_bitmap(buffer);
45
46 clear_to_color(buffer,makecol(0,0,0));
47 
48 m_ball->draw(buffer);
49 
50 release_bitmap(buffer);
51
52 m_screenBuffer->flip();
53 }
54 else
55 {
56 allegro_message("triple buffer error");
57 }
58}

GameObject.cpp (Ball is a sub-class)

1//---------------------------------------------------------
2//GameObject::loadImage
3//---------------------------------------------------------
4int GameObject::loadImage(string sFile)
5{
6 int result = -1;
7 BITMAP* temp = load_bitmap(sFile.c_str(),NULL);
8 m_image = create_video_bitmap(temp->w, temp->h);
9 blit(temp,m_image,0,0,0,0,temp->w,temp->h);
10
11 destroy_bitmap(temp);
12
13 if(m_image)
14 {
15 result = SUCCESS;
16 }
17 return result;
18}

ScreenBuffer.cpp

1//---------------------------------------------------------
2// ScreenBuffer::ScreenBuffer()
3//---------------------------------------------------------
4ScreenBuffer::ScreenBuffer()
5{
6 m_bTripleBuffer=false;
7
8 m_currentPage = 0;
9 
10 if(enableTripleBuffering())
11 {
12 m_numPages = 3;
13 }
14 else
15 {
16 m_numPages = 2;
17 }
18 
19 m_bufferPages = new BITMAP*[m_numPages];
20
21 for(int i=0; i<m_numPages; i++)
22 {
23 m_bufferPages<i> = create_video_bitmap(SCREEN_W, SCREEN_H);
24 }
25
26 clear_bitmap(m_bufferPages[m_currentPage]);
27}
28//---------------------------------------------------------
29// ScreenBuffer::enableTripleBuffering()
30//---------------------------------------------------------
31bool ScreenBuffer::enableTripleBuffering()
32{
33 //try to enable triple buffering
34 if(!(gfx_capabilities & GFX_CAN_TRIPLE_BUFFER))
35 {
36 enable_triple_buffer();
37 }
38
39 //make sure it worked
40 if(!(gfx_capabilities & GFX_CAN_TRIPLE_BUFFER))
41 {
42 m_bTripleBuffer = FALSE;
43 }
44 else
45 {
46 m_bTripleBuffer = true;
47 }
48
49 return m_bTripleBuffer;
50}
51//---------------------------------------------------------
52// ScreenBuffer::flip
53//---------------------------------------------------------
54void ScreenBuffer::flip()
55{
56 //make sure last flip happened
57 do{}while(poll_scroll());
58
59 //post a request to display new image
60 request_video_bitmap(m_bufferPages[m_currentPage]);
61
62 //point to next page
63 m_currentPage = (m_currentPage+1)%m_numPages;
64}

kenmasters1976
Member #8,794
July 2007

It seems you are using video bitmaps. Have you tried with memory bitmaps?.

Cain
Member #6,095
August 2005

For the ball object or the buffers? As far as I know for triple buffering to work they need to be video bitmaps. I tried both video and memory bitmaps for the ball and it didn't make a difference.

amber
Member #6,783
January 2006
avatar

Are you using Windows?

I'm not sure if this is an issue any more, but code like this used to misbehave on Windows:

    acquire_bitmap(buffer);  
    clear_to_color(buffer,makecol(0,0,0));    
    m_ball->draw(buffer);
    release_bitmap(buffer);
    m_screenBuffer->flip();

The clear would actually end up releasing the bitmap and everything from then on would be slow as Allegro had to keep locking the bitmap again.
Try this and see if it speeds up:

    clear_to_color(buffer,makecol(0,0,0));
    acquire_bitmap(buffer);      
    m_ball->draw(buffer);
    release_bitmap(buffer);
    m_screenBuffer->flip();

Cain
Member #6,095
August 2005

I tried that but it didn't seem to make a difference.

I think the problem is with the timing in my run method. I took the timing out and then it ran really smooth, but obviously I need to have a timing loop so I'll have to come up with something else.

Neil Walker
Member #210
April 2000
avatar

Hello,
Take heed of the manual for acquire_bitmap()

Quote:

You never need to call the function explicitly as it is low level, and will only give you a speed up if you know what you are doing. Using it wrongly may cause slowdown, or even lock up your program.

You don't use acquire_bitmap when you are doing vram to vram calls. i.e. take out your acquire bitmap call if you have achieved and are using paging/triple buffering and video bitmaps, which is what you are doing.

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Todd Cope
Member #998
November 2000
avatar

Quote:

I think the problem is with the timing in my run method. I took the timing out and then it ran really smooth, but obviously I need to have a timing loop so I'll have to come up with something else.

Allegro's timers are not that good. If you really want a smooth game you will have to resort to high performance timers which are platform specific. High performance timers have been discussed here before. I ran this search and got some good results.

Edit: I hear Allegro 5 has much better timers but it is not nearly complete yet.

Cain
Member #6,095
August 2005

Thanks Todd, I'll look into it.

The problem is definitely the timers. I disabled them and it ran great on my laptop because it's a rather slow machine, but on my desktop the game is unplayable because the logic loop is not regulated so the ball just flies around the screen but at least it's smooth...heh.

If the refresh rate is 60Hz should the logic be lower, equal or higher, or does it really matter as long as it's (relatively) consistent?

Todd Cope
Member #998
November 2000
avatar

Quote:

If the refresh rate is 60Hz should the logic be lower, equal or higher, or does it really matter as long as it's (relatively) consistent?

I use 60hz timers with all my games and they run smooth even if the monitor's refresh rate isn't the same. It works similarly to how 24fps movies are played on 30fps televisions. You should be able to use whatever logic rate you want but I haven't tried anything other than 60hz and 100hz.

Neil Walker
Member #210
April 2000
avatar

you could always call request_refresh_rate(gamefps);

remember about removing acquire_bitmap as well when using video bitmaps...

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Cain
Member #6,095
August 2005

I removed the acquire/release bitmap functions but still have the issue. I've provided a link to the source code and a compiled exe(alleg42.dll not included) if anyone wants to look at it to see what I mean. Pressing any key will exit the game as I have not implemented in the input routine yet. The timing I'm using is basically the one from the FAQ which is obviously not good enough so I'll have to find a better routine. I did a search on the forums and tried a few different ones that I came across but nothing seems to work.

I was playing Diablo the other day and it ran great on my computer which makes me wonder what they did to get things to run nice and smooth even on machines that are much faster than it was designed for. I'm sure their code is optimized for windows which seems like what I'll need to do to get my simple Pong game to work.

The way I'm looking at it is if I can't get pong to run smoothly then there's not much hope for more complex games...heh.

http://www.spiritsofwar.com//troy/Pong.zip

Audric
Member #907
January 2001

Quote:

I was playing Diablo the other day and it ran great on my computer which makes me wonder what they did to get things to run nice and smooth

Probably Blizzard's mind control plugin, because Diablo 2's logic and drawing are capped at 25fps.

Cain
Member #6,095
August 2005

I was actually referring to Diablo 1...but yeah it wouldn't surprise me if they had some sort of subliminal mind control stuff going on. ;)

kenmasters1976
Member #8,794
July 2007

Just compiled your code (the .exe you provided didn't work). My guess is that your problem is indeed the resolution of Allegro timers, that's why the ball jitters. You'll have to find another way for timing your game.

Also, on a side note, you do a lot of checks, but you don't handle them correctly... when running your program it may show messages indicating that something didn't work but yet it crashes.

Cain
Member #6,095
August 2005

Yeah I know I'm not using all my checks properly, I just haven't gotten around to doing all the error checking. I actually haven't touch the game for a while until last night when I have nothing else to do.

I'll keep looking around and trying out new stuff for timing. Thanks for looking at it.

Matt Smith
Member #783
November 2000

25 fps can be smooth. Disney cartoons are 12 fps.

Go to: