
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <stdio.h>
#include <stdlib.h>

#define DRAW_REPEATS 1000
#define DISPLAY_W 320
#define DISPLAY_H 240

void draw_putpixel(ALLEGRO_BITMAP * screen, int index) {
  unsigned int x, y;
  ALLEGRO_LOCKED_REGION * lr = 
  al_lock_bitmap(screen, al_get_bitmap_format(screen), ALLEGRO_LOCK_WRITEONLY);
  for(y = 0; y < DISPLAY_H; y++) {
    for (x = 0; x < DISPLAY_W; x++) {
      ALLEGRO_COLOR c = al_map_rgb(x % 256, y % 256, index % 256);
      al_put_pixel(x, y, c);
    }
  }
  al_unlock_bitmap(screen);
  al_flip_display();
}


void draw_direct(ALLEGRO_BITMAP * screen, int index) {
  int x, y;
  unsigned char * row;
  unsigned int * pixel;
  ALLEGRO_LOCKED_REGION * lr = 
  al_lock_bitmap(screen, al_get_bitmap_format(screen), ALLEGRO_LOCK_WRITEONLY);
  for(y = 0; y < DISPLAY_H; y++) {
    row = (((unsigned char *)lr->data) + y * lr->pitch);
    for (x = 0; x < DISPLAY_W; x++) {
      pixel    = (unsigned int*)(row + x * lr->pixel_size);
      (*pixel) = (index%256) + ((y%256) << 8) + ((x%256) << 16);
       /* + (y%256) << 8 + (index%256) << 16 */
    }
  }
  al_unlock_bitmap(screen);
  al_flip_display();
}


typedef void draw_callback(ALLEGRO_BITMAP *, int);

void test_draw(int repeats, ALLEGRO_BITMAP * screen, draw_callback * callback, char * name) {
  int index;
  double start, delta, stop, fps;
  start = al_get_time();
  for(index = 0; index < repeats; index++) {
    callback(screen, index);
  }
  stop = al_get_time();
  delta = stop - start;
  fps = ((double)repeats) / delta;
  printf("Drew %d frames in %f seconds or %f fps using %s\n", repeats, delta, fps, name);
}

int main(int argc, char ** argv) {
  ALLEGRO_DISPLAY * display = NULL;
  ALLEGRO_BITMAP  * screen  = NULL;
  ALLEGRO_BITMAP  * buffer  = NULL;
  
  
  if (!al_init()) { 
    fprintf(stderr, "Failed to initialize allegro!\n");
    return 1;
  }
  
  display = al_create_display(DISPLAY_W, DISPLAY_H);
  if(!display) {
    fprintf(stderr, "Failed to create display!\n");
    return 1;
  }
  
  screen = al_get_backbuffer(display);
  test_draw(500, screen, draw_putpixel, "al_put_pixel and locking");
  test_draw(500, screen, draw_direct, "direct drawing and locking");
  
  al_destroy_display(display);
}

