Пример #1
0
/* Function: al_destroy_thread
 */
void al_destroy_thread(ALLEGRO_THREAD *thread)
{
   if (!thread) {
      return;
   }

   /* Join if required. */
   switch (thread->thread_state) {
      case THREAD_STATE_CREATED: /* fall through */
      case THREAD_STATE_STARTING: /* fall through */
      case THREAD_STATE_STARTED:
         al_join_thread(thread, NULL);
         break;
      case THREAD_STATE_JOINING:
         ASSERT(thread->thread_state != THREAD_STATE_JOINING);
         break;
      case THREAD_STATE_JOINED:
         break;
      case THREAD_STATE_DESTROYED:
         ASSERT(thread->thread_state != THREAD_STATE_DESTROYED);
         break;
      case THREAD_STATE_DETACHED:
         ASSERT(thread->thread_state != THREAD_STATE_DETACHED);
         break;
   }

   /* May help debugging. */
   thread->thread_state = THREAD_STATE_DESTROYED;
   al_free(thread);
}
Пример #2
0
/* ljoy_exit_joystick: [primary thread]
 *  Shut down the joystick driver.
 */
static void ljoy_exit_joystick(void)
{
    int i;

#ifdef SUPPORT_HOTPLUG
    if (inotify_fd != -1) {
        _al_unix_stop_watching_fd(inotify_fd);
        close(inotify_fd);
        inotify_fd = -1;
    }
    hotplug_ended = true;
    al_signal_cond(hotplug_cond);
    al_join_thread(hotplug_thread, NULL);
#endif

    al_destroy_mutex(config_mutex);
    config_mutex = NULL;

    for (i = 0; i < (int)_al_vector_size(&joysticks); i++) {
        ALLEGRO_JOYSTICK_LINUX **slot = _al_vector_ref(&joysticks, i);
        inactivate_joy(*slot);
        al_free(*slot);
    }
    _al_vector_free(&joysticks);
    num_joysticks = 0;
}
Пример #3
0
static void _uninstall_sdl_event_hack(void)
{
   if (thread) {
      al_set_thread_should_stop(thread);
      al_join_thread(thread, NULL);
      al_destroy_thread(thread);
   }
}
Пример #4
0
static void oss_deallocate_voice(ALLEGRO_VOICE *voice)
{
   OSS_VOICE *oss_voice = voice->extra;

   oss_voice->quit_poll_thread = true;
   al_join_thread(oss_voice->poll_thread, NULL);
   al_destroy_thread(oss_voice->poll_thread);

   close(oss_voice->fd);
   free(voice->extra);
   voice->extra = NULL;
}
Пример #5
0
int main(int argc, const char *argv[])
{
   ALLEGRO_THREAD *thread[MAX_THREADS];
   Background background[MAX_BACKGROUNDS] = {
      { 1.0, 0.5, 0.5 },
      { 0.5, 1.0, 0.5 },
      { 0.5, 0.5, 1.0 },
      { 1.0, 1.0, 0.5 },
      { 0.5, 1.0, 1.0 },
      { 1.0, 0.7, 0.5 },
      { 0.5, 1.0, 0.7 },
      { 0.7, 0.5, 1.0 },
      { 1.0, 0.7, 0.5 },
      { 0.5, 0.7, 1.0 }
   };
   int num_threads;
   int i;

   if (argc > 1) {
      num_threads = strtol(argv[1], NULL, 10);
      if (num_threads > MAX_THREADS)
         num_threads = MAX_THREADS;
      else if (num_threads < 1)
         num_threads = 1;
   }
   else {
      num_threads = 3;
   }

   if (!al_init()) {
      abort_example("Could not init Allegro.\n");
      return 1;
   }
   
   al_init_primitives_addon();
   al_install_keyboard();
   al_install_mouse();

   for (i = 0; i < num_threads; i++) {
      thread[i] = al_create_thread(thread_func,
         &background[i % MAX_BACKGROUNDS]);
   }
   for (i = 0; i < num_threads; i++) {
      al_start_thread(thread[i]);
   }
   for (i = 0; i < num_threads; i++) {
      al_join_thread(thread[i], NULL);
      al_destroy_thread(thread[i]);
   }

   return 0;
}
Пример #6
0
static void pulseaudio_deallocate_voice(ALLEGRO_VOICE *voice)
{
   PULSEAUDIO_VOICE *pv = voice->extra;

   /* We do NOT hold the voice mutex here, so this does NOT result in a
    * deadlock when the thread calls _al_voice_update.
    */
   al_set_thread_should_stop(pv->poll_thread);
   al_join_thread(pv->poll_thread, NULL);
   al_destroy_thread(pv->poll_thread);

   al_destroy_mutex(pv->buffer_mutex);

   pa_simple_free(pv->s);
   al_free(pv);
}
Пример #7
0
/* To be called when stream is destroyed */
static void ogg_stream_close(ALLEGRO_AUDIO_STREAM *stream)
{
   AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra;
   ALLEGRO_EVENT quit_event;


   quit_event.type = _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE;
   al_emit_user_event(al_get_audio_stream_event_source(stream), &quit_event, NULL);
   al_join_thread(stream->feed_thread, NULL);
   al_destroy_thread(stream->feed_thread);

   ov_clear(extra->vf);
   _AL_FREE(extra->vf);
   _AL_FREE(extra);
   stream->extra = NULL;
   stream->feed_thread = NULL;
}
Пример #8
0
/* The stop_voice method should stop playback. For non-streaming voices, it
   should leave the data loaded, and reset the voice position to 0. */
static int _dsound_stop_voice(ALLEGRO_VOICE* voice)
{
   ALLEGRO_DS_DATA *ex_data = (ALLEGRO_DS_DATA *)voice->extra;

   ALLEGRO_DEBUG("Stopping voice\n");

   if (!ex_data->ds8_buffer) {
      ALLEGRO_ERROR("Trying to stop empty voice buffer\n");
      return 1;
   }

   /* if playing a sample */
   if (!voice->is_streaming) {
      ALLEGRO_DEBUG("Stopping non-streaming voice\n");
      ex_data->ds8_buffer->Stop();
      ex_data->ds8_buffer->SetCurrentPosition(0);
      ALLEGRO_INFO("Non-streaming voice stopped\n");
      return 0;
   }

   if (ex_data->stop_voice == 0) {
      ALLEGRO_DEBUG("Joining thread\n");
      ex_data->stop_voice = 1;
      while (ex_data->stop_voice == 1) {
	  al_wait_cond(voice->cond, voice->mutex);
      }
      al_join_thread(ex_data->thread, NULL);
      ALLEGRO_DEBUG("Joined thread\n");

      ALLEGRO_DEBUG("Destroying thread\n");
      al_destroy_thread(ex_data->thread);
      ALLEGRO_DEBUG("Thread destroyed\n");
      /* This is required to restart the background thread when the voice
       * restarts.
       */
      ex_data->stop_voice = 1;
   }

   ALLEGRO_DEBUG("Releasing buffer\n");
   ex_data->ds8_buffer->Release();
   ex_data->ds8_buffer = NULL;

   ALLEGRO_INFO("Voice stopped\n");
   return 0;
}
Пример #9
0
static void hapxi_exit_haptic(void)
{
   void *ret_value;
   ASSERT(hapxi_thread);
   ASSERT(hapxi_mutex);
   ASSERT(hapxi_cond);

   /* Request the event thread to shut down, signal the condition, then join the thread. */
   al_set_thread_should_stop(hapxi_thread);
   al_signal_cond(hapxi_cond);
   al_join_thread(hapxi_thread, &ret_value);

   /* clean it all up. */
   al_destroy_thread(hapxi_thread);
   al_destroy_cond(hapxi_cond);

   al_destroy_mutex(hapxi_mutex);
   hapxi_mutex = NULL;
}
Пример #10
0
static void pulseaudio_deallocate_voice(ALLEGRO_VOICE *voice)
{
   PULSEAUDIO_VOICE *pv = voice->extra;

   al_lock_mutex(voice->mutex);
   pv->status = PV_JOIN;
   al_broadcast_cond(pv->status_cond);
   al_unlock_mutex(voice->mutex);

   /* We do NOT hold the voice mutex here, so this does NOT result in a
    * deadlock when the thread calls _al_voice_update.
    */
   al_join_thread(pv->poll_thread, NULL);
   al_destroy_thread(pv->poll_thread);

   al_destroy_cond(pv->status_cond);
   al_destroy_mutex(pv->buffer_mutex);

   pa_simple_free(pv->s);
   al_free(pv);
}
Пример #11
0
/* The stop_voice method should stop playback. For non-streaming voices, it
   should leave the data loaded, and reset the voice position to 0. */
static int _openal_stop_voice(ALLEGRO_VOICE* voice)
{
   ALLEGRO_AL_DATA *ex_data = voice->extra;
   ALenum openal_err;

   if (!ex_data->buffers) {
      ALLEGRO_WARN("Trying to stop empty voice buffer\n");
      return 1;
   }

   /* if playing a sample */
   if (!voice->is_streaming) {
      alSourceStop(ex_data->source);
      if ((openal_err = alGetError()) != AL_NO_ERROR) {
         ALLEGRO_ERROR("Could not stop voice: %s\n",
            openal_get_err_str(openal_err));
         return 1;
      }
      return 0;
   }

   if (ex_data->thread) {
      al_set_thread_should_stop(ex_data->thread);
      while (!ex_data->stopped) {
         al_wait_cond(voice->cond, voice->mutex);
      }
      al_join_thread(ex_data->thread, NULL);
      ex_data->thread = NULL;
      ex_data->stopped = false;
   }
   
   alSourcei(ex_data->source, AL_BUFFER, 0);
   alDeleteSources(1, &ex_data->source);
   alDeleteBuffers(ex_data->num_buffers, ex_data->buffers);
   al_free(ex_data->buffers);
   ex_data->buffers = NULL;
   
   alGetError(); /* required! */
   return 0;
}
Пример #12
0
int main(void)
{
   ALLEGRO_THREAD *thread[NUM_THREADS];
   ALLEGRO_DISPLAY *display;
   ALLEGRO_TIMER *timer;
   ALLEGRO_EVENT_QUEUE *queue;
   ALLEGRO_EVENT event;
   bool need_draw;
   int i;

   for (i = 0; i < 256; i++) {
      sin_lut[i] = 128 + (int) (127.0 * sin(i / 8.0));
   }

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

   al_install_keyboard();
   al_install_mouse();
   display = al_create_display(W * IMAGES_PER_ROW,
      H * NUM_THREADS / IMAGES_PER_ROW);
   if (!display) {
      abort_example("Error creating display\n");
      return 1;
   }
   timer = al_install_timer(1.0/3);
   if (!timer) {
      abort_example("Error creating timer\n");
      return 1;
   }
   queue = al_create_event_queue();
   if (!queue) {
      abort_example("Error creating event queue\n");
      return 1;
   }
   al_register_event_source(queue, al_get_display_event_source(display));
   al_register_event_source(queue, al_get_keyboard_event_source());
   al_register_event_source(queue, al_get_mouse_event_source());
   al_register_event_source(queue, al_get_timer_event_source(timer));

   /* Note:
    * Right now, A5 video displays can only be accessed from the thread which
    * created them (at lesat for OpenGL). To lift this restriction, we could
    * keep track of the current OpenGL context for each thread and make all
    * functions accessing the display check for it.. not sure it's worth the
    * additional complexity though.
    */
   al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_RGB_888);
   al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
   for (i = 0; i < NUM_THREADS; i++) {
      thread_info[i].bitmap = al_create_bitmap(W, H);
      if (!thread_info[i].bitmap) {
         goto Error;
      }
      thread_info[i].mutex = al_create_mutex();
      if (!thread_info[i].mutex) {
         goto Error;
      }
      thread_info[i].cond = al_create_cond();
      if (!thread_info[i].cond) {
         goto Error;
      }
      thread_info[i].is_paused = false;
      thread_info[i].random_seed = i;
      thread[i] = al_create_thread(thread_func, &thread_info[i]);
      if (!thread[i]) {
         goto Error;
      }
   }
   set_target(0, -0.56062033041600878303, -0.56064322926933807256);
   set_target(1, -0.57798076669230014080, -0.63449861991138123418);
   set_target(2,  0.36676836392830602929, -0.59081385302214906030);
   set_target(3, -1.48319283039401317303, -0.00000000200514696273);
   set_target(4, -0.74052910500707636032,  0.18340899525730713915);
   set_target(5,  0.25437906525768350097, -0.00046678223345789554);
   set_target(6, -0.56062033041600878303,  0.56064322926933807256);
   set_target(7, -0.57798076669230014080,  0.63449861991138123418);
   set_target(8,  0.36676836392830602929,  0.59081385302214906030);

   for (i = 0; i < NUM_THREADS; i++) {
      al_start_thread(thread[i]);
   }
   al_start_timer(timer);

   need_draw = true;
   while (true) {
      if (need_draw && al_event_queue_is_empty(queue)) {
         show_images();
         need_draw = false;
      }

      al_wait_for_event(queue, &event);
      if (event.type == ALLEGRO_EVENT_TIMER) {
         need_draw = true;
      }
      else if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {
         int n = (event.mouse.y / H) * IMAGES_PER_ROW + (event.mouse.x / W);
         if (n < NUM_THREADS) {
            double x = event.mouse.x - (event.mouse.x / W) * W;
            double y = event.mouse.y - (event.mouse.y / H) * H;
            /* Center to the mouse click position. */
            if (thread_info[n].is_paused) {
               thread_info[n].target_x = x / W - 0.5;
               thread_info[n].target_y = y / H - 0.5;
            }
            toggle_pausedness(n);
         }
      }
      else if (event.type == ALLEGRO_EVENT_DISPLAY_EXPOSE) {
         need_draw = true;
      }
      else if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
         break;
      }
      else if (event.type == ALLEGRO_EVENT_KEY_DOWN) {
         if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
            break;
         }
         need_draw = true;
      }
   }

   for (i = 0; i < NUM_THREADS; i++) {
      /* Set the flag to stop the thread.  The thread might be waiting on a
       * condition variable, so signal the condition to force it to wake up.
       */
      al_set_thread_should_stop(thread[i]);
      al_lock_mutex(thread_info[i].mutex);
      al_broadcast_cond(thread_info[i].cond);
      al_unlock_mutex(thread_info[i].mutex);

      /* al_destroy_thread() implicitly joins the thread, so this call is not
       * strictly necessary.
       */
      al_join_thread(thread[i], NULL);
      al_destroy_thread(thread[i]);
   }

   al_destroy_event_queue(queue);
   al_uninstall_timer(timer);
   al_destroy_display(display);

   return 0;

