Thread: Quick Allegro Question

  1. #1
    Registered User
    Join Date
    May 2002
    Posts
    208

    Quick Allegro Question

    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

  2. #2
    Registered User
    Join Date
    May 2002
    Posts
    208

    Another Allegro Question

    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();

  3. #3
    Registered User rmullen3's Avatar
    Join Date
    Nov 2001
    Posts
    330
    A bitmap pointer in allegro is a pointer to a structure called BITMAP.

    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;             /* 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;
    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.h

    The other version of BITMAP which contains members such as bmBits and bmHeight is 64 bytes.

  4. #4
    Registered User
    Join Date
    May 2002
    Posts
    208

    ok

    I understand then thanx
    Jeff Paddon
    Undergraduate Research Assistant
    Physics Department
    St. Francis Xavier University

  5. #5
    Registered User JoshG's Avatar
    Join Date
    Mar 2002
    Posts
    326
    You can't just use sizeof()?

  6. #6
    Registered User rmullen3's Avatar
    Join Date
    Nov 2001
    Posts
    330
    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 don't know. I don't use vsync().

  7. #7
    Registered User
    Join Date
    May 2002
    Posts
    208

    Thanx

    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

  8. #8
    Rambling Man
    Join Date
    Jan 2002
    Posts
    1,050
    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'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)

  9. #9
    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.

  10. #10
    Registered User
    Join Date
    May 2002
    Posts
    208

    umm...

    I dunno how to make a datafile and I used 16 bit???

  11. #11
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    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;
    }

  12. #12
    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.

  13. #13
    Registered User
    Join Date
    May 2002
    Posts
    208

    Thanx

    I think u did a pretty good job
    Jeff Paddon
    Undergraduate Research Assistant
    Physics Department
    St. Francis Xavier University

  14. #14
    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.

  15. #15
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946

    Re: Quick Allegro Question

    Originally 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.
    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 of
    Code:
    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;
    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 struct
    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;
    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.
    hello, internet!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. * quick question *
    By SavesTheDay in forum C Programming
    Replies: 3
    Last Post: 03-27-2002, 06:58 PM
  2. just a reaaaaaaly quick question plz help
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 03-21-2002, 11:39 AM
  3. ALLEGRO Question
    By Unregistered in forum Game Programming
    Replies: 10
    Last Post: 10-22-2001, 01:27 PM
  4. ALLEGRO Question
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 09-14-2001, 11:06 AM
  5. Quick question: exit();
    By Cheeze-It in forum C Programming
    Replies: 6
    Last Post: 08-15-2001, 05:46 PM