Exemplo n.º 1
0
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;
		}
	}
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
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;
		}
	}
	
}
Exemplo n.º 4
0
	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
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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;
        }
    }
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
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;
};
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
/* 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;
}
Exemplo n.º 14
0
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);
   }
}
Exemplo n.º 15
0
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);
        }
    }
}
Exemplo n.º 16
0
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;
		}
	}
}
Exemplo n.º 17
0
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;
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
0
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);
}
Exemplo n.º 20
0
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);
}
Exemplo n.º 21
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;
}
Exemplo n.º 23
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;
}
Exemplo n.º 24
0
/* _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;
}