Re: [AD] new_api_branch: al_create_display and blit patch

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Sunday 15 May 2005 00:58, Evert Glebbeek wrote:
> Two patches attached. The first removes the v_w and v_h parameters from 
> al_create_display, conforming more to the original design. For the 
> compatibility layer this means that set_gfx_mode() now ignores the last 
> two parameters completely. I don't think it's really important in 
> practice.

Commited with updates. This means that for instance exupdate from 4.2 won't 
work with page flipping in X11 or other platforms for which the vram is a 
single surface. No problem because the new display API does the page 
flipping anyway. Attached is a hacked-up exupdate for those who want to 
take a look at it.

I've spend the afternoon trying to get `video bitmaps' to work somewhat 
sensibly in X11 (ie, by allocating them all as seperate entities rather 
than as subbitmaps of a large bitmap) and I've more or less figured out 
that the way it is currently done is about optimal: I was able to get the 
new code to run, but not without insane flickering otherwise. It's not a 
big issue though: it's up to the graphics driver to decide how video 
bitmaps are best implemented and if the current way is the best, then so 
be it. To make this work, all display drivers need to be aware of the 
flags passed to al_create_display(). This is a rather lengthy and boring 
update I've worked around for now.

I have hit a bit of a snag though: when doing page flipping, X event queue 
is flooded. From what I can tell, it's the same problem that used to 
plague expal. This doesn't happen with 4.2, so it's due to a difference 
between the 4.2 and 4.3 X11 driver. Probably there needs to be an XSync() 
somewhere, but I can't figure out where. Someone with a better 
understanding of the driver than I have may want to have a look at it.

I haven't commited my blit() patch yet.
By the way, can we have a compat header file for compatibility stuff, just 
as we have compat C files? It'll help clean up some of the headers.

Evert
/*
 *    Example program for the Allegro library, by Shawn Hargreaves.
 *
 *    This program demonstrates how to support double buffering,
 *    page flipping, and triple buffering as options within a single
 *    program, and how to make things run at a constant rate no
 *    matter what the speed of your computer. You have to use this
 *    example from the commandline to specify as first parameter a
 *    number which represents the type of video update you want: 1
 *    for double buffering with memory bitmaps, 2 for page flipping,
 *    3 for triple buffering and 4 for double buffering with system
 *    bitmaps. After this, a dialog allows you to select a screen
 *    resolution and finally you will see a kaleidoscopic animation,
 *    along with a frames per second counter on the top left of
 *    the screen.
 */


#include <allegro.h>



/* number of video memory pages:
 *  1 = double buffered
 *  2 = page flipping
 *  3 = triple buffered
 */
int num_pages;

int use_system_bitmaps;



/* counters for speed control and frame rate measurement */
volatile int update_count = 0;
volatile int frame_count = 0;
volatile int fps = 0;



/* timer callback for controlling the program speed */
void timer_proc(void)
{
   update_count++;
}

END_OF_FUNCTION(timer_proc)



/* timer callback for measuring the framerate */
void fps_proc(void)
{
   fps = frame_count;
   frame_count = 0;
}

END_OF_FUNCTION(fps_proc)



/* some rotation values for the graphical effect */
fixed r1 = 0;
fixed r2 = 0;
fixed r3 = 0;
fixed r4 = 0;



/* helper to draw four mirrored versions of a triangle */
void kalid(BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3,
	   int r, int g, int b)
{
   triangle(bmp, SCREEN_W/2+x1, SCREEN_H/2+y1, SCREEN_W/2+x2, SCREEN_H/2+y2,
	    SCREEN_W/2+x3, SCREEN_H/2+y3, makecol(r, g, b));
   triangle(bmp, SCREEN_W/2-x1, SCREEN_H/2+y1, SCREEN_W/2-x2, SCREEN_H/2+y2,
	    SCREEN_W/2-x3, SCREEN_H/2+y3, makecol(r, g, b));
   triangle(bmp, SCREEN_W/2-x1, SCREEN_H/2-y1, SCREEN_W/2-x2, SCREEN_H/2-y2,
	    SCREEN_W/2-x3, SCREEN_H/2-y3, makecol(r, g, b));
   triangle(bmp, SCREEN_W/2+x1, SCREEN_H/2-y1, SCREEN_W/2+x2, SCREEN_H/2-y2,
	    SCREEN_W/2+x3, SCREEN_H/2-y3, makecol(r, g, b));
}



