Show ex3buf.c syntax highlighted
/*
* Example program for the Allegro library, by Shawn Hargreaves.
*
* This program demonstrates the use of triple buffering and vertical
* retrace interrupt simulation.
*/
#include "allegro.h"
#define NUM_SHAPES 16
typedef struct SHAPE
{
int color; /* color of the shape */
fixed x, y; /* centre of the shape */
fixed dir1, dir2, dir3; /* directions to the three corners */
fixed dist1, dist2, dist3; /* distances to the three corners */
fixed xc, yc, ac; /* position and angle change values */
} SHAPE;
SHAPE shapes[NUM_SHAPES];
/* randomly initialises a shape structure */
void init_shape(SHAPE *shape)
{
shape->color = 1+(rand()%15);
/* randomly position the corners */
shape->dir1 = al_int_to_fix(rand()%256);
shape->dir2 = al_int_to_fix(rand()%256);
shape->dir3 = al_int_to_fix(rand()%256);
shape->dist1 = al_int_to_fix(rand()%64);
shape->dist2 = al_int_to_fix(rand()%64);
shape->dist3 = al_int_to_fix(rand()%64);
/* rand centre position and movement speed/direction */
shape->x = al_int_to_fix(rand() % AL_SCREEN_W);
shape->y = al_int_to_fix(rand() % AL_SCREEN_H);
shape->ac = al_int_to_fix((rand()%9)-4);
shape->xc = al_int_to_fix((rand()%7)-2);
shape->yc = al_int_to_fix((rand()%7)-2);
}
/* updates the position of a shape structure */
void move_shape(SHAPE *shape)
{
shape->x += shape->xc;
shape->y += shape->yc;
shape->dir1 += shape->ac;
shape->dir2 += shape->ac;
shape->dir3 += shape->ac;
if (((shape->x <= 0) && (shape->xc < 0)) ||
((shape->x >= al_int_to_fix(AL_SCREEN_W)) && (shape->xc > 0))) {
shape->xc = -shape->xc;
shape->ac = al_int_to_fix((rand()%9)-4);
}
if (((shape->y <= 0) && (shape->yc < 0)) ||
((shape->y >= al_int_to_fix(AL_SCREEN_H)) && (shape->yc > 0))) {
shape->yc = -shape->yc;
shape->ac = al_int_to_fix((rand()%9)-4);
}
}
/* draws a frame of the animation */
void draw(AL_BITMAP *b)
{
int c;
al_acquire_bitmap(b);
al_clear_bitmap(b);
for (c=0; c<NUM_SHAPES; c++) {
al_draw_triangle(b,
al_fix_to_int(shapes[c].x+al_fix_mul(shapes[c].dist1, al_fix_cos(shapes[c].dir1))),
al_fix_to_int(shapes[c].y+al_fix_mul(shapes[c].dist1, al_fix_sin(shapes[c].dir1))),
al_fix_to_int(shapes[c].x+al_fix_mul(shapes[c].dist2, al_fix_cos(shapes[c].dir2))),
al_fix_to_int(shapes[c].y+al_fix_mul(shapes[c].dist2, al_fix_sin(shapes[c].dir2))),
al_fix_to_int(shapes[c].x+al_fix_mul(shapes[c].dist3, al_fix_cos(shapes[c].dir3))),
al_fix_to_int(shapes[c].y+al_fix_mul(shapes[c].dist3, al_fix_sin(shapes[c].dir3))),
shapes[c].color);
move_shape(shapes+c);
}
if (al_retrace_proc)
al_put_text(b, al_font_8x8, "Triple buffering with retrace sync", 0, 0, 255);
else
al_put_text(b, al_font_8x8, "Triple buffering", 0, 0, 255);
al_release_bitmap(b);
}
int fade_color = 63;
/* vertical retrace callback function for doing the palette fade */
void fade(void)
{
int c = (fade_color < 64) ? fade_color : 127 - fade_color;
AL_RGB rgb;
rgb.r = rgb.g = rgb.b = c;
al_set_color_no_vsync(0, &rgb);
fade_color++;
if (fade_color >= 128)
fade_color = 0;
}
AL_END_OF_FUNCTION(fade);
/* main animation control loop */
void triple_buffer(AL_BITMAP *page1, AL_BITMAP *page2, AL_BITMAP *page3)
{
AL_BITMAP *active_page = page1;
int page = 0;
do {
/* draw a frame */
draw(active_page);
/* make sure the last flip request has actually happened */
do {
} while (al_poll_scroll());
/* post a request to display the page we just drew */
al_request_video_bitmap(active_page);
/* update counters to point to the next page */
switch (page) {
case 0: page = 1; active_page = page2; break;
case 1: page = 2; active_page = page3; break;
case 2: page = 0; active_page = page1; break;
}
} while (!al_key_pressed());
al_clear_keybuf();
}
int main()
{
AL_BITMAP *page1, *page2, *page3;
int c;
allegro_init();
al_install_timer();
al_install_keyboard();
al_install_mouse();
/* see comments in exflip.c */
if (al_set_gfx_mode(AL_GFX_AUTODETECT, 320, 240, 0, 720) != 0) {
if (al_set_gfx_mode(AL_GFX_SAFE, 320, 240, 0, 0) != 0) {
al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
al_show_message("Unable to set any graphic mode\n%s\n", al_error);
return 1;
}
}
al_set_palette(al_desktop_palette);
/* if triple buffering isn't available, try to enable it */
if (!(al_gfx_capabilities & AL_GFX_CAN_TRIPLE_BUFFER))
al_enable_triple_buffer();
/* if that didn't work, give up */
if (!(al_gfx_capabilities & AL_GFX_CAN_TRIPLE_BUFFER)) {
al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
#ifdef ALLEGRO_DOS
al_show_message("Triple buffering not available, sorry\n\nTry again in clean DOS mode (not under Windows)\n");
#else
al_show_message("Triple buffering not available, sorry\n");
#endif
return 1;
}
/* allocate three sub bitmaps to access pages of the al_screen */
page1 = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
page2 = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
page3 = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
if ((!page1) || (!page2) || (!page3)) {
al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
al_show_message("Unable to create three video memory pages\n");
return 1;
}
/* initialise the shapes */
for (c=0; c<NUM_SHAPES; c++)
init_shape(shapes+c);
al_text_mode(-1);
LOCK_VARIABLE(fade_color);
LOCK_FUNCTION(fade);
if (al_timer_can_simulate_retrace()) {
al_timer_simulate_retrace(TRUE);
al_retrace_proc = fade;
}
else {
al_show_alert("Retrace sync is not available in",
"this environment, so you won't get",
"the funky smooth palette fading",
"Damn, that's a shame", NULL, 13, 0);
}
triple_buffer(page1, page2, page3);
al_destroy_bitmap(page1);
al_destroy_bitmap(page2);
al_destroy_bitmap(page3);
al_retrace_proc = NULL;
return 0;
}
AL_END_OF_MAIN();
See more files for this project here