static void *thread_func(ALLEGRO_THREAD *thr, void *arg) { ThreadInfo *info = (ThreadInfo *) arg; Viewport viewport; unsigned char palette[256][3]; int y, w, h; y = 0; w = al_get_bitmap_width(info->bitmap); h = al_get_bitmap_height(info->bitmap); viewport.centre_x = info->target_x; viewport.centre_y = info->target_y; viewport.x_extent = 3.0; viewport.y_extent = 3.0; viewport.zoom = 1.0; info->target_x = 0; info->target_y = 0; while (!al_get_thread_should_stop(thr)) { al_lock_mutex(info->mutex); while (info->is_paused) { al_wait_cond(info->cond, info->mutex); /* We might be awoken because the program is terminating. */ if (al_get_thread_should_stop(thr)) { break; } } if (!info->is_paused) { if (y == 0) { random_palette(palette, &info->random_seed); } draw_mandel_line(info->bitmap, &viewport, palette, y); y++; if (y >= h) { double z = viewport.zoom; y = 0; viewport.centre_x += z * viewport.x_extent * info->target_x; viewport.centre_y += z * viewport.y_extent * info->target_y; info->target_x = 0; info->target_y = 0; viewport.zoom *= 0.99; } } al_unlock_mutex(info->mutex); al_rest(0); } return NULL; }
static void *Func_Thread(ALLEGRO_THREAD *thr, void *arg){ DATA *data = (DATA*) arg; float num = 0.1; al_lock_mutex(data->mutex); bool modi_X = data->modi_X; data->ready = true; al_broadcast_cond(data->cond); al_unlock_mutex(data->mutex); while(!al_get_thread_should_stop(thr)){ al_lock_mutex(data->mutex); if(modi_X) data->posiX += num; else data->posiY += num; al_unlock_mutex(data->mutex); al_rest(0.01); } return NULL; }
static void *sound_update_proc(ALLEGRO_THREAD *thread, void *arg) { ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; (void)arg; queue = al_create_event_queue(); al_register_event_source(queue, al_get_timer_event_source(ping_timer)); if (music_timer) al_register_event_source(queue, al_get_timer_event_source(music_timer)); while (!al_get_thread_should_stop(thread)) { if (!al_wait_for_event_timed(queue, &event, 0.25)) continue; if (event.any.source == (void *)music_timer) music_player(); if (event.any.source == (void *)ping_timer) { if (!ping_proc()) al_stop_timer(ping_timer); } } al_destroy_event_queue(queue); return NULL; }
static void * threadedSegment(ALLEGRO_THREAD *read_thread, void *arg) { while(!al_get_thread_should_stop(read_thread)) { map_segment.lockRead(); read_segment(arg); map_segment.unlockRead(); al_rest(ssConfig.automatic_reload_time/1000.0); } return 0; }
static void *wakeup_thread(ALLEGRO_THREAD *thread, void *user) { al_rest(1); while (!al_get_thread_should_stop(thread)) { /* If the program uses timers, this hack is not required usually. */ if (_al_get_active_timers_count()) break; if (!al_is_keyboard_installed()) break; wakeup_with_fake_timer_event(); al_rest(0.01); } return user; }
void * kresliace_vlakno(ALLEGRO_THREAD *thread, void *event_queue) { ALLEGRO_DISPLAY *display = NULL; display = al_create_display(640, 480); if (!display) { fprintf(stderr, "failed to create display!\n"); exit(1); } al_register_event_source(event_queue, al_get_display_event_source(display)); while (!al_get_thread_should_stop(thread)) { al_clear_to_color(al_map_rgb(100,0,100)); int i = 0; al_lock_mutex(mutex); // struct Player * _player = player_copy(player); struct List *kopia_sceny = list_deep_copy(scena, objekt_copy); al_unlock_mutex(mutex); /* for (i = 0; i < 300; i++) { player_draw(_player); }*/ struct List *iterator = kopia_sceny; for (; iterator != NULL; iterator = iterator->next) { struct Objekt *obj = iterator->item; obj->draw(obj->objekt); } //zmazeme kopie objektov z kopie sceny iterator = kopia_sceny; for (; iterator != NULL; iterator = iterator->next) { struct Objekt *obj = iterator->item; obj->destroy(obj->objekt); free(obj); } //zmazeme kopiu sceny // list_destroy(kopia_sceny); // player_destroy(_player); al_flip_display(); } al_unregister_event_source(event_queue, al_get_display_event_source(display)); al_destroy_display(display); }
static void *pulseaudio_update(ALLEGRO_THREAD *self, void *data) { ALLEGRO_VOICE *voice = data; PULSEAUDIO_VOICE *pv = voice->extra; while (!al_get_thread_should_stop(self)) { if (pv->status == PV_PLAYING) { unsigned int frames = 4096; if (voice->is_streaming) { // streaming audio const void *data = _al_voice_update(voice, &frames); if (data) { pa_simple_write(pv->s, data, frames * pv->frame_size, NULL); } } else { // direct buffer audio al_lock_mutex(pv->buffer_mutex); const char *data = pv->buffer; unsigned int len = frames * pv->frame_size; pv->buffer += frames * pv->frame_size; if (pv->buffer > pv->buffer_end) { len = pv->buffer_end - data; pv->buffer = voice->attached_stream->spl_data.buffer.ptr; voice->attached_stream->pos = 0; if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) { pv->status = PV_STOPPING; } } else { voice->attached_stream->pos += frames; } al_unlock_mutex(pv->buffer_mutex); pa_simple_write(pv->s, data, len, NULL); } } else if (pv->status == PV_STOPPING) { pa_simple_flush(pv->s, NULL); pv->status = PV_STOPPED; } else if (pv->status == PV_STOPPED) { al_rest(0.001); } } return NULL; }
/* Function for the haptics polling thread. */ static void *hapxi_poll_thread(ALLEGRO_THREAD *thread, void *arg) { ALLEGRO_TIMEOUT timeout; al_lock_mutex(hapxi_mutex); while (!al_get_thread_should_stop(thread)) { /* Poll once every 10 milliseconds. XXX: Should this be configurable? */ al_init_timeout(&timeout, ALLEGRO_XINPUT_POLL_DELAY); /* Wait for the condition to allow the polling thread to be awoken when needed. */ al_wait_cond_until(hapxi_cond, hapxi_mutex, &timeout); /* If we get here poll joystick for new input or connection * and dispatch events. */ hapxi_poll_haptics(); } al_unlock_mutex(hapxi_mutex); return arg; }
static void *loading_thread(ALLEGRO_THREAD *thread, void *arg) { ALLEGRO_FONT *font; ALLEGRO_COLOR text; font = al_load_font("data/fixed_font.tga", 0, 0); text = al_map_rgb_f(255, 255, 255); /* In this example we load mysha.pcx 100 times to simulate loading * many bitmaps. */ load_count = 0; while (load_count < load_total) { ALLEGRO_COLOR color; ALLEGRO_BITMAP *bmp; color = al_map_rgb(rand() % 256, rand() % 256, rand() % 256); color.r /= 4; color.g /= 4; color.b /= 4; color.a /= 4; if (al_get_thread_should_stop(thread)) break; bmp = al_load_bitmap("data/mysha.pcx"); /* Simulate different contents. */ al_set_target_bitmap(bmp); al_draw_filled_rectangle(0, 0, 320, 200, color); al_draw_textf(font, text, 0, 0, 0, "bitmap %d", 1 + load_count); al_set_target_bitmap(NULL); /* Allow the main thread to see the completed bitmap. */ al_lock_mutex(mutex); bitmaps[load_count] = bmp; load_count++; al_unlock_mutex(mutex); /* Simulate that it's slow. */ al_rest(0.05); } al_destroy_font(font); return arg; }
static void *pulse_audio_update_recorder(ALLEGRO_THREAD *t, void *data) { ALLEGRO_AUDIO_RECORDER *r = (ALLEGRO_AUDIO_RECORDER *) data; PULSEAUDIO_RECORDER *pa = (PULSEAUDIO_RECORDER *) r->extra; ALLEGRO_EVENT user_event; uint8_t *null_buffer; unsigned int fragment_i = 0; null_buffer = al_malloc(1024); if (!null_buffer) { ALLEGRO_ERROR("Unable to create buffer for draining PulseAudio.\n"); return NULL; } while (!al_get_thread_should_stop(t)) { al_lock_mutex(r->mutex); if (!r->is_recording) { /* Even if not recording, we still want to read from the PA server. Otherwise it will buffer everything and spit it all out whenever the recording resumes. */ al_unlock_mutex(r->mutex); pa_simple_read(pa->s, null_buffer, 1024, NULL); } else { ALLEGRO_AUDIO_RECORDER_EVENT *e; al_unlock_mutex(r->mutex); if (pa_simple_read(pa->s, r->fragments[fragment_i], r->fragment_size, NULL) >= 0) { user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; e = al_get_audio_recorder_event(&user_event); e->buffer = r->fragments[fragment_i]; e->samples = r->samples; al_emit_user_event(&r->source, &user_event, NULL); if (++fragment_i == r->fragment_count) { fragment_i = 0; } } } } al_free(null_buffer); return 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); }
static void *hotplug_proc(ALLEGRO_THREAD *thread, void *data) { (void)data; while (!al_get_thread_should_stop(thread)) { if (!hotplug_ended) { al_wait_cond(hotplug_cond, hotplug_mutex); } if (hotplug_ended) { break; } al_rest(1); al_lock_mutex(config_mutex); ljoy_scan(true); al_unlock_mutex(config_mutex); } hotplug_ended = false; return NULL; }
void * dumba5_update_thread(ALLEGRO_THREAD * thread, void * arg) { DUMBA5_PLAYER * dp = (DUMBA5_PLAYER *)arg; ALLEGRO_EVENT_QUEUE * queue; unsigned short *fragment; long n; long size; int n_channels; queue = al_create_event_queue(); al_register_event_source(queue, al_get_audio_stream_event_source(dp->stream)); while(1) { ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if(event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) { fragment = (unsigned short *)al_get_audio_stream_fragment(dp->stream); if(!fragment) { return NULL; } n = duh_render(dp->sigrenderer, 16, 0, dp->volume, 65536.0 / dp->freq, dp->bufsize, fragment); if (n == 0) { if (++dp->silentcount >= 2) { duh_end_sigrenderer(dp->sigrenderer); if(!al_set_audio_stream_fragment(dp->stream, fragment)) { } al_destroy_audio_stream(dp->stream); dp->sigrenderer = NULL; return NULL; } } n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer); n *= n_channels; size = dp->bufsize * n_channels; for (; n < size; n++) { fragment[n] = 0x8000; } if(!al_set_audio_stream_fragment(dp->stream, fragment)) { } } if(al_get_thread_should_stop(thread)) { break; } } al_destroy_event_queue(queue); return NULL; }
/* TODO: review */ static void *_openal_update(ALLEGRO_THREAD *self, void *arg) { ALLEGRO_VOICE *voice = (ALLEGRO_VOICE*) arg; ALLEGRO_AL_DATA *ex_data = (ALLEGRO_AL_DATA*)voice->extra; unsigned int i, samples_per_update; unsigned int bytes_per_sample; const void *data; void *silence; /* Streams should not be set to looping */ alSourcei(ex_data->source, AL_LOOPING, AL_FALSE); silence = al_calloc(1, ex_data->buffer_size); if (ex_data->format == AL_FORMAT_STEREO8 || ex_data->format == AL_FORMAT_MONO8) { memset(silence, 0x80, ex_data->buffer_size); } for (i = 0; i < ex_data->num_buffers; i++) { alBufferData(ex_data->buffers[i], ex_data->format, silence, ex_data->buffer_size, voice->frequency); } alSourceQueueBuffers(ex_data->source, ex_data->num_buffers, ex_data->buffers); alSourcePlay(ex_data->source); switch (ex_data->format) { case AL_FORMAT_STEREO16: bytes_per_sample = 4; break; case AL_FORMAT_STEREO8: case AL_FORMAT_MONO16: bytes_per_sample = 2; break; default: bytes_per_sample = 1; break; } samples_per_update = ex_data->buffer_size / bytes_per_sample; data = silence; while (!al_get_thread_should_stop(self)) { ALint status = 0; alGetSourcei(ex_data->source, AL_BUFFERS_PROCESSED, &status); if (status <= 0) { /* FIXME what is this for ? */ al_rest(0.001); continue; } while (--status >= 0) { ALuint buffer; data = _al_voice_update(voice, voice->mutex, &samples_per_update); if (data == NULL) data = silence; alSourceUnqueueBuffers(ex_data->source, 1, &buffer); alBufferData(buffer, ex_data->format, data, samples_per_update * bytes_per_sample, voice->frequency); alSourceQueueBuffers(ex_data->source, 1, &buffer); } alGetSourcei(ex_data->source, AL_SOURCE_STATE, &status); if (status == AL_STOPPED) { alSourcePlay(ex_data->source); } } alSourceStop(ex_data->source); al_free(silence); ex_data->stopped = true; al_broadcast_cond(voice->cond); return NULL; }
static void *_dsound_update_recorder(ALLEGRO_THREAD *t, void *data) { ALLEGRO_AUDIO_RECORDER *r = (ALLEGRO_AUDIO_RECORDER *) data; DSOUND_RECORD_DATA *extra = (DSOUND_RECORD_DATA *) r->extra; DWORD last_read_pos = 0; ALLEGRO_EVENT user_event; bool is_dsound_recording = false; size_t fragment_i = 0; size_t bytes_written = 0; ALLEGRO_INFO("Starting recorder thread\n"); while (!al_get_thread_should_stop(t)) { al_lock_mutex(r->mutex); while (!r->is_recording) { if (is_dsound_recording) { extra->buffer8->Stop(); is_dsound_recording = false; } al_wait_cond(r->cond, r->mutex); if (al_get_thread_should_stop(t)) goto stop_recording; } if (!is_dsound_recording) { extra->buffer8->Start(DSCBSTART_LOOPING); is_dsound_recording = true; extra->buffer8->GetCurrentPosition(NULL, &last_read_pos); } void *buffer1, *buffer2; DWORD buffer1_size, buffer2_size; DWORD cap_pos, bytes_to_read; extra->buffer8->GetCurrentPosition(NULL, &cap_pos); /* never read past the end of the buffer; that way buffer2 is always NULL */ if (last_read_pos <= cap_pos) bytes_to_read = cap_pos - last_read_pos; else bytes_to_read = extra->desc.dwBufferBytes - last_read_pos; if (bytes_to_read) { uint8_t *buffer; size_t buffer_size; extra->buffer8->Lock(last_read_pos, bytes_to_read, &buffer1, &buffer1_size, &buffer2, &buffer2_size, 0); ALLEGRO_ASSERT(buffer2 == NULL); buffer = (uint8_t *)buffer1; buffer_size = buffer1_size; while (buffer_size > 0) { if (bytes_written + buffer_size <= r->fragment_size) { memcpy((uint8_t*) r->fragments[fragment_i] + bytes_written, buffer, buffer_size); bytes_written += buffer_size; buffer_size = 0; } else { ALLEGRO_AUDIO_RECORDER_EVENT *e; size_t bytes_to_write = r->fragment_size - bytes_written; memcpy((uint8_t*) r->fragments[fragment_i] + bytes_written, buffer, bytes_to_write); buffer_size -= bytes_to_write; buffer += bytes_to_write; user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; e = al_get_audio_recorder_event(&user_event); e->buffer = r->fragments[fragment_i]; e->samples = r->samples; al_emit_user_event(&r->source, &user_event, NULL); /* advance to the next fragment */ if (++fragment_i == r->fragment_count) { fragment_i = 0; } bytes_written = 0; } } extra->buffer8->Unlock(buffer1, buffer1_size, buffer2, buffer2_size); /* advanced the last read position */ last_read_pos += bytes_to_read; if (last_read_pos >= extra->desc.dwBufferBytes) last_read_pos -= extra->desc.dwBufferBytes; } al_unlock_mutex(r->mutex); al_rest(0.10); } stop_recording: if (is_dsound_recording) { extra->buffer8->Stop(); } ALLEGRO_INFO("Leaving recorder thread\n"); return NULL; }