Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » 60Hz with Allegro?

This thread is locked; no one can reply to it. rss feed Print
60Hz with Allegro?
Zepper
Member #8,715
June 2007
avatar

- You know that 1000/60 = 16.67, and 16x60 = 960 miliseconds. In other words, Allegro doesn't keep my program running at exactly 60Hz - it keeps around 62~63 frames-per-second (62.5 is the result). The function to request a 60Hz refresh (request_refresh_rate(60)) doesn't work, even if the Windows monitor is set to 60Hz, Allegro keeps displaying 70Hz of refreshing.

- There's only the milisecond as precision? No turn arounds? Yes, my system is Windows XP, using MinGW + Dev-Cpp.

gnolam
Member #2,030
March 2002
avatar

1) Show us your initialization code.
2) Are you using vsync?
3) What's the result of get_refresh_rate()?
4) You won't ever get exactly the logic or refresh rate you requested. The timers only have so much precision, and in any non-real-time system you will have interference from other processes.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Kibiz0r
Member #6,203
September 2005
avatar

Might be helpful to see the main loop, too.

Zepper
Member #8,715
June 2007
avatar

- I use exactly what extimer.c does. Anyway, I get 62~63 FPS, but the get_refresh_rate() still returns 60, the retrace count returns 71~72 at every sync. No, I don't use vsync(), but this...

1//TIMER CONTROL
2//=============
3volatile int update_count = 0;
4volatile int frame_count = 0;
5volatile int fps = 0;
6 
7void gfx_timer_proc(void)
8{
9 update_count = 1;
10}
11 
12END_OF_FUNCTION(gfx_timer_proc)
13 
14static void gfx_fps_proc(void)
15{
16 fps = frame_count;
17 frame_count = 0;
18}
19 
20 
21/* inits timer
22 */
23void gfx_init_timer()
24{
25 LOCK_VARIABLE(update_count);
26 LOCK_VARIABLE(frame_count);
27 LOCK_VARIABLE(fps);
28 LOCK_FUNCTION(gfx_timer_proc);
29 LOCK_FUNCTION(gfx_fps_proc);
30 
31 install_int_ex(gfx_timer_proc, BPS_TO_TIMER(60));
32 install_int_ex(gfx_fps_proc, BPS_TO_TIMER(1));
33}
34 
35void refresh_screen()
36{
37 while(0 == update_count) {
38 rest(0);
39 }
40 update_count = 0;
41 frame_count++;
42 
43 //blit the current image buffer
44 // source, destiny, sx, sy, dx, dy, sizex, sizey
45 blit(video->Bmp_eagle,screen,0,0,video->x,video->y,video->xmax,video->ymax);
46}

- The refresh_screen() is called when an entire PPU frame is done. Things run around 110 FPS with no control, of course. Anything more?

Kris Asick
Member #1,424
July 2001

Three things.

1. request_refresh_rate() needs some work. I've never seen it work properly on Windows.

2. Even if you successfully request the refresh rate you want, it will never be exactly the same every time. No matter what, your Allegro timer will slowly drift away from the monitor's refresh. The only ways you can time perfectly to the monitor is to use vsync(), page flipping (which also uses vsync()) or learn triple buffering.

3. Timing only to the monitor is a very bad idea since not every user will have the same refresh rate and since request_refresh_rate() isn't reliable. If you want your game to be timed accurately you will need to resort to a timer. Thus, unless you're doing real-time logic, monitor synchronization plus accurate game timing are impossible to combine without frame loss.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

gnolam
Member #2,030
March 2002
avatar

1) You're not showing us how you set up your graphics mode.
2) That's now how you synchronize updates to the refresh rate. Use vsync().

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Zepper
Member #8,715
June 2007
avatar

Fair enough, here...

1/* install gfx
2 */
3int init_gfx()
4{
5 int directx_vmode[10] = {
6/*00*/ GFX_AUTODETECT,
7/*01*/ GFX_AUTODETECT_FULLSCREEN,
8/*02*/ GFX_AUTODETECT_WINDOWED,
9/*03*/ GFX_SAFE,
10/*04*/ GFX_DIRECTX_ACCEL,
11/*05*/ GFX_DIRECTX_SOFT,
12/*06*/ GFX_DIRECTX_SAFE,
13/*07*/ GFX_DIRECTX_WIN,
14/*08*/ GFX_DIRECTX_OVL,
15/*09*/ GFX_GDI
16 };
17 
18 /* Allows to run in background, sweet!
19 */
20 set_display_switch_mode(SWITCH_BACKGROUND);
21 
22 set_color_depth(16);
23 request_refresh_rate(60);
24 if(0 != set_gfx_mode(directx_vmode[video->gfx_card],video->vx,video->vy,0,0))
25 {
26 allegro_message("Graphics error: %s.\n", allegro_error);
27 return -1;
28 }
29 if (get_refresh_rate() != 60)
30 allegro_message("Couldn't set refresh rate to 60Hz!");
31
32 /* gfx interpolation requires 640x480
33 */
34 video->Bmp_eagle = create_bitmap_ex(16,640,480);
35 surface_lim = (short *)video->Bmp_eagle->line[0];
36
37 /* reset video context
38 */
39 fps_display = 1;
40 reset_xyblit();
41 ppu_select_palette(0);
42 return 0;
43}

- I use a config file, where the user can specify a gfx mode and a resolution. I gathered all those variables into a structure.

video->gfx_card selects a video mode, even with the poor "card" label though, since it's not a card anyway.
video->vx,video->vy defines the size of the screen, like 640 480.

- The other stuff does not affect the gfx, except for the 16-bit mode indexed by a palette array.

Go to: