Error Message when program finishes
AramisL

Hi forum!
First I want to thank Edgar Reynaldo and Neil Roy, they help me with my last and solved question. https://www.allegro.cc/forums/thread/617247

But a new problem rised, when timer and video are together, Edgar Reynaldo gave me a piece of code but I didnt understand too much, I tried some times but can not run it fine.

So, I write this code to check my solution without copy & paste, it plays the video but when I press ESC (to finish the execution)it give me a Windows error:

"las.exe has stopped working.
A problem caused the program to stop working correctly. Windows will close the program and notify you if solution is available."

I searched in the forum, but I couldn't find a solution, ohhh and it message doesnt appear when I close the console.

#SelectExpand
1#include <stdio.h> 2#include <windows.h> 3/** CImg lib **/ 4#include "CImg.h" 5using namespace cimg_library; 6 7/** Allegro lib**/ 8#include <allegro5/allegro.h> 9#include <allegro5/allegro.h> 10#include <allegro5/allegro_audio.h> 11#include <allegro5/allegro_acodec.h> 12#include <allegro5/allegro_image.h> 13#include <allegro5/allegro_primitives.h> 14#include <allegro5/allegro_font.h> 15#include <allegro5/allegro_ttf.h> 16//#include <allegro_physfs.h> 17#include <allegro5/allegro_video.h> 18#include <allegro5/allegro_native_dialog.h> 19 20#define DEBUG 21 22void initialize(); 23bool captura(int, int, int, int, char *); 24extern bool SaveBMPFile(char *, HBITMAP, HDC, int, int); 25inline int GetFilePointer(HANDLE FileHandle) 26{ 27 return SetFilePointer(FileHandle, 0, 0, FILE_CURRENT); 28} 29 30int main(int argc, char** argv) 31{ 32 //captura(0,0, 1366, 768,"screenshot.bmp"); 33 34 initialize(); 35 ALLEGRO_DISPLAY *display = al_create_display(1366, 768); 36 ALLEGRO_VIDEO* video = NULL; 37 ALLEGRO_BITMAP* bitmap = NULL; 38 ALLEGRO_BITMAP* img = NULL; 39 ALLEGRO_EVENT_QUEUE *evqueue = al_create_event_queue(); 40 ALLEGRO_TIMER *fps_timer = al_create_timer(1.0 / 60.0); 41 ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); 42 chdir(al_path_cstr(path, '/')); 43 bool render = true, executing = true, redraw = true, playvideo1 = true; 44 45 46 al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, true); 47 al_set_display_flag(display, ALLEGRO_PROGRAMMABLE_PIPELINE, true); 48 49 if (!display) 50 { 51 printf("Failed to create display!\n"); 52 printf(" no display "); 53 }; 54 al_register_event_source(evqueue, al_get_keyboard_event_source()); 55 al_register_event_source(evqueue, al_get_mouse_event_source()); 56 al_register_event_source(evqueue, al_get_display_event_source(display)); 57 al_register_event_source(evqueue, al_get_timer_event_source(fps_timer)); 58 59 al_start_timer(fps_timer); 60 al_flip_display(); 61 al_rest(1); 62 while (executing) 63 { 64 ALLEGRO_EVENT event; 65 al_wait_for_event(evqueue, &event); 66 67 switch (event.type) 68 { 69 case ALLEGRO_EVENT_TIMER: 70 render = true; 71 break; 72 case ALLEGRO_EVENT_DISPLAY_CLOSE: 73 executing = false; 74 break; 75 case ALLEGRO_EVENT_KEY_DOWN: 76 executing = event.keyboard.keycode != ALLEGRO_KEY_ESCAPE; 77 break; 78 } 79 80 if (render && al_is_event_queue_empty(evqueue)) 81 { 82 render = false; 83 84 if(playvideo1==true) 85 { 86 video = al_open_video("welcome.ogv"); 87 al_start_video(video, al_get_default_mixer()); 88 playvideo1=false; 89 } 90 if(redraw) 91 { 92 al_clear_to_color(al_map_rgb(25,155,55)); 93 redraw = false; 94 } 95 bitmap = al_get_video_frame(video); 96 if(bitmap==NULL) 97 printf(" bitmap empty "); 98 if(bitmap) 99 { 100 al_draw_bitmap(bitmap, 111, 200, 0); 101 al_flip_display(); 102 al_rest(0.01); 103 } 104 105 } 106 render = false; 107 } 108 109 al_unregister_event_source(evqueue, al_get_keyboard_event_source()); 110 al_unregister_event_source(evqueue, al_get_mouse_event_source()); 111 al_unregister_event_source(evqueue, al_get_display_event_source(display)); 112 al_unregister_event_source(evqueue, al_get_timer_event_source(fps_timer)); 113 114 al_destroy_display(display); 115 al_close_video(video); 116 al_destroy_event_queue(evqueue); 117 al_destroy_timer(fps_timer); 118 al_destroy_bitmap(bitmap); 119 al_destroy_bitmap(img); 120 al_destroy_path(path); 121 122 return 0; 123}

Note: playvideo1 in the finished program must be false, and only when the student press a button with the mouse it must be true and then start video.
If the size of video is large it gives some glitches, but in this projects isn't a problem.

If somebody find the problem, please help me.

Neil Roy

Try executing al_destroy_display(display); last. I am wondering if that might cause problems when you destroy it before you close the video or destroy the bitmaps?

As a rule of thumb, I destroy these things in the reverse order that I created them in, to be safe.

I would also check to see if your display variable is valid immediately after you create display and then exit(1) if it fails rather than waiting until later on to check it. I also note that you don't exit if it fails, so that will definitely cause a problem if creating it fails and then you go to exit normally, your program will try and destroy the display when none was created.

Always check for errors right away anyhow and exit if they fail with an error message, destroying anything that was created before you exit.

Chris Katko

Are you using Visual Studio? If so, it's super easy to just turn on the debugger, place a breakpoint before the end, and "step through" the code until it blows up and you'll know the exact line it blew up.

Heck, even without the breakpoint, Visual Studio should still tell you the line of code responsible if you just run it with Debug (Control-F5?) instead of normal mode.

AramisL

Thanks for reply, I tried some solutions, and change a lot of settings and this code works, doesn't give error BUT never return 0, unless if I comment al_close_video.
I use CodeBlocks so there are 2 logs, the first with no error and return 0, and the second never return 0 and no message error either, as we can see "DirectSound closed" disappeared.
My question is: is it so important al_close_video? can I fix it?

#SelectExpand
1 2 al_start_timer(fps_timer); 3 al_flip_display(); 4 al_rest(1); 5 while (executing) 6 { 7 ALLEGRO_EVENT event; 8 al_wait_for_event(evqueue, &event); 9 10 switch (event.type) 11 { 12 case ALLEGRO_EVENT_TIMER: 13 render = true; 14 break; 15 case ALLEGRO_EVENT_DISPLAY_CLOSE: 16 executing = false; 17 break; 18 19 case ALLEGRO_EVENT_KEY_DOWN: 20 executing = event.keyboard.keycode != ALLEGRO_KEY_ESCAPE; 21 break; 22 } 23 24 if (render && al_is_event_queue_empty(evqueue)) 25 { 26 render = false; 27 28 if(playvideo1==true) 29 { 30 video = al_open_video("welcome.ogv"); 31 al_start_video(video, al_get_default_mixer()); 32 playvideo1=false; 33 } 34 if(redraw) 35 { 36 al_clear_to_color(al_map_rgb(25,155,55)); 37 redraw = false; 38 } 39 bitmap = al_get_video_frame(video); 40 if(bitmap==NULL) 41 printf(" bitmap empty "); 42 if(bitmap) 43 { 44 al_draw_bitmap(bitmap, 99, 100, 0); 45 al_flip_display(); 46 al_rest(0.01); 47 } 48 49 } 50 render = false; 51 } 52 al_unregister_event_source(evqueue, al_get_keyboard_event_source()); 53 al_unregister_event_source(evqueue, al_get_display_event_source(display)); 54 al_unregister_event_source(evqueue, al_get_timer_event_source(fps_timer)); 55 al_set_target_bitmap(NULL); 56 al_destroy_event_queue(evqueue); 57 al_destroy_timer(fps_timer); 58 al_destroy_bitmap(bitmap); 59 al_destroy_display(display); 60 al_destroy_path(path); 61 62 shutdown(); 63 al_close_video(video); 64 return 0; 65} 66void shutdown() 67{ 68 al_shutdown_ttf_addon(); 69 al_shutdown_font_addon(); 70 al_shutdown_primitives_addon(); 71 al_uninstall_keyboard(); 72 al_uninstall_mouse(); 73 al_uninstall_audio(); 74 al_uninstall_system(); 75}

