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 \