Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » video & physfs problems in the same file

This thread is locked; no one can reply to it. rss feed Print
video & physfs problems in the same file
AramisL
Member #16,723
August 2017
avatar

Hi people!

I have this project (called LAS), to help new students in my university, this isn´t a game, you can think it like an Encarta (an interactive book), and I want this program could plays videos, some videos I will make with Blender, so.... my problem is this: I can´t play videos after init physfs

I mean:
project only with physfs works fine
project only with video addon works fine
project doesnt works fine, can't play video if physfs is used before, but can play video before use physfs (open video cant find video, give me NULL)

So, I thought the problem could be the interface I/O, so I tried to fixed using:
void al_set_fs_interface()
void al_set_standard_fs_interface()
void al_restore_state()
void al_set_standard_file_interface()
...to manage the interfaces ??? in some strategic places of the program, but I don´t know the how to

please help me ;D

#SelectExpand
1#include <stdio.h> 2#include <physfs.h> 3#include <allegro5/allegro.h> 4#include <allegro5/allegro_primitives.h> 5#include <allegro5/allegro_image.h> 6#include <allegro5/allegro_native_dialog.h> 7#include <allegro5/allegro_font.h> 8#include <allegro5/allegro_ttf.h> 9#include <allegro5/allegro_physfs.h> 10#include <allegro5/allegro_audio.h> 11#include <allegro5/allegro_video.h> 12 13typedef struct ALLEGRO_STATE ALLEGRO_STATE; 14const float FPS = 60; 15static char const *filename; 16void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface); 17{ 18 thread_local_state *tls; 19 20 if ((tls = tls_get()) == NULL) 21 return; 22 tls->fs_interface = fs_interface; 23} 24void al_set_standard_fs_interface(void) 25{ 26 al_set_fs_interface(&_al_fs_interface_stdio); 27} 28int main(void) 29{ 30 /** DECLARACIONES **/ 31 ALLEGRO_DISPLAY *display = NULL; 32 ALLEGRO_MONITOR_INFO info; 33 ALLEGRO_BITMAP *image = NULL; 34 ALLEGRO_BITMAP *bitmap = NULL; 35 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 36 ALLEGRO_TIMER *timer = NULL; 37 ALLEGRO_EVENT ev; 38 ALLEGRO_VIDEO *video = NULL; 39 bool redraw = true; 40 bool exit_program = false; 41 int windowHeight, windowWidth, screenWidth, screenHeight, x; 42 float sx, sy; 43 char resol[59]; 44if(!al_init()) 45 { 46 al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar A5!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 47 return -1; 48 } 49 if(!al_init_image_addon()) 50 { 51 al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar al_init_image_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 52 return -1; 53 } 54 if(!al_init_font_addon()) 55 { 56 al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar al_init_font_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 57 return -1; 58 } 59 if(!al_init_ttf_addon()) 60 { 61 al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar al_init_ttf_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 62 return -1; 63 } 64 if(!al_init_primitives_addon()) 65 { 66 al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar al_init_primitives_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 67 return -1; 68 } 69 if(!al_install_keyboard()) 70 { 71 al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar al_install_keyboard!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 72 return -1; 73 } 74 if (!al_init_video_addon()) 75 { 76 printf("Could not initialize the video addon.\n"); 77 return -1; 78 } 79 timer = al_create_timer(1.0 / FPS); 80 if(!timer) 81 { 82 al_show_native_message_box(display, "Error", "Error", "Fallo al crear timer!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 83 return -1; 84 } 85/* Resolution Independence */ 86 al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW); 87 al_get_monitor_info(0, &info); 88 windowWidth = info.x2 - info.x1; /* Assume this is 1366 */ 89 windowHeight = info.y2 - info.y1; /* Assume this is 768 */ 90 display = al_create_display(1000, 420); /*(windowWidth, windowHeight);*/ 91 if(!display) 92 { 93 al_show_native_message_box(display, "Error", "Error", "Fallo al crear display!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 94 al_destroy_timer(timer); 95 return -1; 96 } 97 screenWidth = windowWidth;/* 768; 4:3 aspecto */ 98 screenHeight = windowHeight;/* 576; */ 99 sx = windowWidth / (float)screenWidth; 100 sy = windowHeight / (float)screenHeight; 101 ALLEGRO_TRANSFORM trans; 102 al_identity_transform(&trans); 103 al_scale_transform(&trans, sx, sy); 104 al_use_transform(&trans); 105 /* fin de Resolution Independence */ 106 al_install_audio(); 107 al_reserve_samples(1); 108 filename = "welcome.ogv"; 109 video = al_open_video(filename); 110 if (!video) 111 { 112 printf("Cannot read %s.\n", filename); 113 } 114 else 115 { 116 printf(" encontrado %s.\n", filename); 117 } 118 video = al_open_video("welcome.ogv"); 119 if(video == NULL) 120 { 121 printf("video not found "); 122 al_rest(8); 123 } 124 al_start_video(video, al_get_default_mixer()); 125 126 for(x = 0; x < 100; ++x) 127 { 128 bitmap = al_get_video_frame(video); 129 130 if(bitmap) 131 { 132 al_clear_to_color(al_map_rgb(21, 93, 110)); /* same color than Else or I have flickering screen */ 133 al_draw_bitmap(bitmap, 111, 200, 0); 134 } 135 else 136 al_clear_to_color(al_map_rgb(21, 93, 110)); /* withot this line I have audio only*/ 137 } 138void al_store_state(ALLEGRO_STATE *state, int ALLEGRO_STATE_ALL); 139 /* Carga segun resolucion */ 140 PHYSFS_init(NULL); 141 if(!PHYSFS_mount("data", "/", 1)) 142 { 143 printf("\n error carga physfs"); 144 al_destroy_display(display); 145 al_destroy_timer(timer); 146 return -1; 147 } 148 al_set_physfs_file_interface(); 149if (!PHYSFS_exists("bg.png")) 150 { 151 printf(" \n Failed: PHYSFS_exists error "); 152 } 153 else 154 { 155 image = al_load_bitmap("bg.png"); 156// al_set_standard_file_interface();/* back to al_fopen interface? */ 157 al_draw_bitmap(image,0,0,0); 158 al_flip_display(); 159 al_rest(2); 160 161 image = al_load_bitmap("Riel.png"); 162 al_draw_bitmap(image,0,0,0); 163 al_flip_display(); 164 al_rest(2); 165// al_set_standard_file_interface(); /* it didnt work here */ 166 } 167 event_queue = al_create_event_queue(); 168 if(!event_queue) 169 { 170 al_show_native_message_box(display, "Error", "Error", "Fallo al inicializar al_init_primitives_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); 171 al_destroy_display(display); 172 al_destroy_timer(timer); 173 return -1; 174 } 175 al_register_event_source(event_queue, al_get_display_event_source(display)); 176 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 177 178 al_start_timer(timer); 179 while(1) 180 { 181 al_wait_for_event(event_queue, &ev); 182 183 if(ev.type == ALLEGRO_EVENT_TIMER) 184 { 185 redraw = true; 186 } 187 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 188 { 189 break; 190 } 191 if(redraw && al_is_event_queue_empty(event_queue)) 192 { 193 redraw = false; 194 void al_restore_state(ALLEGRO_STATE const *state); /* ?? I copied... */ 195 void al_set_standard_file_interface(void); /* ...from ona example*/ 196 video = al_open_video("welcome.ogv"); 197 if(video == NULL) 198 { 199 printf(" no video file "); 200 al_rest(8); 201 } 202 else 203 { 204 printf(" video file found "); 205 } 206 al_start_video(video, al_get_default_mixer()); 207 for(x = 0; x < 100; ++x) 208 { 209 bitmap = al_get_video_frame(video); 210 if(bitmap) 211 { 212 al_clear_to_color(al_map_rgb(21, 93, 110)); 213 al_draw_bitmap(bitmap, 111, 200, 0); 214 } 215 else 216 al_clear_to_color(al_map_rgb(21, 93, 110)); 217 al_flip_display(); 218 al_rest(0.01); 219 } 220 } 221 } 222 al_destroy_timer(timer); 223 al_destroy_display(display); 224 al_destroy_event_queue(event_queue); 225 al_destroy_bitmap(image); 226 al_destroy_bitmap(bitmap); 227 al_close_video(video); 228 return 0; 229}

