Allegro.cc - Online Community

Allegro.cc Forums » The Depot » Screen Update framework (criticism needed)

This thread is locked; no one can reply to it. rss feed Print
Screen Update framework (criticism needed)
FMC
Member #4,431
March 2004
avatar

So, im working on a general purpose framework for 2d allegro games; right know i've got the screen update part ready.

We have gfx.c:

1/*
2 Name: gfx.c
3 Copyright: 2005 FMC
4 Author: Fabio Maria Carlucci
5 Date: 03/12/05 15.23
6 Description: graphical routines related (update, gfx loading, ...)
7*/
8#include "game_includes.h"
9 
10static int iPage, iMode, iHasSetup = 0, iX, iY, iFatalError, iColours;
11BITMAP *bDbuf, *vPages[3], *bDraw;
12 
13int gfx_setup(int mode, int x, int y, int cols){
14 iPage = 0;
15 iMode = mode;
16 iHasSetup = 1;
17 iX = x;
18 iY = y;
19 iFatalError = 0;
20 iColours = cols;
21
22 return GM_OK;
23 }
24
25int gfx_start(){
26 if(!iHasSetup){
27 P_ERROR("You must first setup for gfx!");
28 return GM_FAIL;
29 }
30
31 int iOk;
32 set_color_depth(iColours);
33 if(iMode & S_FULL)
34 iOk = set_gfx_mode(GFX_AUTODETECT, iX, iY, 0, 0);
35 else
36 iOk = set_gfx_mode(GFX_AUTODETECT_WINDOWED, iX, iY, 0, 0);
37
38 if(iOk){
39 iMode = 0;
40 P_ERROR("\nCan't init selected video mode");
41 iFatalError = 1; //fatal error triggered
42 return GM_FAIL;
43 }
44
45 bDraw = screen; //by default the screen is the "drawable" surface
46
47 //if triple buffering is enabled
48 if(iMode & TRIPLE_BUF){
49 /* triple buffering setup */
50 if (!(gfx_capabilities & GFX_CAN_TRIPLE_BUFFER))
51 enable_triple_buffer();
52 if (!(gfx_capabilities & GFX_CAN_TRIPLE_BUFFER)) {
53 P_ERROR("\nCan't do triple buffering... will try page flipping");
54 iMode -= TRIPLE_BUF;
55 iMode += PAGE_FLIP;
56 }
57 else {
58 vPages[0] = create_video_bitmap(iX, iY);
59 vPages[1] = create_video_bitmap(iX, iY);
60 vPages[2] = create_video_bitmap(iX, iY);
61 }
62 bDraw = vPages[iPage];
63 }
64 //if page flipping is enabled
65 if(iMode & PAGE_FLIP){
66 vPages[0] = create_video_bitmap(iX, iY);
67 vPages[1] = create_video_bitmap(iX, iY);
68 bDraw = vPages[iPage];
69 }
70 //if double buffering is enabled
71 if(iMode & DOUBLE_BUF){
72 bDbuf = create_bitmap(iX, iY);
73 if(!bDbuf){ //if it can't init the double buffer say so and try a workaround
74 iMode -= DOUBLE_BUF;
75 P_ERROR("\nCan't create double buffer!");
76 }
77 else
78 bDraw = bDbuf; //double buffer can be the drawable bitmap even if page flipping or triple buf are enabled
79 }
80
81 return GM_OK;
82 }
83
84int gfx_update(){
85 if(iFatalError)return GM_FAIL;
86
87 if(iMode & TRIPLE_BUF){
88 if(iMode & DOUBLE_BUF)blit(bDbuf, vPages[iPage], 0, 0, 0, 0, screen->w, screen->h);
89
90 do {
91 } while (poll_scroll());
92 
93 request_video_bitmap(vPages[iPage]);
94 iPage = (iPage+1)%3;
95 if(!(iMode & DOUBLE_BUF))bDraw = vPages[iPage];
96 }
97 else if(iMode & PAGE_FLIP){
98 if(iMode & DOUBLE_BUF)blit(bDbuf, vPages[iPage], 0, 0, 0, 0, screen->w, screen->h);
99
100 show_video_bitmap(vPages[iPage]);
101 iPage = 1-iPage;
102 if(!(iMode & DOUBLE_BUF))bDraw = vPages[iPage];
103 }
104 else if(iMode & DOUBLE_BUF){
105 blit(bDbuf, screen, 0, 0, 0, 0, screen->w, screen->h);
106 }
107
108 return GM_OK;
109 }
110
111int gfx_end(){
112 if(iFatalError)return GM_FAIL;
113
114 if(iMode & DOUBLE_BUF)destroy_bitmap(bDbuf);
115
116 if(iMode & PAGE_FLIP){
117 destroy_bitmap(vPages[0]);
118 destroy_bitmap(vPages[1]);
119 }
120 else if(iMode & TRIPLE_BUF){
121 destroy_bitmap(vPages[0]);
122 destroy_bitmap(vPages[1]);
123 destroy_bitmap(vPages[2]);
124 }
125
126
127 return GM_OK;
128 }

gfx.h:

//gfx.h

extern BITMAP *bDraw;

int gfx_setup(int mode, int x, int y, int cols);    
int gfx_start();
int gfx_update();
int gfx_end();

game_includes.h (this is game specific, now i just show the most simple case)

//game related includes

#include <allegro.h>

#include "global_defs.h"
#include "gfx.h"

global_defs.h

//global definitions go here

#define DOUBLE_BUF  1
#define TRIPLE_BUF  2
#define PAGE_FLIP   4

#define S_WINDOWED  8
#define S_FULL     16

//function returns
#define GM_OK    0
#define GM_FAIL -1

---------------
As you can see there are 4 functions to call:
int gfx_setup(int mode, int x, int y, int cols);
This has to be called as a first thing, x,y set the resolution, cols the color depth, mode specifies if windowed or not and which screen update mode to use, parameters are a mix of (DOUBLE_BUF, TRIPLE_BUF, PAGE_FLIP, S_WINDOWED, S_FULL)

int gfx_start();
has to be called to actually start the graphic mode

int gfx_update();
must be called every game cycle

int gfx_end();
must be called before exiting, frees memory

The use is very simple, you do all the drawing to bDraw (regardless of the update mode you selected) and then just call gfx_update();

A very simple program(with no error checking) that moves a rectangle across the screen would look like:

1#include "game_includes.h"
2 
3int main(){
4 allegro_init();
5 //
6 gfx_setup(PAGE_FLIP + DOUBLE_BUF + S_FULL, 640, 480, 16);
7 gfx_start();
8
9 install_keyboard();
10 int k= 0;
11 while(!key[KEY_ESC]){
12 clear_to_color(bDraw, makecol(10,10,10));
13 rectfill(bDraw, 40 + k/2, 40, 120 + k/2, 120, makecol(190,0,0));
14 k = (k+1)%800;
15
16 gfx_update();
17 }
18 gfx_end();
19
20
21 return 0;
22 }
23END_OF_MAIN()

As you can see you can combine Page flipping with double buffering, usefull if you need to use some transparencies in your game (so do not have to read from video memory)

It should work correctly and anyone can use but what i'd like are some critics, mainly about things that should/could be done in a cleaner and/or more efficient way. Thanks.

[EDIT]Attached a working example with source and binary (4.2 dll needed)

[FMC Studios] - [Caries Field] - [Ctris] - [Pman] - [Chess for allegroites]
Written laws are like spiders' webs, and will, like them, only entangle and hold the poor and weak, while the rich and powerful will easily break through them. -Anacharsis
Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails. Explore. Dream. Discover. -Mark Twain

Evert
Member #794
November 2000
avatar

Looks ok, I guess, but have you looked at Chris Barry's screen update mechanism (which is Allegro 4.3's screen update mechanism, basically)?

FMC
Member #4,431
March 2004
avatar

I knew he had done something similar but i wanted to make something on my own, so i didn't check his code :)

[FMC Studios] - [Caries Field] - [Ctris] - [Pman] - [Chess for allegroites]
Written laws are like spiders' webs, and will, like them, only entangle and hold the poor and weak, while the rich and powerful will easily break through them. -Anacharsis
Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails. Explore. Dream. Discover. -Mark Twain

Marco Radaelli
Member #3,028
December 2002
avatar

It's ok, altough it's a bit limited, but I guess you just started working on it.
So far I have two things to say:

  • gfx_setup() doesn't do enough checks, passing, i.e., 0 as second argument made the program crash

  • I think your framework should hide calls like allegro_init() and install_keyboard()

That's it :)

Go to: