static void _uninstall_sdl_event_hack(void) { if (thread) { al_set_thread_should_stop(thread); al_join_thread(thread, NULL); al_destroy_thread(thread); } }
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); }
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; }
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); }
/* 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; }
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; }