Edgar Reynaldo
Member #8,592
May 2007
avatar

AramisL said:

void al_set_fs_interface(const ALLEGRO_FS_INTERFACE *fs_interface);
{
   thread_local_state *tls;
   if ((tls = tls_get()) == NULL) return;
   tls->fs_interface = fs_interface;
}
void al_set_standard_fs_interface(void) {
   al_set_fs_interface(&_al_fs_interface_stdio);
}
int main(void)

What exactly are you trying to do here? You can't just re-write and override functions like that :O xD

Please try reading the manual.

http://liballeg.org/a5docs/trunk/physfs.html#al_set_physfs_file_interface

http://liballeg.org/a5docs/trunk/fshook.html#al_set_standard_fs_interface

After you call physfs_init, call al_set_physfs_file_interface. Now load all of your assets from the zip archive you specified. After that when you're all done with your data file, call al_set_standard_fs_interface to use the normal filesystem interface for your video streaming.

AramisL
Member #16,723
August 2017
avatar

Hi Edgar!
I just copied that from someplace, and copy & paste ;D I already read that pages before, but I dont understand what they say, it is obscure thing to me yet :P like magic....
Thanks for answer and I will try that solution

Edgar Reynaldo
Member #8,592
May 2007
avatar

Copy Paste Coding is the Source of All EvilTM...

