FMC
Member #4,431
March 2004
|
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 | | 10 | static int iPage, iMode, iHasSetup = 0, iX, iY, iFatalError, iColours; | 11 | BITMAP *bDbuf, *vPages[3], *bDraw; | 12 | | 13 | int 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 | | 25 | int 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 | | 84 | int 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 | | 111 | int 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 | | 3 | int 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 | } | 23 | END_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
|