Exemplo n.º 1
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.º 2
0
static void xinerama_get_display_offset(ALLEGRO_SYSTEM_XGLX *s, int adapter, int *x, int *y)
{
    ALLEGRO_ASSERT(adapter >= 0 && adapter < s->xinerama_screen_count);
    *x = s->xinerama_screen_info[adapter].x_org;
    *y = s->xinerama_screen_info[adapter].y_org;
    ALLEGRO_DEBUG("xinerama dpy off %ix%i\n", *x, *y);
}
Exemplo n.º 3
0
void _dsound_close_recorder(ALLEGRO_AUDIO_RECORDER *r) {
   ALLEGRO_ASSERT(capture_device);
   (void) r;

   capture_device->Release();
   capture_device = NULL;
}
Exemplo n.º 4
0
/* Load a PNG file from disk, doing colour coversion if required.
 */
ALLEGRO_BITMAP *_al_load_png_f(ALLEGRO_FILE *fp, int flags)
{
   jmp_buf jmpbuf;
   ALLEGRO_BITMAP *bmp;
   png_structp png_ptr;
   png_infop info_ptr;

   ALLEGRO_ASSERT(fp);

   if (!check_if_png(fp)) {
      ALLEGRO_ERROR("Not a png.\n");
      return NULL;
   }

   /* Create and initialize the png_struct with the desired error handler
    * functions.  If you want to use the default stderr and longjump method,
    * you can supply NULL for the last three parameters.  We also supply the
    * the compiler header file version, so that we know if the application
    * was compiled with a compatible version of the library.
    */
   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                    (void *)NULL, NULL, NULL);
   if (!png_ptr) {
      ALLEGRO_ERROR("png_ptr == NULL\n");
      return NULL;
   }

   /* Allocate/initialize the memory for image information. */
   info_ptr = png_create_info_struct(png_ptr);
   if (!info_ptr) {
      png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL);
      ALLEGRO_ERROR("png_create_info_struct failed\n");
      return NULL;
   }

   /* Set error handling. */
   if (setjmp(jmpbuf)) {
      /* Free all of the memory associated with the png_ptr and info_ptr */
      png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
      /* If we get here, we had a problem reading the file */
      ALLEGRO_ERROR("Error reading PNG file\n");
      return NULL;
   }
   png_set_error_fn(png_ptr, jmpbuf, user_error_fn, NULL);

   /* Use Allegro packfile routines. */
   png_set_read_fn(png_ptr, fp, (png_rw_ptr) read_data);

   /* We have already read some of the signature. */
   png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);

   /* Really load the image now. */
   bmp = really_load_png(png_ptr, info_ptr, flags);

   /* Clean up after the read, and free any memory allocated. */
   png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);

   return bmp;
}
Exemplo n.º 5
0
bool _al_save_jpg(char const *filename, ALLEGRO_BITMAP *bmp)
{
   ALLEGRO_FILE *fp;
   bool result;

   ALLEGRO_ASSERT(filename);
   ALLEGRO_ASSERT(bmp);

   fp = al_fopen(filename, "wb");
   if (!fp) {
      ALLEGRO_ERROR("Unable to open file %s for writing\n", filename);
      return false;
   }

   result = _al_save_jpg_f(fp, bmp);

   al_fclose(fp);

   return result;
}
Exemplo n.º 6
0
static int check_if_png(ALLEGRO_FILE *fp)
{
   unsigned char buf[PNG_BYTES_TO_CHECK];

   ALLEGRO_ASSERT(fp);

   if (al_fread(fp, buf, PNG_BYTES_TO_CHECK) != PNG_BYTES_TO_CHECK)
      return 0;

   return (png_sig_cmp(buf, (png_size_t) 0, PNG_BYTES_TO_CHECK) == 0);
}
Exemplo n.º 7
0
bool _al_save_png(const char *filename, ALLEGRO_BITMAP *bmp)
{
   ALLEGRO_FILE *fp;
   bool retsave;
   bool retclose;

   ALLEGRO_ASSERT(filename);
   ALLEGRO_ASSERT(bmp);

   fp = al_fopen(filename, "wb");
   if (!fp) {
      ALLEGRO_ERROR("Unable to open file %s for writing\n", filename);
      return false;
   }

   retsave = _al_save_png_f(fp, bmp);
   retclose = al_fclose(fp);

   return retsave && retclose;
}
Exemplo n.º 8
0
ALLEGRO_BITMAP *_al_load_jpg(char const *filename, int flags)
{
   ALLEGRO_FILE *fp;
   ALLEGRO_BITMAP *bmp;

   ALLEGRO_ASSERT(filename);

   fp = al_fopen(filename, "rb");
   if (!fp)
      return NULL;

   bmp = _al_load_jpg_f(fp, flags);

   al_fclose(fp);

   return bmp;
}
Exemplo n.º 9
0
void Prog::handle_event(const ALLEGRO_EVENT & event)
{
   if (event.type == ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT) {
      ALLEGRO_AUDIO_STREAM *stream;
      Group *group;
      void *buf;
      float gain;
      float pan;

      stream = (ALLEGRO_AUDIO_STREAM *) event.any.source;
      buf = al_get_audio_stream_fragment(stream);
      if (!buf) {
         /* This is a normal condition that you must deal with. */
         return;
      }

      if (stream == stream1)
         group = &group1;
      else if (stream == stream2)
         group = &group2;
      else if (stream == stream3)
         group = &group3;
      else if (stream == stream4)
         group = &group4;
      else if (stream == stream5)
         group = &group5;
      else
         group = NULL;

      ALLEGRO_ASSERT(group);

      if (group) {
         group->generate((float *) buf, SAMPLES_PER_BUFFER);
         if (group->get_gain_if_changed(&gain)) {
            al_set_audio_stream_gain(stream, gain);
         }
         if (group->get_pan_if_changed(&pan)) {
            al_set_audio_stream_pan(stream, pan);
         }
      }

      if (!al_set_audio_stream_fragment(stream, buf)) {
         log_printf("Error setting stream fragment.\n");
      }
   }
}
Exemplo n.º 10
0
int str_to_blend_mode(const std::string & str)
{
   if (str == "ZERO")
      return ALLEGRO_ZERO;
   if (str == "ONE")
      return ALLEGRO_ONE;
   if (str == "ALPHA")
      return ALLEGRO_ALPHA;
   if (str == "INVERSE")
      return ALLEGRO_INVERSE_ALPHA;
   if (str == "ADD")
      return ALLEGRO_ADD;
   if (str == "SRC_MINUS_DEST")
      return ALLEGRO_SRC_MINUS_DEST;
   if (str == "DEST_MINUS_SRC")
      return ALLEGRO_DEST_MINUS_SRC;

   ALLEGRO_ASSERT(false);
   return ALLEGRO_ONE;
}
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.º 12
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.º 13
0
/* really_load_png:
 *  Worker routine, used by load_png and load_memory_png.
 */