There are a lot of other things that need to be fixed in your code as well.

Your code needs to be formatted with proper indentation spacing, or no one will bother reading it, as it is too confusing.

You're using function declarations where you're trying to call a function, you're playing the video with rest in addition to a timer, and I'm sure there are other things.

Neil Roy
Member #2,229
April 2002

In my Deluxe Pacman 2 game (below), I initialize Physfs with the following code:

/// ****** Initialize PHYSFS *******
   PHYSFS_init(NULL);
   if(!PHYSFS_mount("Deluxe Pacman 2.pak", "/", 1)) {
      a5_error(AT, setting.screen, "PHSYFS_init() failed.");
      exit(1);
   }
   al_set_physfs_file_interface();

Note: the a5_error() is my own personal function, not part of Allegro 5.

In the above case, my "Deluxe Pacman 2.pak" file is just a ZIP file renamed and all file access will look inside of it when al_set_physfs_file_interface(); is invoked.

For normal file access you would use al_set_standard_file_interface();, check for files outside of your ZIP and then invoke al_set_physfs_file_interface(); again to switch back to the ZIP. Which is what I do in my game.

Edgar Reynaldo
Member #8,592
May 2007
avatar

AramisL
Member #16,723
August 2017
avatar

Solved problem! ;D but when I tried to clean the video fragment I have problems, maybe because I followed this post https://www.allegro.cc/forums/thread/612410
BUT, in that example, there is'nt a timer, so my video flickr and restart infinite times halting my pc :o console says: null null null null

#SelectExpand
196 video = al_open_video("welcome.ogv"); 197 al_start_video(video, al_get_default_mixer()); 198 for(x = 0; x < 100; ++x) 199 { 200 bitmap = al_get_video_frame(video); 201 if(bitmap) 202 al_draw_bitmap(bitmap, 111, 200, 0); 203 else 204 printf(" null "); 205 al_flip_display(); 206 al_rest(0.01); 207 }

Edgar Reynaldo
Member #8,592
May 2007
avatar

#SelectExpand
1while (!done) { 2 3if (redraw) { 4 al_clear_to_color(al_map_rgb(255,255,255)); 5 al_draw_bitmap(bitmap , x , y); 6 al_flip_display(); 7 redraw = false; 8} 9do [ 10 11 ALLEGRO_EVENT ev; 12 al_wait_for_event(q , &ev); 13 14 if (ev.type == ALLEGRO_EVENT_VIDEO_FRAME_SHOW) { 15 bitmap = al_get_video_frame(video) { 16 } 17 if (ev.type == ALLEGRO_EVENT_TIMER) { 18 redraw = true; 19 } 20 21} while (!al_is_event_queue_empty(q)); 22 23}

GullRaDriel
Member #3,861
September 2003
avatar

Edgar's solution is a good one. No misused timer as he uses events (more garanties to have it running at the same fps everywhere), and it manages redraw.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Edgar Reynaldo
Member #8,592
May 2007
avatar

I put together a working example for you AramisL, here it is :

Video.zip (win32 binary + src)

Here's the full code :

#SelectExpand
1 2#include "allegro5/allegro.h" 3#include "allegro5/allegro_video.h" 4#include "allegro5/allegro_audio.h" 5 6#include <cstdio> 7 8int main(int argc , char** argv) { 9 10 const char* video_path = "cat.ogv"; 11 12 if (argc == 2) { 13 video_path = argv[1]; 14 } 15 16 17 int ww = 1024; 18 int wh = 768; 19 20 int vw = 600; 21 int vh = 480; 22 23 if (!al_init()) {return 1;} 24 if (!al_init_video_addon()) {return 2;} 25 26 if (!al_install_audio()) {return 3;} 27 if (!al_install_keyboard()) {return 4;} 28 29 al_reserve_samples(2); 30 31 al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE); 32 33 ALLEGRO_DISPLAY *display = al_create_display(ww,wh); 34 ALLEGRO_VIDEO* video = NULL; 35 ALLEGRO_BITMAP* bitmap = NULL; 36 ALLEGRO_EVENT_QUEUE *evqueue = al_create_event_queue(); 37 38 ALLEGRO_TIMER *fps_timer = al_create_timer(1.0 / 60.0); 39// ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); 40// chdir(al_path_cstr(path, '/')); 41 42 43 al_register_event_source(evqueue, al_get_keyboard_event_source()); 44 al_register_event_source(evqueue, al_get_display_event_source(display)); 45 al_register_event_source(evqueue, al_get_timer_event_source(fps_timer)); 46 47 48 al_start_timer(fps_timer); 49 50 bool redraw = true; 51 bool quit = false; 52 bool playing = false; 53 bool play = true; 54 55 video = al_open_video(video_path); 56 if (!video) { 57 printf("Failed to load video '%s'.\n" , video_path); 58 return -1; 59 } 60 al_register_event_source(evqueue , al_get_video_event_source(video)); 61 62 while(!quit) 63 { 64 if(redraw) 65 { 66 al_clear_to_color(al_map_rgb(23,111,222)); 67 if (bitmap && playing) { 68 int srcw = al_get_bitmap_width(bitmap); 69 int srch = al_get_bitmap_height(bitmap); 70 vw = al_get_video_scaled_width(video); 71 vh = al_get_video_scaled_height(video); 72// float scalex = vw/destw; 73// float scaley = vh/desth; 74// float scale = (scalex>scaley)?scaley:scalex; 75 76 al_draw_scaled_bitmap(bitmap , 0 , 0 , srcw , srch , (ww-vw)/2 , (wh - vh)/2 , vw , vh , 0); 77 } 78 al_flip_display(); 79 redraw = false; 80 } 81 do 82 { 83 ALLEGRO_EVENT ev; 84 al_wait_for_event(evqueue, &ev); 85 86 if(ev.type == ALLEGRO_EVENT_VIDEO_FRAME_SHOW) 87 { 88 bitmap = al_get_video_frame(video); 89 } 90 91 if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_P) { 92 play = true; 93 } 94 if (ev.type == ALLEGRO_EVENT_VIDEO_FINISHED) { 95 playing = false; 96 play = true;/// restart video 97 } 98 99 if (play) { 100 if (!playing) { 101 al_set_video_playing(video , false); 102 al_start_video(video , al_get_default_mixer()); 103 al_seek_video(video , 0.0); 104 al_set_video_playing(video , true); 105 int i = 0; 106 while (!(bitmap = al_get_video_frame(video)) && i < 100) { 107 al_rest(0.01); 108 ++i; 109 } 110 if (i < 1000) { 111 playing = true; 112 } 113 } 114 else { 115 al_set_video_playing(video , false); 116 bitmap = 0; 117 playing = false; 118 } 119 play = false; 120 } 121 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 122 quit = true; 123 } 124 if (ev.type == ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 125 quit = true; 126 } 127 if(ev.type == ALLEGRO_EVENT_TIMER) 128 { 129 redraw = true; 130 } 131 if (ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) { 132 al_acknowledge_resize(display); 133 ww = al_get_display_width(display); 134 wh = al_get_display_height(display); 135 } 136 } 137 while(!al_is_event_queue_empty(evqueue)); 138 139 } 140 141 al_close_video(video); 142 video = 0; 143 144 al_uninstall_system(); 145 146 return 0; 147}

I think the only thing you are missing is to register the video event source with your event queue. That's why you're not getting any events.

al_register_event_source(queue , al_get_video_event_source(video));

Then you'll want to monitor ALLEGRO_EVENT_VIDEO_FRAME_SHOW and ALLEGRO_EVENT_VIDEO_FINISHED event types in your event loop.

Go to: