I am trying to figure out them memory requriments for my game and I was just wondering how many bytes a BITMAP * pointer is?
IS it the same as a regular pointer.
I am trying to figure out them memory requriments for my game and I was just wondering how many bytes a BITMAP * pointer is?
IS it the same as a regular pointer.
Jeff Paddon
Undergraduate Research Assistant
Physics Department
St. Francis Xavier University
I figured I would post this here.
I am trying to make a game. I have just started and I am getting the movment down first. I tried to double buffer my bitmaps in my game and when I run it the movment is slow sorta unresponsive and sketchy. I dunno why and i can't seem to figure it out. Here is the code below. It compiles fine it is just the animation. by the way I am using Dev C++ and the allegro graphics library.
Code:#include <allegro.h> int main() { allegro_init(); set_gfx_mode(GFX_SAFE, 640, 480, 0, 0); set_color_depth(16); install_keyboard(); BITMAP *amb; BITMAP *map; BITMAP *buffer; map = load_bitmap("map.bmp", NULL); amb = load_bitmap("amb.bmp", NULL); buffer = create_bitmap(640,480); int x=10, y=10; while(!key[KEY_ESC]) { if(key[KEY_LEFT]) { x=x-10; } if(key[KEY_RIGHT]) { x=x+10; } if(key[KEY_UP]) { y=y-10; } if(key[KEY_DOWN]) { y=y+10; } vsync(); draw_sprite(buffer, map, 0, 0); draw_sprite(buffer, amb, x, y); blit(buffer, screen, 0,0,0,0,640,480); } destroy_bitmap(map); destroy_bitmap(amb); allegro_exit(); return 0; } END_OF_MAIN();
A bitmap pointer in allegro is a pointer to a structure called BITMAP.
Using sizeof, BITMAP's size is about 60 bytes (that is if we discount the GFX_VTABLE pointer which is of an unknown size to me) and assume ZERO_SIZE is defined as 0 and not 64 as in almaccfg.hCode:typedef struct BITMAP /* a bitmap structure */ { int w, h; /* width and height in pixels */ int clip; /* flag if clipping is turned on */ int cl, cr, ct, cb; /* clip left, right, top and bottom values */ GFX_VTABLE *vtable; /* drawing functions */ void *write_bank; /* C func on some machines, asm on i386 */ void *read_bank; /* C func on some machines, asm on i386 */ void *dat; /* the memory we allocated for the bitmap */ unsigned long id; /* for identifying sub-bitmaps */ void *extra; /* points to a structure with more info */ int x_ofs; /* horizontal offset (for sub-bitmaps) */ int y_ofs; /* vertical offset (for sub-bitmaps) */ int seg; /* bitmap segment */ unsigned char *line[ZERO_SIZE]; } BITMAP;
The other version of BITMAP which contains members such as bmBits and bmHeight is 64 bytes.
I understand then thanx
Jeff Paddon
Undergraduate Research Assistant
Physics Department
St. Francis Xavier University
You can't just use sizeof()?
gcc -lalleg
http://www.ciusa.net/~jrgrant/
I don't know. I don't use vsync().Code:#include <allegro.h> int main() { allegro_init(); set_gfx_mode(GFX_SAFE, 640, 480, 0, 0); set_color_depth(16); install_keyboard(); BITMAP *amb; BITMAP *map; BITMAP *buffer; map = load_bitmap("map.bmp", NULL); amb = load_bitmap("amb.bmp", NULL); buffer = create_bitmap(640,480); int x=10, y=10; while(!key[KEY_ESC]) { if(key[KEY_LEFT]) { x-=10; } if(key[KEY_RIGHT]) { x+=10; } if(key[KEY_UP]) { y-=10; } if(key[KEY_DOWN]) { y+=10; } masked_blit (map, buffer, 0, 0, 0, 0, map->w, map->h); masked_blit (amb, buffer, 0, 0, x, y, amb->w, amb->h); blit (buffer, screen, 0, 0, 0, 0, 640, 480); } destroy_bitmap(map); destroy_bitmap(amb); allegro_exit(); return 0; } END_OF_MAIN();
I tried that but the animation is still terrible. I dunno I don't think it is my computer though. cause when i used a bigger bitmap before it worked. Oh I dunnno
Jeff Paddon
Undergraduate Research Assistant
Physics Department
St. Francis Xavier University
I'd imagine that if you do that it should work perfectly fine. but one thing you have to remember is that you are drawing the map and amb over and over again no matter if a key is pressed or not. what you should do is arrange so that you aren't redrawing everything unless need be (i.e. a valid key is pressed)Code:#include <allegro.h> BITMAP *amb; //keep your bitmaps up here because you'll eventually need to use them in other functions as well and loading them in main() won't allow you to do that BITMAP *map; BITMAP *buffer; int main() { allegro_init(); set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0); //this is fullscreen autodetect instead of loading into safe set_color_depth(32); //this will be much better but it may not work on a few computers install_keyboard(); map = load_bitmap("map.bmp", NULL); amb = load_bitmap("amb.bmp", NULL); buffer = create_bitmap(SCREEN_W, SCREEN_H); //this is going to be 640x480 int x=10, y=10; while(!key[KEY_ESC]) { if(key[KEY_LEFT]) { x-=10; } if(key[KEY_RIGHT]) { x+=10; } if(key[KEY_UP]) { y-=10; } if(key[KEY_DOWN]) { y+=10; } masked_blit (map, buffer, 0, 0, 0, 0, SCREEN_W, SCREEN_H); //do you have magic pink in bitmap *map? if you don't then you should just use normal blit draw_sprite(buffer, amb, x, y); //i'm guessing here but draw_sprite() might be more appropriate for you to use here blit (buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); } destroy_bitmap(map); destroy_bitmap(amb); allegro_exit(); return 0; } END_OF_MAIN();
I don't really like to use draw_sprite(), I've found that blit() works faster, plus draw_sprite() is limited to 8 bit if I remember right
and using 32 bit is S-L-O-W unless you have a good vid card, then it won't be too bad. I usually get over double the FPS when I use 16 bit. That isn't really saying much, since games run faster in software mode than hardware on my computer because of the shiznitty card I got.
And if you are making an actual game, do not load each bitmap one by one. Put them into datafile(s). Trust me, saves a lot of headaches later on. Plus it keeps normal people out of your graphics. It is quite simple to hack (if you dig in the allegro datafile help file it says how the files are setup and how to hack some stuff). It also compresses the files pretty well if you choose to compress them. It compresses about 25%. Don't worry about decompressing, allegro handles that automatically when you load a datafile. Very quickly as well.
I dunno how to make a datafile and I used 16 bit???
You can try doing some page flipping. I can't get this to work on one of my computers with windows 98 though. I've tried everyt hing.
Also don't use this code, it's pretty bad and has almost no
error checking. You would also probably want to throw out % 2 stuft since that doesn't really generate a random number.
Also map.pcx is a 640x480 the circles are
about 45x45.
I personaly like the SDL better because there's less namespace clashes and seems to handle windows better.
Speedwise I think there about the same.
Code:#include <allegro.h> #include <time.h> #define NUM_CIRCLE 8 typedef struct Sprite { int x; int y; int xvel; int yvel; int bound_w; int bound_h; int bound_xoffset; int bound_yoffset; BITMAP* surf; int w; int h; } Sprite; Sprite circle_sprite; Sprite circle_list[NUM_CIRCLE]; BITMAP* back_surface; BITMAP* primary; BITMAP* map_bmp; void init_game(); void render_graphics(); void finish_game(); void flip(); void create_circle(Sprite* cp, char* filename); void update_circle(Sprite* cp); int collision(Sprite* s1, Sprite* s2); void handle_collision(Sprite* s1, Sprite* s2); void do_collision(); int main() { int game_over; int i; srand(time(NULL)); allegro_init(); /* you should set the color depth before you set the video mode */ set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0); install_keyboard(); init_game(); game_over = 0; while(!game_over) { poll_keyboard(); if (key[KEY_ESC]) game_over = 1; if (key[KEY_RIGHT]) circle_sprite.xvel = 5; if (key[KEY_LEFT]) circle_sprite.xvel = -5; if (key[KEY_UP]) circle_sprite.yvel = -5; if (key[KEY_DOWN]) circle_sprite.yvel = 5; update_circle(&circle_sprite); for (i = 0; i < NUM_CIRCLE; ++i) update_circle(&circle_list[i]); do_collision(); render_graphics(); } finish_game(); return 0; } END_OF_MAIN(); void init_game() { BITMAP* surf; int i; primary = create_video_bitmap(screen->w, screen->h); if (primary == NULL) exit(EXIT_FAILURE); back_surface = create_video_bitmap(screen->w, screen->h); if (back_surface == NULL) exit(EXIT_FAILURE); surf = load_bitmap("map.pcx", NULL); if (surf == NULL) exit(EXIT_FAILURE); map_bmp = create_video_bitmap(surf->w, surf->h); if (map_bmp == NULL) exit(EXIT_FAILURE); blit(surf, map_bmp, 0, 0, 0, 0, surf->w, surf->h); map_bmp = surf; create_circle(&circle_sprite, "circle.pcx"); for (i = 0; i < NUM_CIRCLE; ++i) create_circle(&circle_list[i], "small_circle.pcx"); } void create_circle(Sprite* cp, char* filename) { BITMAP* surf; cp->x = rand() % screen->w; cp->y = rand() % screen->h; if (rand() % 2) cp->yvel = rand() % 5 + 1; else cp->yvel = -rand() % 5 - 1; if (rand() % 2) cp->xvel = rand() % 5 + 1; else cp->yvel = -rand() % 5 - 1; surf = load_bitmap(filename, NULL); if (surf == NULL) exit(EXIT_FAILURE); cp->surf = create_video_bitmap(surf->w, surf->h); if (cp->surf == NULL) exit(EXIT_FAILURE); blit(surf, cp->surf, 0, 0, 0, 0, surf->w, surf->h); destroy_bitmap(surf); cp->w = cp->surf->w; cp->h = cp->surf->h; cp->bound_w = int(cp->w * .80); cp->bound_h = int(cp->h * .80); cp->bound_xoffset = (cp->w - cp->bound_w)/2; cp->bound_yoffset = (cp->h - cp->bound_h)/2; } void render_graphics() { int i; Sprite* sp; acquire_bitmap(screen); blit(map_bmp, back_surface, 0, 0, 0, 0, map_bmp->w, map_bmp->h); for (i = 0; i < NUM_CIRCLE; ++i) { sp = &circle_list[i]; draw_sprite(back_surface, sp->surf, sp->x, sp->y); } draw_sprite(back_surface, circle_sprite.surf, circle_sprite.x, circle_sprite.y); release_bitmap(screen); flip(); } void update_circle(Sprite* cp) { int width; int height; width = cp->surf->w; height = cp->surf->h; cp->x += cp->xvel; cp->y += cp->yvel; if (cp->x < 0) { cp->x = 0; cp->xvel = 3; } if (cp->x + width >= screen->w) { cp->x = screen->w - width - 1; cp->xvel = -3; } if (cp->y < 0) { cp->y = 0; cp->yvel = 3; } if (cp->y + height > screen->h) { cp->y = screen->h - height - 1; cp->yvel = -3; } } void finish_game() { int i; destroy_bitmap(primary); destroy_bitmap(back_surface); destroy_bitmap(map_bmp); destroy_bitmap(circle_sprite.surf); for (i = 0; i < NUM_CIRCLE; ++i) destroy_bitmap(circle_list[i]); } void flip() { BITMAP* tmp; show_video_bitmap(back_surface); tmp = primary; primary = back_surface; back_surface = tmp; } void do_collision() { int i, j; for (i = 0; i < NUM_CIRCLE; ++i) { if (collision(&circle_sprite, &circle_list[i])) handle_collision(&circle_sprite, &circle_list[i]); } for (i = 0; i < NUM_CIRCLE; ++i) for (j = i; j < NUM_CIRCLE; ++j) if (i != j && collision(&circle_list[i], &circle_list[j])) handle_collision(&circle_list[i], &circle_list[j]); } int collision(Sprite* s1, Sprite* s2) { int left1, right1; int top1, bottom1; int left2, right2; int top2, bottom2; left1 = s1->x + s1->bound_xoffset; right1 = s1->x + s1->bound_w; top1 = s1->y + s1->bound_yoffset; bottom1 = s1->y + s1->bound_h; left2 = s2->x + s2->bound_xoffset; right2 = s2->x + s2->bound_w; top2 = s2->y + s2->bound_yoffset; bottom2 = s2->y + s2->bound_h; if (left1 > right2 || right1 < left2) return 0; if (top1 > bottom2 || bottom1 < top2) return 0; return 1; } void handle_collision(Sprite* s1, Sprite* s2) { int vx1, vy1, vx2, vy2; vx1 = s1->xvel; vy1 = s1->yvel; vx2 = s2->xvel; vy2 = s2->yvel; s1->x -= vx1; s1->y -= vy1; s2->xvel -= vx2; s2->yvel -= vy2; s1->xvel = vx2; s1->yvel = vy2; s2->xvel = vx1; s2->yvel = vy1; }
datafiles are simple. If you go into your tools folder (it's under the allegro folder) you'll find a program called grabber. Run it and you'll come up to a GUI environment. Go into the help and it'll explain how to use the grabber program. Once you build your datafile you can edit it again using the grabber program. When you make the datafile it should also make a header file for the datafile. Include this header file with every source file that uses the datafile.
To load the program, you need to make a pointer to the datafile. Do this by typing this out, preferrably make it global so all your source files can use it without having to reload it over and over.
DATAFILE *PointerNameGoesHere;
Then in your initialization function, or in main() or where else you want to load it, you use this:
PointerNameGoesHere = load_datafile("datafilename.dat");
To use a image from the datafile, you use this (I am using blit to demonstrate, it'll work with the rest of the drawing functions as well)
blit(PointerNameGoesHere[NameOfTheImage].dat,0,0,5,5,20,20);
unless you are using C++, then you'll have to typecast like this:
blit((BITMAP*)PointerNameGoesHere[NameOfTheImage].dat,0,0,5,5,20,20);
Of course datafiles can hold more than just graphics. They can contain sound files, fonts, cursors, you name it. Just use the same basic way the blitting does, but typecast it for the same type (like for sound files use SAMPLE instead of BITMAP)
Sorry, I am terrible at explaining things.
I think u did a pretty good job
Jeff Paddon
Undergraduate Research Assistant
Physics Department
St. Francis Xavier University
Do you understand it fully? If there is anything you don't, just ask.
Oh, and something to help you a bit in finding the RAM required. If you are using Windows XP, press CTRL+ALT+DELETE, and it gives you an approximate reading of how much RAM it is taking up (it should be under the proccesses tab. Be warned, after pressing CTRL+ALT+DELETE you can only close the program with hitting end task, because you lose control of the program (it's an allegro problem that is going to be fixed in version 5). Remember, this isn't very accurate, but it'll give you an idea of how much it takes.
a bitmap pointer is 4 bytes, like any other pointer. but i assume you mean the bitmap struct that the pointer points to. according to my allegro 3.0 docs, outside ofOriginally posted by kas2002
I am trying to figure out them memory requriments for my game and I was just wondering how many bytes a BITMAP * pointer is?
IS it the same as a regular pointer.
you should not refer to anything in the BITMAP struct, as the rest of the info is not guaranteed to stay the same over time. but for the curious here's the allegro 3.0 full BITMAP structCode:typedef struct BITMAP { int w, h; - size of the bitmap in pixels int clip; - non-zero if clipping is turned on int cl, cr, ct, cb; - clip rectangle left, right, top, and bottom int seg; - segment for use with the line pointers unsigned char *line[]; - pointers to the start of each line } BITMAP;
which is, obviously, 60 bytes (just a bunch of ints and pointers, which are all 4 bytes each) not including the line data, which varies by bitmap. however you really shouldn't be concerned about the size of the bitmap struct, but rather the size of the data that the dat pointer points to. this is equal to W x H x B where width is the width of the bitmap, H is the height, and B is the bytes per pixel (8bpp = 1Bpp, 15bpp = 16bpp = 2Bpp, etc etc). if you plug in a few numbers you can see that all but the smallest bitmaps will have much larger data than anything else.Code:typedef struct BITMAP /* a bitmap structure */ { int w, h; /* width and height in pixels */ int clip; /* flag if clipping is turned on */ int cl, cr, ct, cb; /* clip left, right, top and bottom values */ GFX_VTABLE *vtable; /* drawing functions */ void (*write_bank)(); /* write bank selector, see bank.s */ void (*read_bank)(); /* read bank selector, see bank.s */ void *dat; /* the memory we allocated for the bitmap */ int bitmap_id; /* for identifying sub-bitmaps */ void *extra; /* points to a structure with more info */ int line_ofs; /* line offset (for screen sub-bitmaps) */ int seg; /* bitmap segment */ unsigned char *line[0]; /* pointers to the start of each line */ } BITMAP;
hello, internet!