allegro5
allegro5 copied to clipboard
something broken in al_lock_bitmap
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.
Hi! The formatting is broken up to double t1;
- 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.