Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Using ALLEGRO_DISPLAY_CLOSE multiple times

This thread is locked; no one can reply to it. rss feed Print
Using ALLEGRO_DISPLAY_CLOSE multiple times
mrmojorisin
Member #15,980
June 2015

I am new in ALLEGRO PROGRAMMING and I was trying some code and I could not solve it... I looked over internet but there seems no solution OR i don't know what to search.

My CODE IS

#SelectExpand
1int main() 2{ 3 al_init(); 4 al_install_keyboard(); 5 al_install_mouse(); 6 al_init_primitives_addon(); 7 al_set_new_display_flags(ALLEGRO_RESIZABLE); 8 ALLEGRO_DISPLAY *display= al_create_display(800,600); 9 ALLEGRO_EVENT_QUEUE *eventqueue = al_create_event_queue(); 10 al_register_event_source(eventqueue, al_get_display_event_source(display)); 11 al_register_event_source(eventqueue, al_get_mouse_event_source()); 12 bool done = false; 13 while (!done) 14 { 15 al_flip_display(); 16 al_draw_rectangle(60,60,180,180,al_map_rgb(122,233,121),4); 17 ALLEGRO_EVENT events; 18 al_wait_for_event(eventqueue, &events); 19 if(events.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 20 { 21 ALLEGRO_DISPLAY *display1 = al_create_display(400,300); 22 al_flip_display; 23 ALLEGRO_EVENT_QUEUE *eventqueue1 = al_create_event_queue(); 24 al_register_event_source(eventqueue1, al_get_display_event_source(display1)); 25 ALLEGRO_EVENT eventss; 26 al_wait_for_event(eventqueue1, &eventss); 27 if(eventss.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 28 { 29 al_destroy_display(display1); 30 al_destroy_event_queue(eventqueue1); 31 } 32 } 33 if(events.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 34 { 35 done = true; 36 } 37 } 38 al_destroy_event_queue(eventqueue); 39 al_destroy_display(display); 40 return 0; 41}

and My error message is in Attachment...

Thomas Fjellstrom
Member #476
June 2000
avatar

What if you replace:

if(eventss.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
   al_destroy_display(display1);
   al_destroy_event_queue(eventqueue1);

with:

do {
  al_wait_for_event(eventqueue1, &eventss);
}
while(eventss.type != ALLEGRO_EVENT_CLOSE);
al_destory_event_source(eventqueue1);
al_destroy_display(display1);

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

mrmojorisin
Member #15,980
June 2015

Thomas Fjellstrom - Tried it but same error message pops up when I close the display1 screen... ??? ??? :-[

Edgar Reynaldo
Member #8,592
May 2007
avatar

You're destroying the display twice, which makes it crash. Your event loop could use some work too. If you want to quit when you get an ALLEGRO_EVENT_DISPLAY_CLOSE mesage, just break out of your loop and then call your destruction functions :

#SelectExpand
1int main(int argc , char** argv) { 2 3 /// Setup here 4 5 /// Main event loop here : 6 do { 7 if (redraw) { 8 // redraw 9 redraw = false; 10 } 11 ALLEGRO_EVENT ev; 12 al_wait_for_event(queue , &ev); 13 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 14 break; 15 } 16 } while (!al_is_event_queue_empty(queue)); 17 18 al_destroy_display(display); 19 // ... 20 return 0; 21}

Thomas Fjellstrom
Member #476
June 2000
avatar

You're destroying the display twice, which makes it crash. Your event loop could use some work too. If you want to quit when you get an ALLEGRO_EVENT_DISPLAY_CLOSE mesage, just break out of your loop and then call your destruction functions :

He's actually creating an entirely new display when hitting a mouse button, then (attempting) waiting for it to be closed, then waiting for the first to be closed.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Edgar Reynaldo
Member #8,592
May 2007
avatar

Jeez. I need to get my eyes checked. Or learn how to read. Or something. :-/

What is really happening is when you close display1 you try to draw to the target bitmap, which is the backbuffer of display1, which you just destroyed. That's why it crashes.

Set the target backbuffer before drawing to a display when you have multiple displays. al_set_target_backbuffer(display);

Thomas Fjellstrom
Member #476
June 2000
avatar

What is really happening is when you close display1 you try to draw to the target bitmap, which is the backbuffer of display1, which you just destroyed. That's why it crashes.

I guess I'm wrong, but I was under the impression that allegro unset the backbuffer when a display is destroyed. Maybe it does, but some things don't check that the backbuffer is null? That explains the 0xC access.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Edgar Reynaldo
Member #8,592
May 2007
avatar

Well that's what GDB told me when I ran it through there. It said al_draw_prim crashed with a null target bitmap in a call to al_get_bitmap_flags :

#SelectExpand
1Program received signal SIGSEGV, Segmentation fault. 20x67701cd2 in al_get_bitmap_flags (bitmap=0x0) at C:\mingw\LIBS\A5GIT\allegro\src\bitmap.c:324 3324 if (bitmap->parent) 4(gdb) bt 5#0 0x67701cd2 in al_get_bitmap_flags (bitmap=0x0) at C:\mingw\LIBS\A5GIT\allegro\src\bitmap.c:324 6#1 0x67801047 in al_draw_prim (vtxs=0x22fc80, decl=0x0, texture=0x0, start=0, end=10, type=4) at C:\mingw\LIBS\A5GIT\allegro\addons\primitives\primitives.c:86 7#2 0x677f2559 in al_draw_rectangle (x1=60, y1=60, x2=180, y2=180, color=..., thickness=4) at C:\mingw\LIBS\A5GIT\allegro\addons\primitives\high_primitives.c:382 8#3 0x004017e7 in main () at Test.cpp:23 9(gdb) frame 1 10#1 0x67801047 in al_draw_prim (vtxs=0x22fc80, decl=0x0, texture=0x0, start=0, end=10, type=4) at C:\mingw\LIBS\A5GIT\allegro\addons\primitives\primitives.c:86 1186 if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || 12(gdb) l 1381 1482 /* In theory, if we ever get a camera concept for this addon, the transformation into 1583 * view space should occur here 1684 */ 1785 1886 if (al_get_bitmap_flags(target) & ALLEGRO_MEMORY_BITMAP || 1987 (texture && al_get_bitmap_flags(texture) & ALLEGRO_MEMORY_BITMAP) || 2088 _al_pixel_format_is_compressed(al_get_bitmap_format(target))) { 2189 ret = _al_draw_prim_soft(texture, vtxs, decl, start, end, type); 2290 } else { 23(gdb)

I used pretty much the exact code he did (aside from a typo and missing includes) to cause the segfault :

#SelectExpand
1 2 3#include "allegro5/allegro.h" 4#include "allegro5/allegro_primitives.h" 5 6 7 8int main() 9{ 10 al_init(); 11 al_install_keyboard(); 12 al_install_mouse(); 13 al_init_primitives_addon(); 14 al_set_new_display_flags(ALLEGRO_RESIZABLE); 15 ALLEGRO_DISPLAY *display= al_create_display(800,600); 16 ALLEGRO_EVENT_QUEUE *eventqueue = al_create_event_queue(); 17 al_register_event_source(eventqueue, al_get_display_event_source(display)); 18 al_register_event_source(eventqueue, al_get_mouse_event_source()); 19 bool done = false; 20 while (!done) 21 { 22 al_flip_display(); 23 al_draw_rectangle(60,60,180,180,al_map_rgb(122,233,121),4); 24 ALLEGRO_EVENT events; 25 al_wait_for_event(eventqueue, &events); 26 if(events.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) 27 { 28 ALLEGRO_DISPLAY *display1 = al_create_display(400,300); 29 al_flip_display(); 30 ALLEGRO_EVENT_QUEUE *eventqueue1 = al_create_event_queue(); 31 al_register_event_source(eventqueue1, al_get_display_event_source(display1)); 32 ALLEGRO_EVENT eventss; 33 al_wait_for_event(eventqueue1, &eventss); 34 if(eventss.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 35 { 36 al_destroy_display(display1); 37 al_destroy_event_queue(eventqueue1); 38 } 39 } 40 if(events.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 41 { 42 done = true; 43 } 44 } 45 al_destroy_event_queue(eventqueue); 46 al_destroy_display(display); 47 return 0; 48}

Go to: