Re: [AD] Miscelaneous issues

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


On Fri, 2005-04-01 at 08:37 +1000, Peter Wang wrote:
> >Yes. Also, which bitmaps should be used? Or maybe the generation should
> >be done at runtime..
> >  
> >
> 
> Runtime is best.  The generated files are rather large.
> 

Ok. I also slightly changed some other stuff so you can see what is
going on while running it.

-- 
Elias Pschernig
Index: examples/expackf.c
===================================================================
RCS file: examples/expackf.c
diff -N examples/expackf.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ examples/expackf.c	5 Apr 2005 15:57:37 -0000
@@ -0,0 +1,445 @@
+/*
+ *    Example program for the Allegro library, by Peter Wang.
+ *
+ *    This program demonstrates the use of the packfile function, with some
+ *    simple tests.
+ *
+ *    The first test uses the standard packfile functions to transfer a
+ *    bitmap file into a block of memory, then reads the bitmap out of the
+ *    block of memory, using a custom packfile vtable.
+ *
+ *    The second test reads in a bitmap with another custom packfile
+ *    vtable, which uses libc's filestream functions.
+ *
+ *    The third test demonstrates seeking with a custom vtable.
+ *
+ *    The fourth test reads two bitmaps, and dumps them back into a
+ *    single file, using a custom vtable again.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "allegro.h"
+
+/*----------------------------------------------------------------------*/
+/*                memory vtable                                         */
+/*----------------------------------------------------------------------*/
+
+/* The packfile data for our memory reader. */
+typedef struct MEMREAD_INFO
+{
+   AL_CONST unsigned char *block;
+   long length;
+   long offset;
+} MEMREAD_INFO;
+
+int memread_getc(void *userdata)
+{
+   MEMREAD_INFO *info = userdata;
+   ASSERT(info);
+   ASSERT(info->offset <= info->length);
+
+   if (info->offset == info->length)
+      return EOF;
+   else
+      return info->block[info->offset++];
+}
+
+int memread_ungetc(int c, void *userdata)
+{
+   MEMREAD_INFO *info = userdata;
+   unsigned char ch = c;
+
+   if ((info->offset > 0) && (info->block[info->offset-1] == ch))
+      return ch;
+   else
+      return EOF;
+}
+
+int memread_putc(int c, void *userdata)
+{
+   return EOF;
+}
+
+long memread_fread(void *p, long n, void *userdata)
+{
+   MEMREAD_INFO *info = userdata;
+   size_t actual;
+   ASSERT(info);
+   ASSERT(info->offset <= info->length);
+
+   actual = MIN(n, info->length - info->offset);
+
+   memcpy(p, info->block + info->offset, actual);
+   info->offset += actual;
+
+   ASSERT(info->offset <= info->length);
+
+   return actual;
+}
+
+long memread_fwrite(AL_CONST void *p, long n, void *userdata)
+{
+   return 0;
+}
+
+int memread_seek(void *userdata, int offset)
+{
+   MEMREAD_INFO *info = userdata;
+   long actual;
+   ASSERT(info);
+   ASSERT(info->offset <= info->length);
+
+   actual = MIN(offset, info->length - info->offset);
+
+   info->offset += actual;
+
+   ASSERT(info->offset <= info->length);
+
+   if (offset == actual)
+      return 0;
+   else
+      return -1;
+}
+
+int memread_fclose(void *userdata)
+{
+   return 0;
+}
+
+int memread_feof(void *userdata)
+{
+   MEMREAD_INFO *info = userdata;
+
+   return info->offset >= info->length;
+}
+
+int memread_ferror(void *userdata)
+{
+   (void)userdata;
+
+   return FALSE;
+}
+
+/* The actual vtable. Note that writing is not supported, the functions for
+ * writing above are only placeholders.
+ */
+PACKFILE_VTABLE memread_vtable =
+{
+   memread_fclose,
+   memread_getc,
+   memread_ungetc,
+   memread_fread,
+   memread_putc,
+   memread_fwrite,
+   memread_seek,
+   memread_feof,
+   memread_ferror
+};
+
+/*----------------------------------------------------------------------*/
+/*                stdio vtable                                          */
+/*----------------------------------------------------------------------*/
+
+static int stdio_fclose(void *userdata)
+{
+   FILE *fp = userdata;
+   return fclose(fp);
+}
+
+static int stdio_getc(void *userdata)
+{
+   FILE *fp = userdata;
+   return fgetc(fp);
+}
+
+static int stdio_ungetc(int c, void *userdata)
+{
+   FILE *fp = userdata;
+   return ungetc(c, fp);
+}
+
+static long stdio_fread(void *p, long n, void *userdata)
+{
+   FILE *fp = userdata;
+   return fread(p, 1, n, fp);
+}
+
+static int stdio_putc(int c, void *userdata)
+{
+   FILE *fp = userdata;
+   return fputc(c, fp);
+}
+
+static long stdio_fwrite(AL_CONST void *p, long n, void *userdata)
+{
+   FILE *fp = userdata;
+   return fwrite(p, 1, n, fp);
+}
+
+static int stdio_seek(void *userdata, int n)
+{
+   FILE *fp = userdata;
+   return fseek(fp, n, SEEK_CUR);
+}
+
+static int stdio_feof(void *userdata)
+{
+   FILE *fp = userdata;
+   return feof(fp);
+}
+
+static int stdio_ferror(void *userdata)
+{
+   FILE *fp = userdata;
+   return ferror(fp);
+}
+
+/* The actual vtable. */
+static PACKFILE_VTABLE stdio_vtable =
+{
+   stdio_fclose,
+   stdio_getc,
+   stdio_ungetc,
+   stdio_fread,
+   stdio_putc,
+   stdio_fwrite,
+   stdio_seek,
+   stdio_feof,
+   stdio_ferror
+};
+
+/*----------------------------------------------------------------------*/
+/*                tests                                                 */
+/*----------------------------------------------------------------------*/
+
+static void next(void)
+{
+   textprintf_centre_ex(screen, font, SCREEN_W / 2,
+      SCREEN_H - text_height(font), -1, -1, "Press a key to continue");
+   readkey();
+   clear_bitmap(screen);
+}
+
+#define CHECK(x, err) if (!x) { alert("Error", err, NULL, "Ok", NULL, 0, 0); return; }
+
+/* This reads the files mysha.pcx and allegro.pcx into a memory block as
+ * binary data, and then uses the memory vtable to read the bitmaps out of
+ * the memory block.
+ */
+static void memread_test(void)
+{
+   PACKFILE *f;
+   MEMREAD_INFO memread_info;
+   BITMAP *bmp, *bmp2;
+   char *block;
+   int l1, l2;
+   PACKFILE *f1, *f2;
+
+   l1 = file_size("allegro.pcx");
+   l2 = file_size("mysha.pcx");
+
+   block = malloc(l1 + l2);
+
+   /* Read mysha.pcx into the memory block. */
+   f1 = pack_fopen("allegro.pcx", "rb");
+   CHECK(f1, "opening allegro.pcx");
+   pack_fread(block, l1, f1);
+   pack_fclose(f1);
+
+   /* Read allegro.pcx into the memory block. */
+   f2 = pack_fopen("mysha.pcx", "rb");
+   CHECK(f2, "opening mysha.pcx");
+   pack_fread(block + l1, l2, f2);
+   pack_fclose(f2);
+
+   /* Open the memory block as PACKFILE, using our memory vtable. */
+   memread_info.block = block;
+   memread_info.length = l1 + l2;
+   memread_info.offset = 0;
+   f = pack_fopen_vtable(&memread_vtable, &memread_info);
+   CHECK(f, "reading from memory block");
+
+   /* Read the bitmaps out of the memory block. */
+   bmp = load_pcx_pf(f, NULL);
+   CHECK(bmp, "load_pcx_pf");
+   bmp2 = load_pcx_pf(f, NULL);
+   CHECK(bmp2, "load_pcx_pf");
+
+   blit(bmp, screen, 0, 0, 0, 0, bmp->w, bmp->h);
+   textprintf_ex(screen, font, bmp->w + 8, 8, -1, -1,
+      "\"allegro.pcx\"");
+   textprintf_ex(screen, font, bmp->w + 8, 8 + 20, -1, -1,
+      "read out of a memory file");
+
+   blit(bmp2, screen, 0, 0, 0, bmp->h + 8, bmp2->w, bmp2->h);
+   textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8, -1, -1,
+      "\"mysha.pcx\"");
+   textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8 + 20, -1, -1,
+      "read out of a memory file");
+
+   destroy_bitmap(bmp);
+   destroy_bitmap(bmp2);
+   pack_fclose(f);
+
+   next();
+}
+
+/* This reads in allegro.pcx, but it does so by using the stdio vtable. */
+static void stdio_read_test(void)
+{
+   FILE *fp, *fp2;
+   PACKFILE *f;
+   BITMAP *bmp,*bmp2;
+
+   /* Simply open the file with the libc fopen. */
+   fp = fopen("allegro.pcx", "rb");
+   CHECK(fp, "opening allegro.pcx");
+
+   /* Create a PACKFILE, with our custom stdio vtable. */
+   f = pack_fopen_vtable(&stdio_vtable, fp);
+   CHECK(f, "reading with stdio");
+
+   /* Now read in the bitmap. */
+   bmp = load_pcx_pf(f, NULL);
+   CHECK(bmp, "load_pcx_pf");
+
+   /* A little bit hackish, we re-assign the file pointer in our PACKFILE
+    * to another file.
+    */
+   fp2 = freopen("mysha.pcx", "rb", fp);
+   CHECK(fp2, "opening mysha.pcx");
+
+   /* Read in the other bitmap. */
+   bmp2 = load_pcx_pf(f, NULL);
+   CHECK(bmp, "load_pcx_pf");
+
+   blit(bmp, screen, 0, 0, 0, 0, bmp->w, bmp->h);
+   textprintf_ex(screen, font, bmp2->w + 8, 8, -1, -1,
+      "\"allegro.pcx\"");
+   textprintf_ex(screen, font, bmp2->w + 8, 8 + 20, -1, -1,
+      "read with stdio functions");
+
+   blit(bmp2, screen, 0, 0, 0, bmp->h + 8, bmp2->w, bmp2->h);
+   textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8, -1, -1,
+      "\"mysha.pcx\"");
+   textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8 + 20, -1, -1,
+      "read with stdio functions");
+
+   destroy_bitmap(bmp);
+   destroy_bitmap(bmp2);
+   pack_fclose(f);
+
+   next();
+}
+
+/* This demonstrates seeking. It opens expackf.c, and reads some characters
+ * from it.
+ */
+static void stdio_seek_test(void)
+{
+   FILE *fp;
+   PACKFILE *f;
+   int c1, c2, c3, c4;
+   int ret;
+   char str[8];
+
+   fp = fopen("expackf.c", "rb");
+   CHECK(fp, "opening expackf.c");
+   f = pack_fopen_vtable(&stdio_vtable, fp);
+   CHECK(f, "reading with stdio");
+
+   pack_fseek(f, 33);
+   pack_fread(str, 7, f);
+   str[7] = '\0';
+
+   textprintf_ex(screen, font, 0, 0, -1, -1, "Seeking to byte 33, reading 7 bytes:");
+   textprintf_ex(screen, font, 0, 20, -1, -1, "\"%s\"", str);
+   textprintf_ex(screen, font, 0, 40, -1, -1, "(Should be \"Allegro\")");
+
+   pack_fclose(f);
+
+   next();
+}
+
+/* This demonstrates writing. It simply saves the two bitmaps into a binary
+ * file.
+ */
+static void stdio_write_test(void)
+{
+   FILE *fp;
+   PACKFILE *f;
+   BITMAP *bmp, *bmp2;
+
+   /* Read the bitmaps. */
+   bmp = load_pcx("allegro.pcx", NULL);
+   CHECK(bmp, "load_pcx");
+   bmp2 = load_pcx("mysha.pcx", NULL);
+   CHECK(bmp2, "load_pcx");
+
+   /* Write them with out custom vtable. */
+   fp = fopen("expackf.out", "wb");
+   CHECK(fp, "writing expackf.out");
+   f = pack_fopen_vtable(&stdio_vtable, fp);
+   CHECK(f, "writing with stdio");
+
+   save_tga_pf(f, bmp, NULL);
+   save_bmp_pf(f, bmp2, NULL);
+
+   destroy_bitmap(bmp);
+   destroy_bitmap(bmp2);
+   pack_fclose(f);
+
+   /* Now read them in again with our custom vtable. */
+   fp = fopen("expackf.out", "rb");
+   CHECK(fp, "fopen");
+   f = pack_fopen_vtable(&stdio_vtable, fp);
+   CHECK(f, "reading from stdio");
+
+   bmp = load_tga_pf(f, NULL);
+   CHECK(bmp, "load_tga_pf");
+   bmp2 = load_bmp_pf(f, NULL);
+   CHECK(bmp2, "load_bmp_pf");
+
+   blit(bmp, screen, 0, 0, 0, 0, bmp->w, bmp->h);
+   textprintf_ex(screen, font, bmp2->w + 8, 8, -1, -1,
+      "\"allegro.pcx\" (as tga)");
+   textprintf_ex(screen, font, bmp2->w + 8, 8 + 20, -1, -1,
+      "wrote with stdio functions");
+
+   blit(bmp2, screen, 0, 0, 0, bmp->h + 8, bmp2->w, bmp2->h);
+   textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8, -1, -1,
+      "\"mysha.pcx\" (as bmp)");
+   textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8 + 20, -1, -1,
+      "wrote with stdio functions");
+
+   destroy_bitmap(bmp);
+   destroy_bitmap(bmp2);
+   pack_fclose(f);
+
+   next();
+}
+
+/*----------------------------------------------------------------------*/
+
+int main(void)
+{
+   if (allegro_init() != 0)
+      return 1;
+   install_keyboard();
+   set_color_depth(32);
+   if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0) != 0)
+      return 1;
+
+   memread_test();
+
+   stdio_read_test();
+
+   stdio_seek_test();
+
+   stdio_write_test();
+
+   return 0;
+}
+
+END_OF_MAIN()
Index: examples/examples.txt
===================================================================
RCS file: /cvsroot/alleg/allegro/examples/examples.txt,v
retrieving revision 1.7
diff -u -p -r1.7 examples.txt
--- examples/examples.txt	13 Feb 2005 19:57:41 -0000	1.7
+++ examples/examples.txt	5 Apr 2005 15:57:37 -0000
@@ -24,6 +24,7 @@ exlights.c - One way to do colored light
 exmem.c    - Drawing onto memory bitmaps and then blitting them to the screen.
 exmidi.c   - Playing MIDI music.
 exmouse.c  - Getting input from the mouse.
+expackf.c  - Using custom PACKFILE vtables.
 expal.c    - Palette effects and color cycling.
 expat.c    - Using patterned drawing modes and sub-bitmaps.
 exquat.c   - A comparison between euler angles and quaternions.
Index: makefile.lst
===================================================================
RCS file: /cvsroot/alleg/allegro/makefile.lst,v
retrieving revision 1.112
diff -u -p -r1.112 makefile.lst
--- makefile.lst	31 Mar 2005 21:15:56 -0000	1.112
+++ makefile.lst	5 Apr 2005 15:57:37 -0000
@@ -535,6 +535,7 @@ ALLEGRO_EXAMPLE_FILES = \
 	examples/exmem.c \
 	examples/exmidi.c \
 	examples/exmouse.c \
+        examples/expackf.c \
 	examples/expal.c \
 	examples/expat.c \
 	examples/exquat.c \
@@ -586,6 +587,7 @@ ALLEGRO_EXAMPLE_EXES = \
 	examples/exmem \
 	examples/exmidi \
 	examples/exmouse \
+        examples/expackf \
 	examples/expal \
 	examples/expat \
 	examples/exquat \


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/