allegro5 icon indicating copy to clipboard operation
allegro5 copied to clipboard

something broken in al_lock_bitmap

Open rmbeer opened this issue 2 years ago • 2 comments

This's the source code with undefined behavior:

` /* This example displays a picture on the screen, with support for

  • command-line parameters, multi-screen, screen-orientation and

  • zooming. */ #include <stdio.h> #include <stdlib.h> #include <allegro5/allegro.h> #include <allegro5/allegro_image.h>

    ALLEGRO_DISPLAY display; ALLEGRO_BITMAPgzz;

void Renderx(){ static int szz=0; al_clear_to_color(al_map_rgb(0,0,0)); int px,py; charzdat,p; ALLEGRO_LOCKED_REGIONzzz; zzz=al_lock_bitmap(gzz,ALLEGRO_LOCK_WRITEONLY,ALLEGRO_PIXEL_FORMAT_RGBA_8888); //zzz=al_lock_bitmap(gzz,ALLEGRO_LOCK_WRITEONLY,ALLEGRO_PIXEL_FORMAT_RGB_888); if(!zzz){printf("fallofallo\n");return -1;} zdat=(char*)zzz->data;p=0; //printf("%d / %d\n",zzz->pixel_size,zzz->pitch); for(px=0;px<240;px++){p=0; //for(px=0;px<480;px++){p=0; //for(py=0;py<320;py++){ for(py=0;py<szz;py++){ //zdat[p]=(px+py)&255;zdat[p+1]=0;zdat[p+2]=0;zdat[p+3]=0;p+=4; //dont show nothing zdat[p]=0;zdat[p+1]=(px+py)&255;zdat[p+2]=0;zdat[p+3]=255;p+=4; //show gradient white //zdat[p]=0;zdat[p+1]=0;zdat[p+2]=(px+py)&255;zdat[p+3]=0;p+=4; //show gradient purple //zdat[p]=0;zdat[p+1]=0;zdat[p+2]=0;zdat[p+3]=(px+py)&255;p+=4; //show gradient black }zdat+=zzz->pitch; }szz++;if(szz>640)szz=640; al_unlock_bitmap(gzz); al_set_target_backbuffer(display); }

int main(int argc, char **argv) { const char *filename; ALLEGRO_BITMAP *bitmap; ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; bool redraw = true; double zoom = 1; double t0; double t1;

  if (!al_init()) {
     printf("Could not init Allegro.\n");
     return -1;
  }

     
  /* The second parameter to the process can optionally specify what 
   * adapter to use.
   */
  if (argc > 2) {
     al_set_new_display_adapter(atoi(argv[2]));
  }

  /* Allegro requires installing drivers for all input devices before
   * they can be used.
   */
  al_install_mouse();
  al_install_keyboard();

  /* Initialize the image addon. Requires the allegro_image addon
   * library.
   */
  al_init_image_addon();


  // Create a new display that we can render the image to.
  display = al_create_display(640, 480);
  if (!display) {
     printf("Error creating display\n");
     return -2;
  }
  
  al_set_window_title(display, "Pruebas");
  

  // Create a timer that fires 30 times a second.
  timer = al_create_timer(1.0 / 15); 
  queue = al_create_event_queue();
  al_register_event_source(queue, al_get_keyboard_event_source()); 
  al_register_event_source(queue, al_get_display_event_source(display));
  al_register_event_source(queue, al_get_timer_event_source(timer));
  al_start_timer(timer); // Start the timer
al_set_blender(ALLEGRO_ADD,ALLEGRO_ALPHA,ALLEGRO_INVERSE_ALPHA);
gzz=al_create_bitmap(640,480);
if(!gzz){printf("fallofallo22\n");return -1;}
al_set_target_bitmap(gzz);
Renderx();
  // Primary 'game' loop.
  while (1) {
      ALLEGRO_EVENT event;
      al_wait_for_event(queue, &event); // Wait for and get an event.
      if (event.type == ALLEGRO_EVENT_DISPLAY_ORIENTATION) {
          int o = event.display.orientation;
          if (o == ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES) {
              printf("0 degrees\n");
          }
          else if (o == ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES) {
              printf("90 degrees\n");
          }
          else if (o == ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES) {
              printf("180 degrees\n");
          }
          else if (o == ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES) {
              printf("270 degrees\n");
          }
          else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_UP) {
              printf("Face up\n");
          }
          else if (o == ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN) {
              printf("Face down\n");
          }
      }
      if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
          break;
      /* Use keyboard to zoom image in and out.
       * 1: Reset zoom.
       * +: Zoom in 10%
       * -: Zoom out 10%
       * f: Zoom to width of window
       */
      if (event.type == ALLEGRO_EVENT_KEY_CHAR) {
          if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
              break; // Break the loop and quite on escape key.
          if (event.keyboard.unichar == '1')
              zoom = 1;
          if (event.keyboard.unichar == '+')
              zoom = 1;
          if (event.keyboard.unichar == '-')
              zoom = 0;
          if (event.keyboard.unichar == 'f')
              zoom = (double)al_get_display_width(display) /
                  al_get_bitmap_width(bitmap);
      }

      // Trigger a redraw on the timer event
      if (event.type == ALLEGRO_EVENT_TIMER)
          redraw = true;
          
      // Redraw, but only if the event queue is empty
      if (redraw && al_is_event_queue_empty(queue)) {
          redraw = false;
          al_set_target_backbuffer(display);
          // Clear so we don't get trippy artifacts left after zoom.
          al_clear_to_color(al_map_rgb_f(0, 0, zoom));
          al_draw_bitmap(gzz,0,0,0);
          al_flip_display();
          Renderx();
      }
  }


  return 0;

}

/* vim: set sts=4 sw=4 et: */ `

It's based in ex_bitmap.c

  • Something are wrong with ALLEGRO_PIXEL_FORMAT_RGBA_8888 and ALLEGRO_PIXEL_FORMAT_RGB_888, both are a size of 4 bytes x pixel, and give strange behavior if you change the code for 4 or 3 bytes.
  • al_set_blender affect al_lock_bitmap, this are undocumented.
  • Don't have sense how are drawing in the bitmap, seem like fragmented.
  • Where you render in all the bitmap, get segfault by overflow or double free.

rmbeer avatar Jun 27 '23 02:06 rmbeer

Hi! The formatting is broken up to double t1;

jeffythedragonslayer avatar Feb 06 '24 23:02 jeffythedragonslayer

  • both are a size of 4 bytes x pixel

According to https://liballeg.org/a5docs/trunk/graphics.html#allegro_pixel_format one of them is 4 bytes and one is 3 bytes.

allefant avatar Feb 06 '24 23:02 allefant