static ALLEGRO_BITMAP *really_load_png(png_structp png_ptr, png_infop info_ptr,
   int flags)
{
   ALLEGRO_BITMAP *bmp;
   png_uint_32 width, height, rowbytes, real_rowbytes;
   int bit_depth, color_type, interlace_type;
   double image_gamma, screen_gamma;
   int intent;
   int bpp;
   int number_passes, pass;
   int num_trans = 0;
   PalEntry pal[256];
   png_bytep trans;
   ALLEGRO_LOCKED_REGION *lock;
   unsigned char *buf;
   unsigned char *dest;
   bool premul = !(flags & ALLEGRO_NO_PREMULTIPLIED_ALPHA);
   bool index_only;

   ALLEGRO_ASSERT(png_ptr && info_ptr);

   /* The call to png_read_info() gives us all of the information from the
    * PNG file before the first IDAT (image data chunk).
    */
   png_read_info(png_ptr, info_ptr);

   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
                &color_type, &interlace_type, NULL, NULL);

   /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    * byte into separate bytes (useful for paletted and grayscale images).
    */
   png_set_packing(png_ptr);

   /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
   if ((color_type == PNG_COLOR_TYPE_GRAY) && (bit_depth < 8))
      png_set_expand(png_ptr);

   /* Adds a full alpha channel if there is transparency information
    * in a tRNS chunk.
    */
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
      if (!(color_type & PNG_COLOR_MASK_PALETTE))
         png_set_tRNS_to_alpha(png_ptr);
      png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
   }

   /* Convert 16-bits per colour component to 8-bits per colour component. */
   if (bit_depth == 16)
      png_set_strip_16(png_ptr);

   /* Convert grayscale to RGB triplets */
   if ((color_type == PNG_COLOR_TYPE_GRAY) ||
       (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
      png_set_gray_to_rgb(png_ptr);

   /* Optionally, tell libpng to handle the gamma correction for us. */
   if (_al_png_screen_gamma != 0.0) {
      screen_gamma = get_gamma();

      if (png_get_sRGB(png_ptr, info_ptr, &intent))
         png_set_gamma(png_ptr, screen_gamma, 0.45455);
      else {
         if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
            png_set_gamma(png_ptr, screen_gamma, image_gamma);
         else
            png_set_gamma(png_ptr, screen_gamma, 0.45455);
      }
   }

   /* Turn on interlace handling. */
   number_passes = png_set_interlace_handling(png_ptr);

   /* Call to gamma correct and add the background to the palette
    * and update info structure.
    */
   png_read_update_info(png_ptr, info_ptr);

   /* Palettes. */
   if (color_type & PNG_COLOR_MASK_PALETTE) {
      int num_palette, i;
      png_colorp palette;

      if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)) {
         /* We don't actually dither, we just copy the palette. */
         for (i = 0; ((i < num_palette) && (i < 256)); i++) {
            pal[i].r = palette[i].red;
            pal[i].g = palette[i].green;
            pal[i].b = palette[i].blue;
         }

         for (; i < 256; i++)
            pal[i].r = pal[i].g = pal[i].b = 0;
      }
   }

   rowbytes = png_get_rowbytes(png_ptr, info_ptr);

   /* Allocate the memory to hold the image using the fields of info_ptr. */
   bpp = rowbytes * 8 / width;

   /* Allegro cannot handle less than 8 bpp. */
   if (bpp < 8)
      bpp = 8;


   if ((bpp == 24) || (bpp == 32)) {
#ifdef ALLEGRO_BIG_ENDIAN
      png_set_bgr(png_ptr);
      png_set_swap_alpha(png_ptr);
#endif
   }

   bmp = al_create_bitmap(width, height);
   if (!bmp) {
      ALLEGRO_ERROR("al_create_bitmap failed while loading PNG.\n");
      return NULL;
   }

   // TODO: can this be different from rowbytes?
   real_rowbytes = ((bpp + 7) / 8) * width;
   if (interlace_type == PNG_INTERLACE_ADAM7)
      buf = al_malloc(real_rowbytes * height);
   else
      buf = al_malloc(real_rowbytes);

   if (bpp == 8 && (color_type & PNG_COLOR_MASK_PALETTE) &&
      (flags & ALLEGRO_KEEP_INDEX))
   {
      lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8,
         ALLEGRO_LOCK_WRITEONLY);
      index_only = true;
   }
   else {
      lock = al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE,
         ALLEGRO_LOCK_WRITEONLY);
      index_only = false;
   }

   /* Read the image, one line at a time (easier to debug!) */
   for (pass = 0; pass < number_passes; pass++) {
      png_uint_32 y;
      unsigned int i;
      unsigned char *ptr;
      dest = lock->data;

      for (y = 0; y < height; y++) {
         unsigned char *dest_row_start = dest;
         /* For interlaced pictures, the row needs to be initialized with
          * the contents of the previous pass.
          */
         if (interlace_type == PNG_INTERLACE_ADAM7)
            ptr = buf + y * real_rowbytes;
         else
            ptr = buf;
         png_read_row(png_ptr, NULL, ptr);
   
         switch (bpp) {
            case 8:
               if (index_only) {
                  for (i = 0; i < width; i++) {
                     *(dest++) = *(ptr++);
                  }
               }
               else if (color_type & PNG_COLOR_MASK_PALETTE) {
                  for (i = 0; i < width; i++) {
                     int pix = ptr[0];
                     ptr++;
                     dest[0] = pal[pix].r;
                     dest[1] = pal[pix].g;
                     dest[2] = pal[pix].b;
                     if (pix < num_trans) {
                        int a = trans[pix];
                        dest[3] = a;
                        if (premul) {
                           dest[0] = dest[0] * a / 255;
                           dest[1] = dest[1] * a / 255;
                           dest[2] = dest[2] * a / 255;
                        }
                     } else {
                        dest[3] = 255;
                     }
                     dest += 4;
                  }
               }
               else {
                  for (i = 0; i < width; i++) {
                     int pix = ptr[0];
                     ptr++;
                     *(dest++) = pix;
                     *(dest++) = pix;
                     *(dest++) = pix;
                     *(dest++) = 255;
                  }
               }
               break;

            case 24:
               for (i = 0; i < width; i++) {
                  uint32_t pix = _AL_READ3BYTES(ptr);
                  ptr += 3;
                  *(dest++) = pix & 0xff;
                  *(dest++) = (pix >> 8) & 0xff;
                  *(dest++) = (pix >> 16) & 0xff;
                  *(dest++) = 255;
               }
               break;

            case 32:
               for (i = 0; i < width; i++) {
                  uint32_t pix = *(uint32_t*)ptr;
                  int r = pix & 0xff;
                  int g = (pix >> 8) & 0xff;
                  int b = (pix >> 16) & 0xff;
                  int a = (pix >> 24) & 0xff;
                  ptr += 4;

                  if (premul) {
                     r = r * a / 255;
                     g = g * a / 255;
                     b = b * a / 255;
                  }

                  *(dest++) = r;
                  *(dest++) = g;
                  *(dest++) = b;
                  *(dest++) = a;
               }
               break;

            default:
               ALLEGRO_ASSERT(bpp == 8 || bpp == 24 || bpp == 32);
               break;
         }
         dest = dest_row_start + lock->pitch;
      }
   }

   al_unlock_bitmap(bmp);

   al_free(buf);

   /* Read rest of file, and get additional chunks in info_ptr. */
   png_read_end(png_ptr, info_ptr);

   return bmp;
}