Beispiel #1
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);
   }
}
Beispiel #2
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);
}
Beispiel #3
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;
}
Beispiel #4
0
void *CreateDisplay(ALLEGRO_THREAD *thr, void *arg)
{
    DISPLAY_DATA *data = (DISPLAY_DATA*) arg;   
    ALLEGRO_DISPLAY *display;

    ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue();
    if(!queue) {
        fprintf(stderr, "failed to create event queue");
        return NULL;
    }

    al_lock_mutex(data->mutex);

    display = AllegroNewDisplay(data->sizeX, data->sizeY, queue);
    al_broadcast_cond(data->cond);

    // Define the size of the image
    Window<int> scr(0, data->sizeX, 0, data->sizeY);
    // Define the domain in which we test for points
    Window<double> fract(data->zoomXmin, data->zoomXmax, data->zoomYmin, data->zoomYmax);
    
    al_unlock_mutex(data->mutex);

    // Generate the fractal
    Mandelbrot(scr, fract);

    while(!al_get_thread_should_stop(thr)) {
        ALLEGRO_EVENT ev;
        al_wait_for_event(queue, &ev);

        if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
            al_set_thread_should_stop(thr);
            al_lock_mutex(data->mutex);
            al_broadcast_cond(data->cond);
            al_unlock_mutex(data->mutex);
            break;
        }       
    }

    al_destroy_display(display);
    al_destroy_event_queue(queue);
}
Beispiel #5
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;
}
Beispiel #6
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;
}