Re: [AD] triple buffering and page flipping

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


On 2006-01-01, Elias Pschernig <elias@xxxxxxxxxx> wrote:
> On Sun, 2006-01-01 at 12:24 +1100, Peter Wang wrote:
> > 
> > The breakage seems like it is limited to the demo game and was
> > introduced when the demo was split into multiple files, namely r5158 in
> > SVN.  Elias?
> > 
> 
> Erm.. the split was done quite some time ago.. anyway, I'll try it in
> windows myself sometime this year and see if I can reproduce..

Here is the fix.  The video bitmaps for page flipping and triple
buffering were being created _before_ the call to set_gfx_mode().

Attached is a related patch to turn the animation_type variable
into an enumeration.

Peter
--- demo/display.c	(revision 5677)
+++ demo/display.c	(local)
@@ -14,6 +14,49 @@ void init_display(int mode, int w, int h
    animation_type = type;
 
    switch (animation_type) {
+      case DOUBLE_BUFFER:
+      case DIRTY_RECTANGLE:
+         num_pages = 1;
+         break;
+
+      case PAGE_FLIP:
+         num_pages = 2;
+         break;
+
+      case TRIPLE_BUFFER:
+         num_pages = 3;
+         break;
+   }
+
+   set_color_depth(8);
+#ifdef ALLEGRO_VRAM_SINGLE_SURFACE
+   if (set_gfx_mode(mode, w, h, w, h * num_pages) != 0) {
+#else
+   if (set_gfx_mode(mode, w, h, 0, 0) != 0) {
+#endif
+      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
+      allegro_message("Error setting 8bpp graphics mode\n%s\n",
+                      allegro_error);
+      exit(1);
+   }
+
+   page1 = NULL;
+   page2 = NULL;
+   page3 = NULL;
+   memory_buffer = NULL;
+
+   switch (animation_type) {
+
+      case DOUBLE_BUFFER:
+      case DIRTY_RECTANGLE:
+	 memory_buffer = create_bitmap(SCREEN_W, SCREEN_H);
+
+         if (!memory_buffer) {
+            set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
+            allegro_message("Could not create memory buffer\n");
+            exit(1);
+         }
+	 break;
 
       case PAGE_FLIP:
          /* set up page flipping bitmaps */
@@ -61,36 +104,6 @@ void init_display(int mode, int w, int h
          }
          break;
    }
-
-
-   switch (animation_type) {
-
-      case PAGE_FLIP:
-         num_pages = 2;
-         break;
-
-      case TRIPLE_BUFFER:
-         num_pages = 3;
-         break;
-
-      default:
-         num_pages = 1;
-         break;
-   }
-
-   set_color_depth(8);
-#ifdef ALLEGRO_VRAM_SINGLE_SURFACE
-   if (set_gfx_mode(mode, w, h, w, h * num_pages) != 0) {
-#else
-   if (set_gfx_mode(mode, w, h, 0, 0) != 0) {
-#endif
-      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
-      allegro_message("Error setting 8bpp graphics mode\n%s\n",
-                      allegro_error);
-      exit(1);
-   }
-
-   memory_buffer = create_bitmap(SCREEN_W, SCREEN_H);
 }
 
 
@@ -203,8 +216,10 @@ void flip_display(void)
 
 void destroy_display(void)
 {
-   destroy_bitmap(memory_buffer);
-   if (num_pages == 2) {
+   if (num_pages == 1) {
+      destroy_bitmap(memory_buffer);
+   }
+   else if (num_pages == 2) {
       destroy_bitmap(page1);
       destroy_bitmap(page2);
    }
@@ -213,4 +228,7 @@ void destroy_display(void)
       destroy_bitmap(page2);
       destroy_bitmap(page3);
    }
+   else {
+      ASSERT(FALSE);
+   }
 }
diff -u demo/display.c demo/display.c
--- demo/display.c	(local)
+++ demo/display.c	(local)
@@ -5,9 +5,9 @@
 static int current_page = 0;
 static int num_pages;
 static BITMAP *memory_buffer, *back;
-int animation_type;
+ANIMATION_TYPE animation_type;
 
-void init_display(int mode, int w, int h, int type)
+void init_display(int mode, int w, int h, ANIMATION_TYPE type)
 {
    char buf[256];
 
only in patch2:
unchanged:
--- demo/animsel.c	(revision 5677)
+++ demo/animsel.c	(local)
@@ -127,7 +127,7 @@ static int anim_desc_proc(int msg, DIALO
 
 
 /* allows the user to choose an animation type */
-int pick_animation_type(int *type)
+int pick_animation_type(ANIMATION_TYPE *type)
 {
    int ret;
 
@@ -146,5 +146,7 @@ int pick_animation_type(int *type)
    *type = anim_type_dlg[2].d1 + 1;
    max_fps = anim_type_dlg[3].flags & D_SELECTED;
 
+   ASSERT(*type >= DOUBLE_BUFFER && *type <= DIRTY_RECTANGLE);
+
    return (ret == 6) ? -1 : ret;
 }
only in patch2:
unchanged:
--- demo/animsel.h	(revision 5677)
+++ demo/animsel.h	(local)
@@ -2,6 +2,8 @@
 #define ANIMSEL_H_INCLUDED
 
 #include "demo.h"
-int pick_animation_type(int *type);
+#include "display.h"
+
+int pick_animation_type(ANIMATION_TYPE *type);
 
 #endif
only in patch2:
unchanged:
--- demo/demo.c	(revision 5677)
+++ demo/demo.c	(local)
@@ -55,7 +55,7 @@ int main(int argc, char *argv[])
 {
    int c, w, h;
    char buf[256], buf2[256];
-   int type = 0;
+   ANIMATION_TYPE type;
 
    for (c = 1; c < argc; c++) {
       if (stricmp(argv[c], "-cheat") == 0)
only in patch2:
unchanged:
--- demo/display.h	(revision 5677)
+++ demo/display.h	(local)
@@ -4,14 +4,19 @@
 #include "demo.h"
 
 /* different ways to update the screen */
-#define DOUBLE_BUFFER      1
-#define PAGE_FLIP          2
-#define TRIPLE_BUFFER      3
-#define DIRTY_RECTANGLE    4
+typedef enum ANIMATION_TYPE ANIMATION_TYPE;
 
-extern int animation_type;
+enum ANIMATION_TYPE
+{
+   DOUBLE_BUFFER = 1,
+   PAGE_FLIP,
+   TRIPLE_BUFFER,
+   DIRTY_RECTANGLE
+};
 
-void init_display(int mode, int w, int h, int animation_type);
+extern ANIMATION_TYPE animation_type;
+
+void init_display(int mode, int w, int h, ANIMATION_TYPE animation_type);
 void destroy_display(void);
 BITMAP *prepare_display(void);
 void flip_display(void);
only in patch2:
unchanged:
--- demo/game.c	(revision 5677)
+++ demo/game.c	(local)
@@ -263,17 +263,19 @@ static void draw_screen(BITMAP *bmp)
    RLE_SPRITE *spr;
    char *animation_type_str;
 
-   if (animation_type == DOUBLE_BUFFER) {
-      animation_type_str = "double buffered";
-   }
-   else if (animation_type == PAGE_FLIP) {
-      animation_type_str = "page flipping";
-   }
-   else if (animation_type == TRIPLE_BUFFER) {
-      animation_type_str = "triple buffered";
-   }
-   else {
-      animation_type_str = "dirty rectangles";
+   switch (animation_type) {
+      case DOUBLE_BUFFER:
+	 animation_type_str = "double buffered";
+	 break;
+      case PAGE_FLIP:
+	 animation_type_str = "page flipping";
+	 break;
+      case TRIPLE_BUFFER:
+	 animation_type_str = "triple buffered";
+	 break;
+      case DIRTY_RECTANGLE:
+	 animation_type_str = "dirty rectangles";
+	 break;
    }
 
    acquire_bitmap(bmp);


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