Error:

   return 1;
}
Пример #13
0
static bool open_video(ALLEGRO_VIDEO *video)
{
   VideoState *is = av_mallocz(sizeof *is);
   int i;
   AVRational fps;

   is->video = video;
   
   init();
   
   video->data = is;
   strncpy(is->filename, al_path_cstr(video->filename, '/'),
      sizeof(is->filename));
   
   is->av_sync_type = DEFAULT_AV_SYNC_TYPE;

   // Open video file
   #ifdef FFMPEG_0_8
   if (avformat_open_input(&is->format_context, is->filename, NULL,
      NULL) != 0) { 	
   #else
   if (av_open_input_file(&is->format_context, is->filename, NULL, 0,
      NULL) != 0) {
   #endif
      av_free(is);
      return false;
   }

   if (av_find_stream_info(is->format_context) < 0) {
      av_free(is);
      return false;
   }

   is->video_index = -1;
   is->audio_index = -1;
   for (i = 0; i < (int)is->format_context->nb_streams; i++) {
      if (is->format_context->streams[i]->codec->codec_type
         == AVMEDIA_TYPE_VIDEO && is->video_index < 0)
      {
         is->video_index = i;
      }
      if (is->format_context->streams[i]->codec->codec_type
         == AVMEDIA_TYPE_AUDIO && is->audio_index < 0)
      {
         is->audio_index = i;
      }
   }
   
   fps = is->format_context->streams[is->video_index]->r_frame_rate;
   video->fps = (double)fps.num / fps.den;
   video->audio_rate = is->format_context->streams[is->audio_index]->
      codec->sample_rate;
   video->width = is->format_context->streams[is->video_index]->codec->width;
   video->height = is->format_context->streams[is->video_index]->codec->height;

   is->pictq_mutex = al_create_mutex();
   is->pictq_cond = al_create_cond();
   
   is->timer_mutex = al_create_mutex();
   is->timer_cond = al_create_cond();

   return true;
}

static bool close_video(ALLEGRO_VIDEO *video)
{
   VideoState *is = video->data;
   
   is->quit = true;
   
   if (is->timer_thread) {
   
      al_lock_mutex(is->timer_mutex);
      al_signal_cond(is->timer_cond);
      al_unlock_mutex(is->timer_mutex);
   
      al_join_thread(is->timer_thread, NULL);
   }
   
   if (is->parse_thread) {
      al_join_thread(is->parse_thread, NULL);
   }

   al_destroy_mutex(is->timer_mutex);
   al_destroy_cond(is->timer_cond);

   av_free(is);
   return true;
}
Пример #14
0
int main(int argc, char **argv)
{
   ALLEGRO_DISPLAY *display;
   ALLEGRO_TIMER *timer;
   ALLEGRO_EVENT_QUEUE *queue;
   bool redraw = true;
   ALLEGRO_FONT *font;
   ALLEGRO_BITMAP *spin, *spin2;
   int current_bitmap = 0;
   int loaded_bitmap = 0;
   ALLEGRO_THREAD *thread;

   (void)argc;
   (void)argv;

   if (!al_init()) {
      abort_example("Could not init Allegro.\n");
   }
   al_init_image_addon();
   al_init_font_addon();
   al_init_primitives_addon();
   init_platform_specific();

   open_log();

   al_install_mouse();
   al_install_keyboard();

   spin = al_load_bitmap("data/cursor.tga");
   log_printf("default bitmap without display: %p\n", spin);

   al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
   spin2 = al_load_bitmap("data/cursor.tga");
   log_printf("video bitmap without display: %p\n", spin2);
   
   log_printf("%p before create_display: ", spin);
   print_bitmap_flags(spin);
   log_printf("\n");

   display = al_create_display(64, 64);
   if (!display) {
      abort_example("Error creating display\n");
   }
   
   spin2 = al_load_bitmap("data/cursor.tga");
   log_printf("video bitmap with display: %p\n", spin2);
   
   log_printf("%p after create_display: ", spin);
   print_bitmap_flags(spin);
   log_printf("\n");
   
   log_printf("%p after create_display: ", spin2);
   print_bitmap_flags(spin2);
   log_printf("\n");

   al_destroy_display(display);
   
   log_printf("%p after destroy_display: ", spin);
   print_bitmap_flags(spin);
   log_printf("\n");
   
   log_printf("%p after destroy_display: ", spin2);
   print_bitmap_flags(spin2);
   log_printf("\n");

   display = al_create_display(640, 480);
   
   log_printf("%p after create_display: ", spin);
   print_bitmap_flags(spin);
   log_printf("\n");
   
   log_printf("%p after create_display: ", spin2);
   print_bitmap_flags(spin2);
   log_printf("\n");

   font = al_load_font("data/fixed_font.tga", 0, 0);

   mutex = al_create_mutex();
   thread = al_create_thread(loading_thread, NULL);
   al_start_thread(thread);

   timer = al_create_timer(1.0 / 30);
   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);

   while (1) {
      ALLEGRO_EVENT event;
      al_wait_for_event(queue, &event);

      if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
         break;
      if (event.type == ALLEGRO_EVENT_KEY_DOWN) {
         if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
             break;
         }
      if (event.type == ALLEGRO_EVENT_TIMER)
         redraw = true;

      if (redraw && al_is_event_queue_empty(queue)) {
         float x = 20, y = 320;
         int i;
         ALLEGRO_COLOR color = al_map_rgb_f(0, 0, 0);
         float t = al_current_time();

         redraw = false;
         al_clear_to_color(al_map_rgb_f(0.5, 0.6, 1));
         
         al_draw_textf(font, color, x + 40, y, 0, "Loading %d%%",
            100 * load_count / load_total);

         al_lock_mutex(mutex);
         if (loaded_bitmap < load_count) {
            /* This will convert any video bitmaps without a display
             * (all the bitmaps being loaded in the loading_thread) to
             * video bitmaps we can use in the main thread.
             */
            al_convert_bitmap(bitmaps[loaded_bitmap]);
            loaded_bitmap++;
         }
         al_unlock_mutex(mutex);

         if (current_bitmap < loaded_bitmap) {
            int bw;
            al_draw_bitmap(bitmaps[current_bitmap], 0, 0, 0);
            if (current_bitmap + 1 < loaded_bitmap)
               current_bitmap++;

            for (i = 0; i <= current_bitmap; i++) {
               bw = al_get_bitmap_width(bitmaps[i]);
               al_draw_scaled_rotated_bitmap(bitmaps[i],
                  0, 0, (i % 20) * 640 / 20, 360 + (i / 20) * 24,
                  32.0 / bw, 32.0 / bw, 0, 0);
            }
         }
         
         if (loaded_bitmap < load_total) {
            al_draw_scaled_rotated_bitmap(spin,
               16, 16, x, y, 1.0, 1.0, t * ALLEGRO_PI * 2, 0);
         }
         
         al_flip_display();
      }
   }

   al_join_thread(thread, NULL);
   al_destroy_mutex(mutex);
   al_destroy_font(font); 
   al_destroy_display(display);

   close_log(true);

   return 0;
}