Both without message error
allegro.log (1) Return 0
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_bmp.cpp:539 _al_d3d_sync_bitmap [ 2.16498] _al_d3d_sync_bitmap (system) ref count == 1
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_bmp.cpp:545 _al_d3d_sync_bitmap [ 2.16501] _al_d3d_sync_bitmap (video) ref count == 1
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.30824] removed dtor for timer 01FB6140
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.30830] removed dtor for queue 01FB4248
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.30832] removed dtor for sub_bitmap 01FBBB98
video D E:\LIBS\LIBS71Build\allegro\addons\video\ogv.c:1104 decode_thread_func [ 3.31926] End decode loop.
audio W E:\LIBS\LIBS71Build\allegro\addons\audio\kcm_stream.c:641 _al_kcm_refill_stream [ 3.42019] Out of buffers
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.42351] removed dtor for timer 01FB5C70
video D E:\LIBS\LIBS71Build\allegro\addons\video\ogv.c:1113 decode_thread_func [ 3.42354] Thread exit.
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.42368] removed dtor for queue 0207E1E0
video D E:\LIBS\LIBS71Build\allegro\addons\video\ogv.c:252 free_stream [ 3.42375] Clean up Theora.
video D E:\LIBS\LIBS71Build\allegro\addons\video\ogv.c:268 free_stream [ 3.42386] Clean up Vorbis.
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.42397] removed dtor for bitmap 02075E18
d3d I E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:901 d3d_destroy_display [ 3.42415] destroying display 01FB2E20 (current 00000000)
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:885 d3d_destroy_display_internals [ 3.42653] waiting for display 01FB2E20's thread to end
d3d W E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:595 d3d_destroy_device [ 3.43304] d3d_destroy_device: ref count not 0
d3d I E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:1550 d3d_display_thread_proc [ 3.43709] d3d display thread exits
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.43964] removed dtor for sample_instance 0003DF90
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.43966] removed dtor for mixer 0003DC60
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:513 _dsound_stop_voice [ 3.43967] Stopping voice
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:530 _dsound_stop_voice [ 3.43968] Joining thread
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:536 _dsound_stop_voice [ 3.44340] Joined thread
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:538 _dsound_stop_voice [ 3.44342] Destroying thread
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:540 _dsound_stop_voice [ 3.44343] Thread destroyed
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:547 _dsound_stop_voice [ 3.44344] Releasing buffer
audio-dsound I E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:551 _dsound_stop_voice [ 3.44345] Voice stopped
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.44348] removed dtor for voice 0003D788
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:365 _dsound_deallocate_voice [ 3.44349] Deallocating voice
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:370 _dsound_deallocate_voice [ 3.44350] Deallocated voice
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:281 _dsound_close [ 3.44352] Releasing device
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:283 _dsound_close [ 3.45713] Released device
audio-dsound I E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:284 _dsound_close [ 3.45716] DirectSound closed
__________________________________________________________________________________
allegro.log (2) never return 0
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_bmp.cpp:539 _al_d3d_sync_bitmap [ 3.35485] _al_d3d_sync_bitmap (system) ref count == 1
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_bmp.cpp:545 _al_d3d_sync_bitmap [ 3.43250] _al_d3d_sync_bitmap (video) ref count == 1
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.44549] removed dtor for queue 02066440
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.44553] removed dtor for timer 020665B0
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.44555] removed dtor for sub_bitmap 02068900
d3d I E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:901 d3d_destroy_display [ 3.44556] destroying display 0205F5F0 (current 00000000)
bitmap D E:\LIBS\LIBS71Build\allegro\src\bitmap_type.c:308 _al_convert_to_memory_bitmap [ 3.44850] converting display bitmap 020756D0 to memory bitmap
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:196 _al_register_destructor [ 3.44855] added dtor for bitmap 02066528, func 0040231F
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_bmp.cpp:539 _al_d3d_sync_bitmap [ 3.44858] _al_d3d_sync_bitmap (system) ref count == 1
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_bmp.cpp:545 _al_d3d_sync_bitmap [ 3.44859] _al_d3d_sync_bitmap (video) ref count == 1
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.45198] removed dtor for bitmap 02066528
d3d D E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:885 d3d_destroy_display_internals [ 3.45249] waiting for display 0205F5F0's thread to end
d3d W E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:595 d3d_destroy_device [ 3.45608] d3d_destroy_device: ref count not 0
d3d I E:\LIBS\LIBS71Build\allegro\src\win\d3d_disp.cpp:1550 d3d_display_thread_proc [ 3.46466] d3d display thread exits
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.46592] removed dtor for sample_instance 02051B88
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.46595] removed dtor for mixer 020516F0
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:513 _dsound_stop_voice [ 3.46596] Stopping voice
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:530 _dsound_stop_voice [ 3.46597] Joining thread
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:536 _dsound_stop_voice [ 3.47589] Joined thread
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:538 _dsound_stop_voice [ 3.47591] Destroying thread
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:540 _dsound_stop_voice [ 3.47593] Thread destroyed
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:547 _dsound_stop_voice [ 3.47593] Releasing buffer
audio-dsound I E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:551 _dsound_stop_voice [ 3.47594] Voice stopped
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.47596] removed dtor for voice 003FEE98
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:365 _dsound_deallocate_voice [ 3.47598] Deallocating voice
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:370 _dsound_deallocate_voice [ 3.47599] Deallocated voice
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:281 _dsound_close [ 3.47601] Releasing device
audio-dsound D E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:283 _dsound_close [ 3.54388] Released device
audio-dsound I E:\LIBS\LIBS71Build\allegro\addons\audio\dsound.cpp:284 _dsound_close [ 3.54391] DirectSound closed
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:116 _al_run_destructors [ 3.54392] calling dtor for timer 06D9F748, func 0042A6AD
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.54393] removed dtor for timer 06D9F748
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:116 _al_run_destructors [ 3.54394] calling dtor for queue 06D8F278, func 0042065F
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.54395] removed dtor for queue 06D8F278
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:116 _al_run_destructors [ 3.54397] calling dtor for bitmap 020756D0, func 0040231F
dtor D E:\LIBS\LIBS71Build\allegro\src\dtor.c:227 _al_unregister_destructor [ 3.54398] removed dtor for bitmap 020756D0

Edgar Reynaldo

It's a good rule of thumb to destroy everything you create, and in the reverse order.

That said,

All you really need to do is close the video and shutdown allegro. Note, most of this is done for you automatically. al_uninstall_system is usually registered with atexit by al_init. Which means you don't need to call anything. Except al_close_video.

/// end main loop
   al_close_video(video);
   al_uninstall_system();/// mostly optional if you called al_init
   /// al_close_video(video);/// Would be bad, as allegro's vtable has been destroyed
   return 0;
}
/// Beware! Global destructors run here!!! (C++ warning)

EDIT
Updated code a little to be more clear on what is going on.

AramisL

Hi! I solved the problem adding bitmap=NULL after somebody closes the windows or when the ESC buttom is pressed.
As you may have read, there was a log that worked, and that is rare, because one program give the same output for the same input; so, why some times did the program work? that smelled like pointer trouble.
So the program works fine now, thanks all for your help! :)

#SelectExpand
1#include <stdio.h> 2#include <windows.h> 3/** CImg lib **/ 4#include "CImg.h" 5using namespace cimg_library; 6 7/** Allegro lib**/ 8#include <allegro5/allegro.h> 9#include <allegro5/allegro.h> 10#include <allegro5/allegro_audio.h> 11#include <allegro5/allegro_acodec.h> 12#include <allegro5/allegro_image.h> 13#include <allegro5/allegro_primitives.h> 14#include <allegro5/allegro_font.h> 15#include <allegro5/allegro_ttf.h> 16//#include <allegro_physfs.h> 17#include <allegro5/allegro_video.h> 18#include <allegro5/allegro_native_dialog.h> 19 20#define DEBUG 21 22void initialize(); 23void shutdown(); 24bool captura(int, int, int, int, char *); 25extern bool SaveBMPFile(char *, HBITMAP, HDC, int, int); 26inline int GetFilePointer(HANDLE FileHandle) 27{ 28 return SetFilePointer(FileHandle, 0, 0, FILE_CURRENT); 29} 30 31int main(int argc, char** argv) 32{ 33/** captura(0,0, 1366, 768,"pantalla3.bmp"); it takes a screenshot 34and save it, to show it later with allegro **/ 35 initialize(); 36 ALLEGRO_DISPLAY *display = al_create_display(500, 368); 37 ALLEGRO_VIDEO* video = NULL; 38 ALLEGRO_BITMAP* bitmap = NULL; 39// ALLEGRO_BITMAP* img = NULL; 40 ALLEGRO_EVENT_QUEUE *evqueue = al_create_event_queue(); 41 ALLEGRO_TIMER *fps_timer = al_create_timer(1.0 / 60.0); 42 ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); 43 chdir(al_path_cstr(path, '/')); 44 bool render = true, executing = true, redraw = true, playvideo1 = true; 45 46 47// al_set_display_flag(display, ALLEGRO_FULLSCREEN_WINDOW, true); 48// al_set_display_flag(display, ALLEGRO_PROGRAMMABLE_PIPELINE, true); 49 50 if (!display) 51 { 52 printf("Failed to create display!\n"); 53 printf(" no displ "); 54 }; 55 al_register_event_source(evqueue, al_get_keyboard_event_source()); 56// al_register_event_source(evqueue, al_get_mouse_event_source()); 57 al_register_event_source(evqueue, al_get_display_event_source(display)); 58 al_register_event_source(evqueue, al_get_timer_event_source(fps_timer)); 59 60 al_start_timer(fps_timer); 61 al_flip_display(); 62 al_rest(1); 63 while (executing) 64 { 65 ALLEGRO_EVENT event; 66 al_wait_for_event(evqueue, &event); 67 68 switch (event.type) 69 { 70 case ALLEGRO_EVENT_TIMER: 71 render = true; 72 break; 73 case ALLEGRO_EVENT_DISPLAY_CLOSE: 74 executing = false; 75 bitmap=NULL; /** already added **/ 76 break; 77 78 case ALLEGRO_EVENT_KEY_DOWN: 79 executing = event.keyboard.keycode != ALLEGRO_KEY_ESCAPE; 80 bitmap=NULL; /** already added **/ 81 break; 82 } 83 84 if (render && al_is_event_queue_empty(evqueue)) 85 { 86 render = false; 87 88 if(playvideo1==true) 89 { 90 video = al_open_video("welcome.ogv"); 91 al_start_video(video, al_get_default_mixer()); 92 playvideo1=false; 93 } 94 if(redraw) 95 { 96 al_clear_to_color(al_map_rgb(25,155,55)); 97 redraw = false; 98 } 99 bitmap = al_get_video_frame(video); 100 if(bitmap==NULL) 101 printf(" bitmap empty "); 102 if(bitmap) 103 { 104 al_draw_bitmap(bitmap, 99, 100, 0); 105 al_flip_display(); 106 al_rest(0.01); 107 } 108 109 } 110 render = false; 111 } 112 113 al_unregister_event_source(evqueue, al_get_keyboard_event_source()); 114//al_unregister_event_source(evqueue, al_get_mouse_event_source()); 115 al_unregister_event_source(evqueue, al_get_display_event_source(display)); 116 al_unregister_event_source(evqueue, al_get_timer_event_source(fps_timer)); 117//al_set_target_bitmap(NULL); 118 /** order changed, to avoid any trouble **/ 119 al_destroy_path(path); 120 al_destroy_timer(fps_timer); 121 al_destroy_event_queue(evqueue); 122 al_destroy_bitmap(bitmap); 123 al_close_video(video); 124 al_destroy_display(display); 125 126 127 shutdown(); 128 129 al_uninstall_system(); 130//al_destroy_bitmap(img); 131 132 return 0; 133} 134 135void initialize() 136{ 137 srand((unsigned int) time(NULL)); 138 139#ifdef DEBUG 140 printf(" Allegro v%i.%i.%i\n", 141 al_get_allegro_version() >> 24, 142 (al_get_allegro_version() >> 16) & 255, 143 (al_get_allegro_version() >> 8) & 255); 144 145 printf("\n video v%i.%i.%i\n", 146 al_get_allegro_video_version() >> 24, 147 (al_get_allegro_video_version() >> 16) & 255, 148 (al_get_allegro_video_version() >> 8) & 255); 149#endif /* DEBUG */ 150 151 if (!al_init()) 152 { 153// al_show_native_message_box(display, "Error", "Error", "Fallo al inita5 !", NULL, ALLEGRO_MESSAGEBOX_ERROR); 154 printf("no carga init5"); 155 exit(EXIT_FAILURE); 156 } 157 if (!al_install_audio()) 158 { 159// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar audio!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 160 printf("no carga init5"); 161 exit(EXIT_FAILURE); 162 } 163 if (!al_init_acodec_addon()) 164 { 165// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar acodec addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 166 printf("no carga init5"); 167 exit(EXIT_FAILURE); 168 } 169 if (!al_reserve_samples(1)) 170 { 171// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar reserve samples!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 172 printf("no carga init5"); 173 exit(EXIT_FAILURE); 174 } 175 if (!al_install_mouse()) 176 { 177// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar mouse!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 178 printf("no carga init5"); 179 exit(EXIT_FAILURE); 180 } 181 if (!al_install_keyboard()) 182 { 183// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar teclado!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 184 printf("no carga init5"); 185 exit(EXIT_FAILURE); 186 } 187 if (!al_init_video_addon()) 188 { 189// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar vid addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 190 printf("no carga init5"); 191 exit(EXIT_FAILURE); 192 } 193 if (!al_init_primitives_addon()) 194 { 195// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar prim addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 196 printf("no carga init5"); 197 exit(EXIT_FAILURE); 198 } 199 if (!al_init_font_addon()) 200 { 201// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar font addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 202 printf("no carga init5"); 203 exit(EXIT_FAILURE); 204 } 205 if (!al_init_ttf_addon()) 206 { 207// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar ttf addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 208 printf("no carga init5"); 209 exit(EXIT_FAILURE); 210 } 211 if (!al_init_image_addon()) 212 { 213// al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar img addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 214 printf("no carga init5"); 215 exit(EXIT_FAILURE); 216 } 217} 218 219void shutdown() 220{ 221 al_shutdown_ttf_addon(); 222 al_shutdown_font_addon(); 223 al_shutdown_primitives_addon(); 224 al_uninstall_keyboard(); 225 al_uninstall_mouse(); 226 al_uninstall_audio(); 227} 228 229bool captura(int x, int y, int width, int height, char *filename) 230{ 231// get a DC compat. w/ the screen 232 HDC hDc = CreateCompatibleDC(0); 233 234// make a bmp in memory to store the capture in 235 HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), width, height); 236 237// join em up 238 SelectObject(hDc, hBmp); 239 240// copy from the screen to my bitmap 241 BitBlt(hDc, 0, 0, width, height, GetDC(0), x, y, SRCCOPY); 242 243// save my bitmap 244 bool ret = SaveBMPFile(filename, hBmp, hDc, width, height); 245 246// free the bitmap memory 247 DeleteObject(hBmp); 248 249 return ret; 250} 251 252extern bool SaveBMPFile(char *filename, HBITMAP bitmap, HDC bitmapDC, int width, int height) 253{ 254 bool Success=false; 255 HDC SurfDC=NULL; // GDI-compatible device context for the surface 256 HBITMAP OffscrBmp=NULL; // bitmap that is converted to a DIB 257 HDC OffscrDC=NULL; // offscreen DC that we can select OffscrBmp into 258 LPBITMAPINFO lpbi=NULL; // bitmap format info; used by GetDIBits 259 LPVOID lpvBits=NULL; // pointer to bitmap bits array 260 HANDLE BmpFile=INVALID_HANDLE_VALUE; // destination .bmp file 261 BITMAPFILEHEADER bmfh; // .bmp file header 262 263 // We need an HBITMAP to convert it to a DIB: 264 if ((OffscrBmp = CreateCompatibleBitmap(bitmapDC, width, height)) == NULL) 265 return false; 266 267 // The bitmap is empty, so let's copy the contents of the surface to it. 268 // For that we need to select it into a device context. We create one. 269 if ((OffscrDC = CreateCompatibleDC(bitmapDC)) == NULL) 270 return false; 271 272 // Select OffscrBmp into OffscrDC: 273 HBITMAP OldBmp = (HBITMAP)SelectObject(OffscrDC, OffscrBmp); 274 275 // Now we can copy the contents of the surface to the offscreen bitmap: 276 BitBlt(OffscrDC, 0, 0, width, height, bitmapDC, 0, 0, SRCCOPY); 277 278 // GetDIBits requires format info about the bitmap. We can have GetDIBits 279 // fill a structure with that info if we pass a NULL pointer for lpvBits: 280 // Reserve memory for bitmap info (BITMAPINFOHEADER + largest possible 281 // palette): 282 if ((lpbi = (LPBITMAPINFO)(new char[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)])) == NULL) 283 return false; 284 285 286 ZeroMemory(&lpbi->bmiHeader, sizeof(BITMAPINFOHEADER)); 287 lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 288 // Get info but first de-select OffscrBmp because GetDIBits requires it: 289 SelectObject(OffscrDC, OldBmp); 290 if (!GetDIBits(OffscrDC, OffscrBmp, 0, height, NULL, lpbi, DIB_RGB_COLORS)) 291 return false; 292 293 // Reserve memory for bitmap bits: 294 if ((lpvBits = new char[lpbi->bmiHeader.biSizeImage]) == NULL) 295 return false; 296 297 // Have GetDIBits convert OffscrBmp to a DIB (device-independent bitmap): 298 if (!GetDIBits(OffscrDC, OffscrBmp, 0, height, lpvBits, lpbi, DIB_RGB_COLORS)) 299 return false; 300 301 // Create a file to save the DIB to: 302 if ((BmpFile = CreateFile(filename, 303 GENERIC_WRITE, 304 0, NULL, 305 CREATE_ALWAYS, 306 FILE_ATTRIBUTE_NORMAL, 307 NULL)) == INVALID_HANDLE_VALUE) 308 309 return false; 310 311 DWORD Written; // number of bytes written by WriteFile 312 313 // Write a file header to the file: 314 bmfh.bfType = 19778; // 'BM' 315 // bmfh.bfSize = ??? // we'll write that later 316 bmfh.bfReserved1 = bmfh.bfReserved2 = 0; 317 // bmfh.bfOffBits = ??? // we'll write that later 318 if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL)) 319 return false; 320 321 if (Written < sizeof(bmfh)) 322 return false; 323 324 // Write BITMAPINFOHEADER to the file: 325 if (!WriteFile(BmpFile, &lpbi->bmiHeader, sizeof(BITMAPINFOHEADER), &Written, NULL)) 326 return false; 327 328 if (Written < sizeof(BITMAPINFOHEADER)) 329 return false; 330 331 // Calculate size of palette: 332 int PalEntries; 333 // 16-bit or 32-bit bitmaps require bit masks: 334 if (lpbi->bmiHeader.biCompression == BI_BITFIELDS) 335 PalEntries = 3; 336 else 337 // bitmap is palettized? 338 PalEntries = (lpbi->bmiHeader.biBitCount <= 8) ? 339 // 2^biBitCount palette entries max.: 340 (int)(1 << lpbi->bmiHeader.biBitCount) 341 // bitmap is TrueColor -> no palette: 342 : 0; 343 // If biClrUsed use only biClrUsed palette entries: 344 if(lpbi->bmiHeader.biClrUsed) 345 PalEntries = lpbi->bmiHeader.biClrUsed; 346 347 // Write palette to the file: 348 if(PalEntries) 349 { 350 if (!WriteFile(BmpFile, &lpbi->bmiColors, PalEntries * sizeof(RGBQUAD), &Written, NULL)) 351 return false; 352 353 if (Written < PalEntries * sizeof(RGBQUAD)) 354 return false; 355 } 356 357 // The current position in the file (at the beginning of the bitmap bits) 358 // will be saved to the BITMAPFILEHEADER: 359 bmfh.bfOffBits = GetFilePointer(BmpFile); 360 361 // Write bitmap bits to the file: 362 if (!WriteFile(BmpFile, lpvBits, lpbi->bmiHeader.biSizeImage, &Written, NULL)) 363 return false; 364 365 if (Written < lpbi->bmiHeader.biSizeImage) 366 return false; 367 368 // The current pos. in the file is the final file size and will be saved: 369 bmfh.bfSize = GetFilePointer(BmpFile); 370 371 // We have all the info for the file header. Save the updated version: 372 SetFilePointer(BmpFile, 0, 0, FILE_BEGIN); 373 if (!WriteFile(BmpFile, &bmfh, sizeof(bmfh), &Written, NULL)) 374 return false; 375 376 if (Written < sizeof(bmfh)) 377 return false; 378 delete[] lpvBits; 379 return true; 380}

Edgar Reynaldo

Don't destroy the 'bitmap' that al_get_video_frame returns. Allegro owns it.

Why split render and redraw into two separate clauses? They should really be the same thing.

You don't need to 'rest' after displaying the bitmap. Your timer event tells you when to redraw. Did ALLEGRO_EVENT_VIDEO_FRAME_SHOW not work for you?

Also, I hate to tell you, but allegro can save .bmp files directly from an ALLEGRO_BITMAP*.

AramisL

Hi! I'll re-write all the code, so, after follow some adviced from Reynaldo now I can play the full video. ;D;D;D

I don´t understand what is ALLEGRO_EVENT_VIDEO_FRAME_SHOW, and how can help me yet, I´ll seek more info.

The bitmap I save is one screenshot I make BEFORE the display (and that part of code I didnt show it). I searched something similar in Allegro-lib but I couldnt find it.

:-/

Edgar Reynaldo

Oh, in that case carry on. Taking a screenshot is only possible with native code. But if you have an ALLEGRO_BITMAP*, you can save it as an image file, based on the extension.

Thread #617252. Printed from Allegro.cc