void network_poll( ENetHost* socket ) { ALLEGRO_EVENT e; ENetEvent ev; if( socket == 0 ) return; while( enet_host_service( socket, &ev, 0 ) > 0 ) { e.user.data1 = (intptr_t)ev.peer; e.user.data2 = (intptr_t)ev.packet; e.user.data3 = 0; switch( ev.type ) { case ENET_EVENT_TYPE_CONNECT: e.type = ALLEGRO_EVENT_NETWORK_CONNECTION; al_emit_user_event( &netEventSource, &e, &network_event_destructor ); break; case ENET_EVENT_TYPE_RECEIVE: e.type = ALLEGRO_EVENT_NETWORK_RECEIVEPACKET; al_emit_user_event( &netEventSource, &e, &network_event_destructor ); break; case ENET_EVENT_TYPE_DISCONNECT: e.type = ALLEGRO_EVENT_NETWORK_DISCONNECTION; al_emit_user_event( &netEventSource, &e, &network_event_destructor ); break; } } }
int main(int argc, char **argv) { ALLEGRO_EVENT_SOURCE fake_src; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT fake_keydown_event, fake_joystick_event; ALLEGRO_EVENT event; (void)argc; (void)argv; if (!al_init()) { abort_example("Could not init Allegro.\n"); } open_log(); /* register our 'fake' event source with the queue */ al_init_user_event_source(&fake_src); queue = al_create_event_queue(); al_register_event_source(queue, &fake_src); /* fake a joystick event */ fake_joystick_event.any.type = ALLEGRO_EVENT_JOYSTICK_AXIS; fake_joystick_event.joystick.stick = 1; fake_joystick_event.joystick.axis = 0; fake_joystick_event.joystick.pos = 0.5; al_emit_user_event(&fake_src, &fake_joystick_event, NULL); /* fake a keyboard event */ fake_keydown_event.any.type = ALLEGRO_EVENT_KEY_DOWN; fake_keydown_event.keyboard.keycode = ALLEGRO_KEY_ENTER; al_emit_user_event(&fake_src, &fake_keydown_event, NULL); /* poll for the events we injected */ while (!al_is_event_queue_empty(queue)) { al_wait_for_event(queue, &event); switch (event.type) { case ALLEGRO_EVENT_KEY_DOWN: ALLEGRO_ASSERT(event.user.source == &fake_src); log_printf("Got keydown: %d\n", event.keyboard.keycode); break; case ALLEGRO_EVENT_JOYSTICK_AXIS: ALLEGRO_ASSERT(event.user.source == &fake_src); log_printf("Got joystick axis: stick=%d axis=%d pos=%f\n", event.joystick.stick, event.joystick.axis, event.joystick.pos); break; } } al_destroy_user_event_source(&fake_src); al_destroy_event_queue(queue); log_printf("Done.\n"); close_log(true); return 0; }
//!Handles allegro events for the sword weapon class void SwordWeapon::EventHandler() { //if the weapon is active watch the active timer if(m_IsActive) { //emit the event source that the projectile has moved m_AlEvent.user.type = CUSTOM_EVENT_ID(MELEEATTACK_EVENT); m_AlEvent.user.data1 = m_LastDrawnXPosition; m_AlEvent.user.data2 = m_LastDrawnYPosition; al_emit_user_event(&m_SwordActiveEventSource, &m_AlEvent, NULL); m_OnActive = false; //Update the weapon sprite tile m_SwordWeaponTile.Event_Handler(); //iterate the timer m_CurrentAttackCount++; //if the active timer is reached if(m_CurrentAttackCount >= m_AttackTime) { //make weapon unactive and reset timer m_IsActive = false; m_CurrentAttackCount = 0; m_OnActive = true; } } }
void on_message_receive(std::string message) override { ALLEGRO_EVENT user_event; user_event.type = ALLEGRO_EVENT_NETWORK_RECEIVE_MESSAGE; std::string *msg = new std::string(message); user_event.user.data1 = (intptr_t)(msg); al_emit_user_event(&network_event_source->event_source, &user_event, my_network_event_dtor); }
void UserEventEmitter::emit_event(int32_t event_type, intptr_t data1, intptr_t data2) { ALLEGRO_EVENT my_event; my_event.user.type = event_type; my_event.user.data1 = data1; my_event.user.data2 = data2; al_emit_user_event(&get_instance()->event_source, &my_event, NULL); // dtor is not needed for this type }
void AllegroEventSource::fire(intptr_t data1, intptr_t data2, intptr_t data3, intptr_t data4) { event.type=eventID; event.user.data1=data1; event.user.data2=data2; event.user.data3=data3; event.user.data4=data4; al_emit_user_event(&event_source, &event, nullptr); }
static void emit_close_event(ALLEGRO_NATIVE_DIALOG *textlog, bool keypress) { ALLEGRO_EVENT event; event.user.type = ALLEGRO_EVENT_NATIVE_DIALOG_CLOSE; event.user.timestamp = al_get_time(); event.user.data1 = (intptr_t)textlog; event.user.data2 = (intptr_t)keypress; al_emit_user_event(&textlog->tl_events, &event, NULL); }
void connection_update() { if (!host) return; ENetEvent ev; while (enet_host_service(host, &ev, 0)) { switch (ev.type) { case ENET_EVENT_TYPE_CONNECT: { if (connection_is_host()) { uint32_t new_sender_id = list_push(peers, ev.peer) + 1; connection_send_to( USER_ID_ASSIGN_PACKET, CHANNEL_COUNT - 1, (const char *)&new_sender_id, sizeof(new_sender_id), ev.peer ); } break; } case ENET_EVENT_TYPE_DISCONNECT: if (connection_is_host()) { size_t i; if (list_index_of(peers, ev.peer, &i)) { list_remove(peers, i); } } break; case ENET_EVENT_TYPE_RECEIVE: if (connection_is_host()) { broadcast_except(ev.peer, ev.packet, ev.channelID); } if (ev.channelID > 0) { uint32_t sender_id, id; char *data = NULL; size_t data_len; unpack_format((char *)ev.packet->data, "uua", &sender_id, &id, &data, &data_len); ALLEGRO_EVENT event; event.type = CONNECTION_RECEIVE_EVENT_ID; event.user.data1 = id; event.user.data2 = (intptr_t)data; event.user.data3 = sender_id; al_emit_user_event(&event_source, &event, NULL); } else { //channel 0 is exclusive for entity updates entity_sync((const char *)ev.packet->data); } break; case ENET_EVENT_TYPE_NONE: break; } } }
static int queue_picture(VideoState * is, AVFrame * pFrame, double pts) { VideoPicture *vp; if (!is->first) { is->first = true; is->external_clock_start = av_gettime(); } /* wait until we have space for a new pic */ al_lock_mutex(is->pictq_mutex); while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE && !is->quit) { al_wait_cond(is->pictq_cond, is->pictq_mutex); } al_unlock_mutex(is->pictq_mutex); if (is->quit) return -1; // windex is set to 0 initially vp = &is->pictq[is->pictq_windex]; vp->dropped = false; { ALLEGRO_EVENT event; vp->frame = pFrame; vp->pts = pts; vp->allocated = 0; /* we have to do it in the main thread */ //printf("allocate %d (%4.1f ms)\n", is->pictq_windex, // get_master_clock(is) * 1000); event.type = ALLEGRO_EVENT_VIDEO_FRAME_ALLOC; event.user.data1 = (intptr_t)is->video; al_emit_user_event(&is->video->es, &event, NULL); /* wait until we have a picture allocated */ al_lock_mutex(is->pictq_mutex); is->got_picture++; while (!vp->allocated && !is->quit) { al_wait_cond(is->pictq_cond, is->pictq_mutex); } al_unlock_mutex(is->pictq_mutex); if (is->quit) { return -1; } } return 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; }
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; };
bool connection_host(uint16_t port, size_t max_players) { destroy_host(); ENetAddress address; address.host = ENET_HOST_ANY; address.port = port; host = enet_host_create(&address, max_players, CHANNEL_COUNT, 0, 0); if (host) { entity_reset_all(); ALLEGRO_EVENT event; event.type = CONNECTION_JOIN_EVENT_ID; al_emit_user_event(&event_source, &event, NULL); } return host != NULL; }
/* Each platform implementation must call this when a menu has been clicked. * The display parameter should be sent if at all possible! If it isn't sent, * and the user is using non-unique ids, it won't know which display actually * triggered the menu click. */ bool _al_emit_menu_event(ALLEGRO_DISPLAY *display, uint16_t unique_id) { ALLEGRO_EVENT event; _AL_MENU_ID *menu_id = NULL; ALLEGRO_EVENT_SOURCE *source = al_get_default_menu_event_source(); /* try to find the menu that triggered the event */ menu_id = _al_find_parent_menu_by_id(display, unique_id); if (menu_id->id == 0) return false; if (menu_id) { /* A menu was found associated with the id. See if it has an * event source associated with it, and adjust "source" accordingly. */ ALLEGRO_MENU *m = menu_id->menu; while (true) { if (m->is_event_source) { source = &m->es; break; } if (!m->parent) break; /* m->parent is of type MENU_ITEM, * which always has a parent of type MENU */ ASSERT(m->parent->parent); m = m->parent->parent; } } event.user.type = ALLEGRO_EVENT_MENU_CLICK; event.user.data1 = menu_id->id; event.user.data2 = (intptr_t) display; event.user.data3 = (intptr_t) menu_id->menu; al_emit_user_event(source, &event, NULL); return true; }
void _al_kcm_emit_stream_events(ALLEGRO_AUDIO_STREAM *stream) { /* Emit one event for each stream fragment available right now. * * There may already be an event corresponding to an available fragment in * some event queue, but there's nothing we can do about that. Streams may * be added and removed from queues, events may be lost by the user, etc. * so it would be dangerous to assume that each fragment event would be * responded to, once and exactly once. * * Having said that, event queues are empty in the steady state so it is * relatively rare that this situation occurs. */ int count = al_get_available_audio_stream_fragments(stream); while (count--) { ALLEGRO_EVENT event; event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT; event.user.timestamp = al_get_time(); al_emit_user_event(&stream->spl.es, &event, NULL); } }
void connection_on_event(ALLEGRO_EVENT *event) { if (event->type == CONNECTION_RECEIVE_EVENT_ID) { if ((uint32_t)event->user.data1 == USER_ID_ASSIGN_PACKET) { uint32_t *new_id = (uint32_t *)event->user.data2; user_id = *new_id; ALLEGRO_EVENT event; event.type = CONNECTION_JOIN_EVENT_ID; al_emit_user_event(&event_source, &event, NULL); entity_reset_all(); } } else if (event->type == CONSOLE_EVENT_ID) { const char *command = (const char *)event->user.data1; char hostname[128]; unsigned int port, max_players; if (sscanf(command, "join %128s %u", hostname, &port) == 2) { connection_join(hostname, port); } else if (sscanf(command, "host %u %u", &port, &max_players) == 2) { connection_host(port, max_players); } } }
void Mouse::Update() { ALLEGRO_EVENT e; ALLEGRO_EVENT ev; while( al_get_next_event( mouseQueue, &e ) ) { switch( e.type ) { case ALLEGRO_EVENT_MOUSE_AXES: Position.X = e.mouse.x; Position.Y = e.mouse.y; if( mouseDownButton != 0 && AllowBoxing && !blockBoxing ) isBoxing = true; if( !AllowBoxing && isBoxing ) isBoxing = false; // Cancel boxing if it has been disabled if( e.mouse.dx != 0 || e.mouse.dy != 0 ) { ev.user.data1 = (intptr_t)this; ev.user.data2 = (intptr_t)malloc( sizeof( Position ) ); memcpy( (void*)ev.user.data2, (void*)&Position, sizeof( Position ) ); ev.user.data3 = (intptr_t)malloc( sizeof( Position ) ); ((Vector2*)ev.user.data3)->X = e.mouse.dx; ((Vector2*)ev.user.data3)->Y = e.mouse.dy; ev.user.data4 = e.mouse.button; ev.type = ALLEGRO_EVENT_MOUSEEX_MOVE; al_emit_user_event( &mouseEventSource, &ev, &Mouse::event_destructor ); } if( e.mouse.dz != 0 ) { ev.user.data1 = (intptr_t)this; ev.user.data2 = (intptr_t)malloc( sizeof( Position ) ); memcpy( (void*)ev.user.data2, (void*)&Position, sizeof( Position ) ); ev.user.data3 = 0; ev.user.data4 = e.mouse.dz; ev.type = ALLEGRO_EVENT_MOUSEEX_WHEEL; al_emit_user_event( &mouseEventSource, &ev, &Mouse::event_destructor ); } break; case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: Position.X = e.mouse.x; Position.Y = e.mouse.y; mouseDownAt.X = e.mouse.x; mouseDownAt.Y = e.mouse.y; mouseDownButton = e.mouse.button; ev.user.data1 = (intptr_t)this; ev.user.data2 = (intptr_t)malloc( sizeof( Position ) ); memcpy( (void*)ev.user.data2, (void*)&Position, sizeof( Position ) ); ev.user.data3 = 0; ev.user.data4 = e.mouse.button; ev.type = ALLEGRO_EVENT_MOUSEEX_DOWN; al_emit_user_event( &mouseEventSource, &ev, &Mouse::event_destructor ); break; case ALLEGRO_EVENT_MOUSE_BUTTON_UP: blockBoxing = false; Position.X = e.mouse.x; Position.Y = e.mouse.y; ev.user.data1 = (intptr_t)this; ev.user.data2 = (intptr_t)malloc( sizeof( Position ) ); memcpy( (void*)ev.user.data2, (void*)&Position, sizeof( Position ) ); ev.user.data3 = 0; ev.user.data4 = e.mouse.button; ev.type = ALLEGRO_EVENT_MOUSEEX_UP; al_emit_user_event( &mouseEventSource, &ev, &Mouse::event_destructor ); if( mouseDownButton == e.mouse.button ) { if( abs( e.mouse.x - mouseDownAt.X ) < ClickFidelity && abs( e.mouse.y - mouseDownAt.Y ) < ClickFidelity ) { ev.user.data2 = (intptr_t)malloc( sizeof( mouseDownAt ) ); memcpy( (void*)ev.user.data2, (void*)&mouseDownAt, sizeof( mouseDownAt ) ); ev.type = ALLEGRO_EVENT_MOUSEEX_CLICK; al_emit_user_event( &mouseEventSource, &ev, &Mouse::event_destructor ); if( al_get_time() - lastClickTime < DoubleClickFidelity && al_get_time() - lastDblClickTime > DoubleClickFidelity ) { ev.user.data2 = (intptr_t)malloc( sizeof( mouseDownAt ) ); memcpy( (void*)ev.user.data2, (void*)&mouseDownAt, sizeof( mouseDownAt ) ); ev.type = ALLEGRO_EVENT_MOUSEEX_DOUBLECLICK; al_emit_user_event( &mouseEventSource, &ev, &Mouse::event_destructor ); lastDblClickTime = al_get_time(); } lastClickTime = al_get_time(); } if( isBoxing ) { ev.user.data2 = (intptr_t)malloc( sizeof( mouseDownAt ) ); ((Vector2*)ev.user.data2)->X = min(mouseDownAt.X, Position.X); ((Vector2*)ev.user.data2)->Y = min(mouseDownAt.Y, Position.Y); ev.user.data3 = (intptr_t)malloc( sizeof( mouseDownAt ) ); ((Vector2*)ev.user.data3)->X = min(mouseDownAt.X, Position.X); ((Vector2*)ev.user.data3)->Y = min(mouseDownAt.Y, Position.Y); ev.type = ALLEGRO_EVENT_MOUSEEX_BOXED; al_emit_user_event( &mouseEventSource, &ev, &Mouse::event_destructor ); isBoxing = false; } mouseDownButton = 0; } break; } } }
static void *decode_thread(ALLEGRO_THREAD *t, void *arg) { VideoState *is = (VideoState *) arg; AVFormatContext *format_context = is->format_context; AVPacket pkt1, *packet = &pkt1; is->videoStream = -1; is->audioStream = -1; if (is->audio_index >= 0) { stream_component_open(is, is->audio_index); } if (is->video_index >= 0) { stream_component_open(is, is->video_index); } if (is->videoStream < 0 && is->audioStream < 0) { ALLEGRO_ERROR("%s: could not open codecs\n", is->filename); goto fail; } for (;;) { if (is->quit) { break; } if (is->seek_req) { int stream_index = -1; int64_t seek_target = is->seek_pos; if (is->videoStream >= 0) stream_index = is->videoStream; else if (is->audioStream >= 0) stream_index = is->audioStream; if (stream_index >= 0) { seek_target = av_rescale_q(seek_target, AV_TIME_BASE_Q, format_context->streams[stream_index]->time_base); } if (av_seek_frame(is->format_context, stream_index, seek_target, is->seek_flags) < 0) { ALLEGRO_WARN("%s: error while seeking (%d, %lu)\n", is->format_context->filename, stream_index, seek_target); } else { if (is->audioStream >= 0) { packet_queue_flush(&is->audioq); packet_queue_put(&is->audioq, &flush_pkt); } if (is->videoStream >= 0) { packet_queue_flush(&is->videoq); packet_queue_put(&is->videoq, &flush_pkt); } } is->seek_req = 0; is->after_seek_sync = true; } if (is->audioq.size > MAX_AUDIOQ_SIZE || is->videoq.size > MAX_VIDEOQ_SIZE) { al_rest(0.01); continue; } if (av_read_frame(is->format_context, packet) < 0) { #ifdef FFMPEG_0_8 if (!format_context->pb->eof_reached && !format_context->pb->error) { #else if (url_ferror((void *)&format_context->pb) == 0) { #endif al_rest(0.01); continue; } else { break; } } // Is this a packet from the video stream? if (packet->stream_index == is->videoStream) { packet_queue_put(&is->videoq, packet); } else if (packet->stream_index == is->audioStream) { packet_queue_put(&is->audioq, packet); } else { av_free_packet(packet); } } /* all done - wait for it */ while (!is->quit) { al_rest(0.1); } fail: return t; } /* We want to be able to send an event to the user exactly at the time * a new video frame should be displayed. */ static void *timer_thread(ALLEGRO_THREAD *t, void *arg) { VideoState *is = (VideoState *) arg; double ot = 0, nt = 0; while (!is->quit) { ALLEGRO_EVENT event; double d; /* Wait here until someone signals to us when a new frame was * scheduled at is->show_next. */ al_lock_mutex(is->timer_mutex); al_wait_cond(is->timer_cond, is->timer_mutex); al_unlock_mutex(is->timer_mutex); if (is->quit) break; /* Wait until that time. This wait is why we have our own thread * here so the user doesn't need to do it. */ while (1) { d = is->show_next - get_master_clock(is); if (d <= 0) break; //printf("waiting %4.1f ms\n", d * 1000); al_rest(d); } nt = get_master_clock(is); //printf("event after %4.1f ms\n", (nt - ot) * 1000); ot = nt; /* Now is the time. */ event.type = ALLEGRO_EVENT_VIDEO_FRAME_SHOW; event.user.data1 = (intptr_t)is->video; al_emit_user_event(&is->video->es, &event, NULL); } return t; }
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; }
void _al_emit_audio_event(int event_type) { ALLEGRO_EVENT event; event.type = event_type; al_emit_user_event(&audio_event_source, &event, destroy_audio_event); }
void PlayingField::emitLineCompleteEvent(int amountOfLines) { ALLEGRO_EVENT ev; ev.user.data1 = amountOfLines; ev.type = ALLEGRO_GET_EVENT_TYPE('l', 'i', 'n', 'e'); al_emit_user_event(getEventSource(), &ev, 0); }
/* Title: Edit Box Section: Internal Function: wz_editbox_proc See also: <wz_widget_proc> */ int wz_editbox_proc(WZ_WIDGET* wgt, ALLEGRO_EVENT* event) { int ret = 1; WZ_EDITBOX* box = (WZ_EDITBOX*)wgt; switch (event->type) { case WZ_DRAW: { if (wgt->flags & WZ_STATE_HIDDEN) { ret = 0; } else { int size = al_ustr_size(box->text); int scroll_offset = al_ustr_offset(box->text, box->scroll_pos); ALLEGRO_USTR_INFO info; ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, scroll_offset, size); int pos = box->cursor_pos - box->scroll_pos; int flags = 0; if(wgt->flags & WZ_STATE_DISABLED) flags = WZ_STYLE_DISABLED; else if(wgt->flags & WZ_STATE_HAS_FOCUS) flags = WZ_STYLE_FOCUSED; wgt->theme->draw_editbox(wgt->theme, wgt->local_x, wgt->local_y, wgt->w, wgt->h, pos, text, flags); } break; } case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: { if (wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if (event->mouse.button == 1 && wz_widget_rect_test(wgt, event->mouse.x, event->mouse.y)) { int len = al_ustr_length(box->text); ALLEGRO_USTR_INFO info; ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, box->scroll_pos, len - 1); ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0); wz_ask_parent_for_focus(wgt); box->cursor_pos = wz_get_text_pos(font, text, event->mouse.x - wgt->x) + box->scroll_pos; } else ret = 0; break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_BEGIN: { if (wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if (wz_widget_rect_test(wgt, event->touch.x, event->touch.y)) { int len = al_ustr_length(box->text); ALLEGRO_USTR_INFO info; ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, box->scroll_pos, len - 1); ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0); wz_ask_parent_for_focus(wgt); box->cursor_pos = wz_get_text_pos(font, text, event->touch.x - wgt->x) + box->scroll_pos; } else ret = 0; break; } #endif case WZ_HANDLE_SHORTCUT: { wz_ask_parent_for_focus(wgt); break; } case WZ_DESTROY: { if(box->own) al_ustr_free(box->text); ret = 0; break; } case ALLEGRO_EVENT_KEY_CHAR: { int len; if(wgt->flags & WZ_STATE_DISABLED || !(wgt->flags & WZ_STATE_HAS_FOCUS)) { ret = 0; break; } else if(event->keyboard.modifiers & ALLEGRO_KEYMOD_CTRL || event->keyboard.modifiers & ALLEGRO_KEYMOD_ALT) { ret = 0; } len = al_ustr_length(box->text); if((int)(event->keyboard.unichar) > 31 && (int)(event->keyboard.unichar) != 127) { al_ustr_insert_chr(box->text, al_ustr_offset(box->text, box->cursor_pos), event->keyboard.unichar); box->cursor_pos++; } else { switch (event->keyboard.keycode) { case ALLEGRO_KEY_BACKSPACE: { if (len > 0 && box->cursor_pos > 0) { al_ustr_remove_chr(box->text, al_ustr_offset(box->text, box->cursor_pos - 1)); box->cursor_pos--; } break; } case ALLEGRO_KEY_DELETE: { if (len > 0 && box->cursor_pos < len) { al_ustr_remove_chr(box->text, al_ustr_offset(box->text, box->cursor_pos)); } break; } case ALLEGRO_KEY_LEFT: { if (box->cursor_pos > 0) { box->cursor_pos--; } else ret = 0; break; } case ALLEGRO_KEY_RIGHT: { if (box->cursor_pos < len) { box->cursor_pos++; } else ret = 0; break; } case ALLEGRO_KEY_HOME: { box->cursor_pos = 0; break; } case ALLEGRO_KEY_END: { len = al_ustr_length(box->text); box->cursor_pos = len; break; } case ALLEGRO_KEY_ENTER: { wz_trigger(wgt); break; } default: ret = 0; } } wz_snap_editbox(box); break; } case WZ_SET_CURSOR_POS: { box->cursor_pos = event->user.data3; wz_snap_editbox(box); } case WZ_SET_TEXT: { if(box->own) { al_ustr_assign(box->text, (ALLEGRO_USTR*)event->user.data3); } else box->text = (ALLEGRO_USTR*)event->user.data3; wz_snap_editbox(box); break; } case WZ_TRIGGER: { ALLEGRO_EVENT ev; wz_craft_event(&ev, WZ_TEXT_CHANGED, wgt, 0); al_emit_user_event(wgt->source, &ev, 0); break; } case ALLEGRO_EVENT_MOUSE_AXES: { if (wgt->flags & WZ_STATE_DISABLED) { ret = 0; } if (wz_widget_rect_test(wgt, event->mouse.x, event->mouse.y)) { wz_ask_parent_for_focus(wgt); } return wz_widget_proc(wgt, event); break; } default: ret = 0; } if (ret == 0) ret = wz_widget_proc(wgt, event); return ret; }
int main(void) { ALLEGRO_TIMER *timer; ALLEGRO_EVENT_SOURCE user_src; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT user_event; ALLEGRO_EVENT event; if (!al_init()) { abort_example("Could not init Allegro.\n"); return 1; } timer = al_create_timer(0.5); if (!timer) { abort_example("Could not install timer.\n"); return 1; } open_log(); al_init_user_event_source(&user_src); queue = al_create_event_queue(); al_register_event_source(queue, &user_src); al_register_event_source(queue, al_get_timer_event_source(timer)); al_start_timer(timer); while (true) { al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_TIMER) { int n = event.timer.count; log_printf("Got timer event %d\n", n); user_event.user.type = MY_SIMPLE_EVENT_TYPE; user_event.user.data1 = n; al_emit_user_event(&user_src, &user_event, NULL); user_event.user.type = MY_COMPLEX_EVENT_TYPE; user_event.user.data1 = (intptr_t)new_event(n); al_emit_user_event(&user_src, &user_event, my_event_dtor); } else if (event.type == MY_SIMPLE_EVENT_TYPE) { int n = (int) event.user.data1; ALLEGRO_ASSERT(event.user.source == &user_src); al_unref_user_event(&event.user); log_printf("Got simple user event %d\n", n); if (n == 5) { break; } } else if (event.type == MY_COMPLEX_EVENT_TYPE) { MY_EVENT *my_event = (void *)event.user.data1; ALLEGRO_ASSERT(event.user.source == &user_src); log_printf("Got complex user event %d\n", my_event->id); al_unref_user_event(&event.user); } } al_destroy_user_event_source(&user_src); al_destroy_event_queue(queue); al_destroy_timer(timer); log_printf("Done.\n"); close_log(true); return 0; }
/* Title: Button Section: Internal Function: wz_button_proc See also: <wz_widget_proc> */ int wz_button_proc(WZ_WIDGET* wgt, const ALLEGRO_EVENT* event) { int ret = 1; WZ_BUTTON* but = (WZ_BUTTON*)wgt; float x, y; switch(event->type) { case WZ_LOSE_FOCUS: { ret = 0; break; } case WZ_DRAW: { if(wgt->flags & WZ_STATE_HIDDEN) { ret = 0; } else { int flags = 0; if(wgt->flags & WZ_STATE_DISABLED) flags |= WZ_STYLE_DISABLED; else if (wgt->flags & WZ_STATE_HAS_FOCUS) flags |= WZ_STYLE_FOCUSED; if(but->down) flags |= WZ_STYLE_DOWN; wgt->theme->draw_button(wgt->theme, wgt->local_x, wgt->local_y, wgt->w, wgt->h, but->text, flags); } break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_MOVE: x = event->touch.x; y = event->touch.y; #endif case ALLEGRO_EVENT_MOUSE_AXES: { if(event->type == ALLEGRO_EVENT_MOUSE_AXES) { x = event->mouse.x; y = event->mouse.y; } if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if((event->mouse.dx != 0 || event->mouse.dy != 0) && wz_widget_rect_test(wgt, x, y) && !(wgt->flags & WZ_STATE_HAS_FOCUS)) { wz_ask_parent_for_focus(wgt); } else { ret = 0; } break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_BEGIN: x = event->touch.x; y = event->touch.y; #endif case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: { if(event->type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) { x = event->mouse.x; y = event->mouse.y; } if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(wz_widget_rect_test(wgt, x, y)) { wz_ask_parent_for_focus(wgt); but->down = 1; wgt->hold_focus = 1; } else ret = 0; break; } case ALLEGRO_EVENT_KEY_DOWN: { switch(event->keyboard.keycode) { case ALLEGRO_KEY_ENTER: { if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(wgt->flags & WZ_STATE_HAS_FOCUS) { but->down = 1; } else ret = 0; break; } default: ret = 0; } break; } case ALLEGRO_EVENT_KEY_UP: { switch(event->keyboard.keycode) { case ALLEGRO_KEY_ENTER: { if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(wgt->flags & WZ_STATE_HAS_FOCUS) { wz_trigger(wgt); } else ret = 0; break; } default: ret = 0; } break; } case WZ_HANDLE_SHORTCUT: { if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else { if(!(wgt->flags & WZ_STATE_HAS_FOCUS)) { wz_ask_parent_for_focus(wgt); } wz_trigger(wgt); } break; } #if (ALLEGRO_SUB_VERSION > 0) case ALLEGRO_EVENT_TOUCH_END: x = event->touch.x; y = event->touch.y; #endif case ALLEGRO_EVENT_MOUSE_BUTTON_UP: { if(event->type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) { x = event->mouse.x; y = event->mouse.y; } if(wgt->flags & WZ_STATE_DISABLED) { ret = 0; } else if(but->down == 1) { if(wz_widget_rect_test(wgt, x, y)) wz_trigger(wgt); but->down = 0; wgt->hold_focus = 0; } else { ret = 0; } break; } case WZ_DESTROY: { if(but->own) al_ustr_free(but->text); ret = 0; break; } case WZ_SET_TEXT: { if(but->own) { al_ustr_free(but->text); but->text = al_ustr_dup((ALLEGRO_USTR*)event->user.data3); } else { but->text = (ALLEGRO_USTR*)event->user.data3; } break; } case WZ_TRIGGER: { ALLEGRO_EVENT ev; but->down = 0; wz_craft_event(&ev, WZ_BUTTON_PRESSED, wgt, 0); al_emit_user_event(wgt->source, &ev, 0); break; } default: ret = 0; } if(ret == 0) ret = wz_widget_proc(wgt, event); return ret; }
/* _al_kcm_feed_stream: * A routine running in another thread that feeds the stream buffers as * neccesary, usually getting data from some file reader backend. */ void *_al_kcm_feed_stream(ALLEGRO_THREAD *self, void *vstream) { ALLEGRO_AUDIO_STREAM *stream = vstream; ALLEGRO_EVENT_QUEUE *queue; ALLEGRO_EVENT event; (void)self; ALLEGRO_DEBUG("Stream feeder thread started.\n"); queue = al_create_event_queue(); al_register_event_source(queue, &stream->spl.es); al_lock_mutex(stream->feed_thread_started_mutex); stream->feed_thread_started = true; al_broadcast_cond(stream->feed_thread_started_cond); al_unlock_mutex(stream->feed_thread_started_mutex); stream->quit_feed_thread = false; while (!stream->quit_feed_thread) { char *fragment; ALLEGRO_EVENT event; al_wait_for_event(queue, &event); if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT && !stream->is_draining) { unsigned long bytes; unsigned long bytes_written; ALLEGRO_MUTEX *stream_mutex; fragment = al_get_audio_stream_fragment(stream); if (!fragment) { /* This is not an error. */ continue; } bytes = (stream->spl.spl_data.len) * al_get_channel_count(stream->spl.spl_data.chan_conf) * al_get_audio_depth_size(stream->spl.spl_data.depth); stream_mutex = maybe_lock_mutex(stream->spl.mutex); bytes_written = stream->feeder(stream, fragment, bytes); maybe_unlock_mutex(stream_mutex); if (stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { /* Keep rewinding until the fragment is filled. */ while (bytes_written < bytes && stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONEDIR) { size_t bw; al_rewind_audio_stream(stream); stream_mutex = maybe_lock_mutex(stream->spl.mutex); bw = stream->feeder(stream, fragment + bytes_written, bytes - bytes_written); bytes_written += bw; maybe_unlock_mutex(stream_mutex); } } else if (bytes_written < bytes) { /* Fill the rest of the fragment with silence. */ int silence_samples = (bytes - bytes_written) / (al_get_channel_count(stream->spl.spl_data.chan_conf) * al_get_audio_depth_size(stream->spl.spl_data.depth)); al_fill_silence(fragment + bytes_written, silence_samples, stream->spl.spl_data.depth, stream->spl.spl_data.chan_conf); } if (!al_set_audio_stream_fragment(stream, fragment)) { ALLEGRO_ERROR("Error setting stream buffer.\n"); continue; } /* The streaming source doesn't feed any more, drain buffers and quit. */ if (bytes_written != bytes && stream->spl.loop == _ALLEGRO_PLAYMODE_STREAM_ONCE) { al_drain_audio_stream(stream); stream->quit_feed_thread = true; } } else if (event.type == _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE) { stream->quit_feed_thread = true; } } event.user.type = ALLEGRO_EVENT_AUDIO_STREAM_FINISHED; event.user.timestamp = al_get_time(); al_emit_user_event(&stream->spl.es, &event, NULL); al_destroy_event_queue(queue); ALLEGRO_DEBUG("Stream feeder thread finished.\n"); return NULL; }