/* draws the current animation frame into the specified bitmap */
void draw_screen(BITMAP *bmp)
{
   fixed c1 = fixcos(r1);
   fixed c2 = fixcos(r2);
   fixed c3 = fixcos(r3);
   fixed c4 = fixcos(r4);
   fixed s1 = fixsin(r1);
   fixed s2 = fixsin(r2);
   fixed s3 = fixsin(r3);
   fixed s4 = fixsin(r4);

   acquire_bitmap(bmp);

   clear_bitmap(bmp);

   xor_mode(TRUE);

   kalid(bmp, fixtoi(c1*SCREEN_W/3), fixtoi(s1*SCREEN_H/3),
	      fixtoi(c2*SCREEN_W/3), fixtoi(s2*SCREEN_H/3),
	      fixtoi(c3*SCREEN_W/3), fixtoi(s3*SCREEN_H/3),
	      127+fixtoi(c1*127), 127+fixtoi(c2*127), 127+fixtoi(c3*127));

   kalid(bmp, fixtoi(s1*SCREEN_W/3), fixtoi(c2*SCREEN_H/3),
	      fixtoi(s3*SCREEN_W/3), fixtoi(c4*SCREEN_H/3),
	      fixtoi(c3*SCREEN_W/3), fixtoi(s4*SCREEN_H/3),
	      127+fixtoi(s1*127), 127+fixtoi(c4*127), 127+fixtoi(s4*127));

   kalid(bmp, fixtoi(fixmul(s2, c3)*SCREEN_W/3), fixtoi(c1*SCREEN_H/3),
	      fixtoi(c4*SCREEN_W/3), fixtoi(fixmul(c2, s3)*SCREEN_H/3),
	      fixtoi(fixmul(c3, s4)*SCREEN_W/3), fixtoi(s1*SCREEN_H/3),
	      127+fixtoi(s2*127), 127+fixtoi(c3*127), 127+fixtoi(s3*127));

   xor_mode(FALSE);

   if (num_pages == 1) {
      if (use_system_bitmaps)
	 textout_ex(bmp, font, "Double buffered (system bitmap)", 0, 0,
		    makecol(255, 255, 255), -1);
      else
	 textout_ex(bmp, font, "Double buffered (memory bitmap)", 0, 0,
		    makecol(255, 255, 255), -1);
   }
   else if (num_pages == 2)
      textout_ex(bmp, font, "Page flipping (two pages of vram)", 0, 0,
		 makecol(255, 255, 255), -1);
   else
      textout_ex(bmp, font, "Triple buffered (three pages of vram)", 0, 0,
		 makecol(255, 255, 255), -1);

   textout_ex(bmp, font, gfx_driver->name, 0, 16, makecol(255, 255, 255), -1);

   textprintf_ex(bmp, font, 0, 32, makecol(255, 255, 255), -1, "FPS: %d", fps);

   release_bitmap(bmp);
}



/* called at a regular speed to update the program state */
void do_update(void)
{
   r1 += ftofix(0.5);
   r2 += ftofix(0.6);
   r3 += ftofix(0.11);
   r4 += ftofix(0.13);
}



int main(int argc, char *argv[])
{ 
   PALETTE pal;
   int card = GFX_AUTODETECT;
   int w, h, bpp, i;
   int flags = 0;
   int update_flags[] = { AL_UPDATE_DOUBLE_BUFFER, AL_UPDATE_PAGE_FLIP,
                          AL_UPDATE_TRIPLE_BUFFER, AL_UPDATE_DOUBLE_BUFFER };

   if (allegro_init() != 0)
      return 1;

   /* check command line arguments */
   if (argc == 2)
      num_pages = atoi(argv[1]);
   else
      num_pages = 0;

   if (num_pages)
      flags = update_flags[num_pages-1];

   if (num_pages == 4) {
      num_pages = 1;
      use_system_bitmaps = TRUE;
   }
   else
      use_system_bitmaps = FALSE;

   if ((num_pages < 1) || (num_pages > 3)) {
      allegro_message("\nUsage: 'exupdate num_pages', where num_pages is one of:\n\n"
		      "1 = double buffered (memory bitmap)\n\n"
		      "    + easy, reliable\n"
		      "    + drawing onto a memory bitmap is very fast\n"
		      "    - blitting the finished image to the screen can be quite slow\n\n"
		      "2 = page flipping (two pages of video memory)\n\n"
		      "    + avoids the need for a memory to screen blit of the completed image\n"
		      "    + can use hardware acceleration when it is available\n"
		      "    - drawing directly to vram can be slower than using a memory bitmap\n"
		      "    - requires a card with enough video memory for two screen pages\n\n"
		      "3 = triple buffered (three pages of video memory)\n\n"
		      "    + like page flipping, but faster and smoother\n"
		      "    - requires a card with enough video memory for three screen pages\n"
		      "    - only possible with some graphics drivers\n\n"
		      "4 = double buffered (system bitmap)\n\n"
		      "    + as easy as normal double buffering\n"
		      "    + system bitmaps can be hardware accelerated on some platforms\n"
		      "    - drawing to system bitmaps is sometimes slower than memory bitmaps\n\n");
      return 1;
   }

   /* set up Allegro */
   install_keyboard();
   install_timer();
   install_mouse();

   if (al_create_display(GFX_SAFE, 0, 8, 320, 200) == NULL) {
      allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
      return 1;
   }
   set_palette(desktop_palette);

   w = SCREEN_W;
   h = SCREEN_H;
   bpp = bitmap_color_depth(screen);
   if (!gfx_mode_select_ex(&card, &w, &h, &bpp))
      return 0;

   al_destroy_display(al_main_display);
   if (al_create_display(card, flags, bpp, w, h) == NULL) {
      allegro_message("Error setting graphics mode\n%s\n", allegro_error);
      return 1;
   }

   generate_332_palette(pal);
   pal[0].r = pal[0].g = pal[0].b = 0;
   set_palette(pal);

   /* install timer handlers to control and measure the program speed */
   install_int_ex(timer_proc, BPS_TO_TIMER(60));
   install_int_ex(fps_proc, BPS_TO_TIMER(1));

   /* main program loop */
   while (!keypressed()) {

      /* draw the next frame of graphics */
      draw_screen(al_get_buffer(al_main_display));
      al_flip_display(al_main_display);

      /* update the program state */
      while (update_count > 0) {
	 do_update();
	 update_count--;
      }

      frame_count++;
   }

   al_destroy_display(al_main_display);
   return 0;
}

END_OF_MAIN()


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/