shithub: dumb

Download patch

ref: 24462dc49742b08e8f868e0b30dc4fa9efe8cf84
parent: 250580dbe710a99d40fb75d3393d31b05f452912
author: Azamat H. Hackimov <azamat.hackimov@gmail.com>
date: Tue Mar 1 16:20:33 EST 2016

Adding allegro4 library bindings

Taken from legacy dumb 0.9.3.

diff: cannot open b/dumb/src/allegro//null: file does not exist: 'b/dumb/src/allegro//null'
--- /dev/null
+++ b/dumb/src/allegro/alplay.c
@@ -1,0 +1,277 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * alplay.c - Functions to play a DUH through         / / \  \
+ *            an Allegro audio stream.               | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <stdlib.h>
+
+#include <allegro.h>
+
+#include "aldumb.h"
+
+
+
+#define ADP_PLAYING 1
+
+struct AL_DUH_PLAYER
+{
+	int flags;
+	long bufsize;
+	int freq;
+	AUDIOSTREAM *stream;
+	DUH_SIGRENDERER *sigrenderer; /* If this is NULL, stream is invalid. */
+	float volume;
+	int silentcount;
+};
+
+
+
+AL_DUH_PLAYER *al_start_duh(DUH *duh, int n_channels, long pos, float volume, long bufsize, int freq)
+{
+	AL_DUH_PLAYER *dp;
+
+	/* This restriction is imposed by Allegro. */
+	ASSERT(n_channels > 0);
+	ASSERT(n_channels <= 2);
+
+	if (!duh)
+		return NULL;
+
+	dp = malloc(sizeof(*dp));
+	if (!dp)
+		return NULL;
+
+	dp->flags = ADP_PLAYING;
+	dp->bufsize = bufsize;
+	dp->freq = freq;
+
+	dp->stream = play_audio_stream(bufsize, 16, n_channels - 1, freq, 255, 128);
+
+	if (!dp->stream) {
+		free(dp);
+		return NULL;
+	}
+
+	voice_set_priority(dp->stream->voice, 255);
+
+	dp->sigrenderer = duh_start_sigrenderer(duh, 0, n_channels, pos);
+
+	if (!dp->sigrenderer) {
+		stop_audio_stream(dp->stream);
+		free(dp);
+		return NULL;
+	}
+
+	dp->volume = volume;
+	dp->silentcount = 0;
+
+	return dp;
+}
+
+
+
+void al_stop_duh(AL_DUH_PLAYER *dp)
+{
+	if (dp) {
+		if (dp->sigrenderer) {
+			duh_end_sigrenderer(dp->sigrenderer);
+			stop_audio_stream(dp->stream);
+		}
+		free(dp);
+	}
+}
+
+
+
+void al_pause_duh(AL_DUH_PLAYER *dp)
+{
+	if (dp && dp->sigrenderer && (dp->flags & ADP_PLAYING)) {
+		voice_stop(dp->stream->voice);
+		dp->flags &= ~ADP_PLAYING;
+	}
+}
+
+
+
+void al_resume_duh(AL_DUH_PLAYER *dp)
+{
+	if (dp && dp->sigrenderer && !(dp->flags & ADP_PLAYING)) {
+		voice_start(dp->stream->voice);
+		dp->flags |= ADP_PLAYING;
+	}
+}
+
+
+
+void al_duh_set_priority(AL_DUH_PLAYER *dp, int priority)
+{
+	if (dp && dp->sigrenderer)
+		voice_set_priority(dp->stream->voice, priority);
+}
+
+
+
+void al_duh_set_volume(AL_DUH_PLAYER *dp, float volume)
+{
+	if (dp)
+		dp->volume = volume;
+}
+
+
+
+float al_duh_get_volume(AL_DUH_PLAYER *dp)
+{
+	return dp ? dp->volume : 0;
+}
+
+
+
+int al_poll_duh(AL_DUH_PLAYER *dp)
+{
+	unsigned short *sptr;
+	long n;
+	long size;
+	int n_channels;
+
+	if (!dp || !dp->sigrenderer)
+		return 1;
+
+	if (!(dp->flags & ADP_PLAYING))
+		return 0;
+
+	sptr = get_audio_stream_buffer(dp->stream);
+
+	if (!sptr)
+		return 0;
+
+	n = duh_render(dp->sigrenderer, 16, 1, dp->volume, 65536.0 / dp->freq, dp->bufsize, sptr);
+
+	if (n == 0) {
+		if (++dp->silentcount >= 2) {
+			duh_end_sigrenderer(dp->sigrenderer);
+			free_audio_stream_buffer(dp->stream);
+			stop_audio_stream(dp->stream);
+			dp->sigrenderer = NULL;
+			return 1;
+		}
+	}
+
+	n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer);
+	n *= n_channels;
+	size = dp->bufsize * n_channels;
+	for (; n < size; n++)
+		sptr[n] = 0x8000;
+
+	free_audio_stream_buffer(dp->stream);
+
+	return 0;
+}
+
+
+
+long al_duh_get_position(AL_DUH_PLAYER *dp)
+{
+	return dp ? duh_sigrenderer_get_position(dp->sigrenderer) : -1;
+}
+
+
+
+AL_DUH_PLAYER *al_duh_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer, float volume, long bufsize, int freq)
+{
+	AL_DUH_PLAYER *dp;
+	int n_channels;
+
+	if (!sigrenderer)
+		return NULL;
+
+	dp = malloc(sizeof(*dp));
+	if (!dp)
+		return NULL;
+
+	n_channels = duh_sigrenderer_get_n_channels(sigrenderer);
+
+	/* This restriction is imposed by Allegro. */
+	ASSERT(n_channels > 0);
+	ASSERT(n_channels <= 2);
+
+	dp->flags = ADP_PLAYING;
+	dp->bufsize = bufsize;
+	dp->freq = freq;
+
+	dp->stream = play_audio_stream(bufsize, 16, n_channels - 1, freq, 255, 128);
+
+	if (!dp->stream) {
+		free(dp);
+		return NULL;
+	}
+
+	voice_set_priority(dp->stream->voice, 255);
+
+	dp->sigrenderer = sigrenderer;
+
+	dp->volume = volume;
+	dp->silentcount = 0;
+
+	return dp;
+}
+
+
+
+DUH_SIGRENDERER *al_duh_get_sigrenderer(AL_DUH_PLAYER *dp)
+{
+	return dp ? dp->sigrenderer : NULL;
+}
+
+
+
+/* IMPORTANT: This function will return NULL if the music has ended. */
+// Should this be changed? User might want to hack the underlying SIGRENDERER
+// and resurrect it (e.g. change pattern number), before it gets destroyed...
+DUH_SIGRENDERER *al_duh_decompose_to_sigrenderer(AL_DUH_PLAYER *dp)
+{
+	if (dp) {
+		DUH_SIGRENDERER *sigrenderer = dp->sigrenderer;
+		if (sigrenderer) stop_audio_stream(dp->stream);
+		free(dp);
+		return sigrenderer;
+	}
+	return NULL;
+}
+
+
+
+/* DEPRECATED */
+AL_DUH_PLAYER *al_duh_encapsulate_renderer(DUH_SIGRENDERER *dr, float volume, long bufsize, int freq)
+{
+	return al_duh_encapsulate_sigrenderer(dr, volume, bufsize, freq);
+}
+
+
+
+/* DEPRECATED */
+DUH_SIGRENDERER *al_duh_get_renderer(AL_DUH_PLAYER *dp)
+{
+	return al_duh_get_sigrenderer(dp);
+}
+
+
+
+/* DEPRECATED */
+DUH_SIGRENDERER *al_duh_decompose_to_renderer(AL_DUH_PLAYER *dp)
+{
+	return al_duh_decompose_to_sigrenderer(dp);
+}
--- /dev/null
+++ b/dumb/src/allegro/datduh.c
@@ -1,0 +1,60 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datduh.c - Integration with Allegro's              / / \  \
+ *            datafiles.                             | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_duh(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = read_duh(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_duh(): tells Allegro about the DUH datafile object. If
+ * you intend to load a datafile containing a DUH object, you must call this
+ * function first. It is recommended you pass DAT_DUH, but you may have a
+ * reason to use a different type (apart from pride, that doesn't count).
+ */
+void dumb_register_dat_duh(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_duh,
+		&_dat_unload_duh
+	);
+}
--- /dev/null
+++ b/dumb/src/allegro/datit.c
@@ -1,0 +1,62 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datit.c - Integration of IT files with             / / \  \
+ *           Allegro's datafiles.                    | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_it(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_it(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_it(): tells Allegro about the IT datafile object. If you
+ * intend to load a datafile containing an IT object, you must call this
+ * function first. It is recommended you pass DUMB_DAT_IT, but you may have a
+ * reason to use a different type (perhaps you already have a datafile with
+ * IT files in and they use a different type).
+ */
+void dumb_register_dat_it(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_it,
+		&_dat_unload_duh
+	);
+}
+
--- /dev/null
+++ b/dumb/src/allegro/datitq.c
@@ -1,0 +1,64 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datitq.c - Integration of IT files with            / / \  \
+ *            Allegro's datafiles.                   | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_it_quick(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_it_quick(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_it_quick(): tells Allegro about the IT datafile object.
+ * If you intend to load a datafile containing an IT object, you must call
+ * this function first. It is recommended you pass DUMB_DAT_IT, but you may
+ * have a reason to use a different type (perhaps you already have a datafile
+ * with IT files in and they use a different type).
+ *
+ * This installs the quick loader: the song length and fast seek points are
+ * not calculated.
+ */
+void dumb_register_dat_it_quick(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_it_quick,
+		&_dat_unload_duh
+	);
+}
--- /dev/null
+++ b/dumb/src/allegro/datmod.c
@@ -1,0 +1,61 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datmod.c - Integration of MOD files with           / / \  \
+ *            Allegro's datafiles.                   | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_mod(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_mod(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_mod(): tells Allegro about the MOD datafile object. If
+ * you intend to load a datafile containing a MOD object, you must call this
+ * function first. It is recommended you pass DUMB_DAT_MOD, but you may have
+ * a reason to use a different type (perhaps you already have a datafile with
+ * MOD files in and they use a different type).
+ */
+void dumb_register_dat_mod(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_mod,
+		&_dat_unload_duh
+	);
+}
--- /dev/null
+++ b/dumb/src/allegro/datmodq.c
@@ -1,0 +1,64 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datmodq.c - Integration of MOD files with          / / \  \
+ *             Allegro's datafiles.                  | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_mod_quick(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_mod_quick(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_mod_quick(): tells Allegro about the MOD datafile object.
+ * If you intend to load a datafile containing a MOD object, you must call this
+ * function first. It is recommended you pass DUMB_DAT_MOD, but you may have
+ * a reason to use a different type (perhaps you already have a datafile with
+ * MOD files in and they use a different type).
+ *
+ * This installs the quick loader: the song length and fast seek points are
+ * not calculated.
+ */
+void dumb_register_dat_mod_quick(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_mod_quick,
+		&_dat_unload_duh
+	);
+}
--- /dev/null
+++ b/dumb/src/allegro/dats3m.c
@@ -1,0 +1,61 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * dats3m.c - Integration of S3M files with           / / \  \
+ *            Allegro's datafiles.                   | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_s3m(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_s3m(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_s3m(): tells Allegro about the S3M datafile object. If
+ * you intend to load a datafile containing an S3M object, you must call this
+ * function first. It is recommended you pass DUMB_DAT_S3M, but you may have
+ * a reason to use a different type (perhaps you already have a datafile with
+ * S3M files in and they use a different type).
+ */
+void dumb_register_dat_s3m(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_s3m,
+		&_dat_unload_duh
+	);
+}
--- /dev/null
+++ b/dumb/src/allegro/dats3mq.c
@@ -1,0 +1,64 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * dats3mq.c - Integration of S3M files with          / / \  \
+ *             Allegro's datafiles.                  | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_s3m_quick(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_s3m_quick(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_s3m_quick(): tells Allegro about the S3M datafile object.
+ * If you intend to load a datafile containing an S3M object, you must call this
+ * function first. It is recommended you pass DUMB_DAT_S3M, but you may have
+ * a reason to use a different type (perhaps you already have a datafile with
+ * S3M files in and they use a different type).
+ *
+ * This installs the quick loader: the song length and fast seek points are
+ * not calculated.
+ */
+void dumb_register_dat_s3m_quick(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_s3m_quick,
+		&_dat_unload_duh
+	);
+}
--- /dev/null
+++ b/dumb/src/allegro/datunld.c
@@ -1,0 +1,31 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datunld.c - Unload function for integration        / / \  \
+ *             with Allegro's datafiles.             | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+void _dat_unload_duh(void *duh)
+{
+	unload_duh(duh);
+}
+
--- /dev/null
+++ b/dumb/src/allegro/datxm.c
@@ -1,0 +1,62 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datxm.c - Integration of XM files with             / / \  \
+ *           Allegro's datafiles.                    | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_xm(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_xm(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_xm(): tells Allegro about the XM datafile object. If you
+ * intend to load a datafile containing an XM object, you must call this
+ * function first. It is recommended you pass DUMB_DAT_XM, but you may have a
+ * reason to use a different type (perhaps you already have a datafile with
+ * XM files in and they use a different type).
+ */
+void dumb_register_dat_xm(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_xm,
+		&_dat_unload_duh
+	);
+}
+
--- /dev/null
+++ b/dumb/src/allegro/datxmq.c
@@ -1,0 +1,64 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * datxmq.c - Integration of XM files with            / / \  \
+ *            Allegro's datafiles.                   | <  /   \_
+ *                                                   |  \/ /\   /
+ * By entheh.                                         \_  /  > /
+ *                                                      | \ / /
+ *                                                      |  ' /
+ *                                                       \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+#include "internal/aldumb.h"
+
+
+
+static void *dat_read_xm_quick(PACKFILE *f, long size)
+{
+	DUMBFILE *df;
+	DUH *duh;
+
+	(void)size;
+
+	df = dumbfile_open_packfile(f);
+
+	if (!df)
+		return NULL;
+
+	duh = dumb_read_xm_quick(df);
+
+	dumbfile_close(df);
+
+	return duh;
+}
+
+
+
+/* dumb_register_dat_xm_quick(): tells Allegro about the XM datafile object.
+ * If you intend to load a datafile containing an XM object, you must call this
+ * function first. It is recommended you pass DUMB_DAT_XM, but you may have a
+ * reason to use a different type (perhaps you already have a datafile with
+ * XM files in and they use a different type).
+ *
+ * This installs the quick loader: the song length and fast seek points are
+ * not calculated.
+ */
+void dumb_register_dat_xm_quick(long type)
+{
+	register_datafile_object(
+		type,
+		&dat_read_xm_quick,
+		&_dat_unload_duh
+	);
+}
--- /dev/null
+++ b/dumb/src/allegro/packfile.c
@@ -1,0 +1,98 @@
+/*  _______         ____    __         ___    ___
+ * \    _  \       \    /  \  /       \   \  /   /       '   '  '
+ *  |  | \  \       |  |    ||         |   \/   |         .      .
+ *  |  |  |  |      |  |    ||         ||\  /|  |
+ *  |  |  |  |      |  |    ||         || \/ |  |         '  '  '
+ *  |  |  |  |      |  |    ||         ||    |  |         .      .
+ *  |  |_/  /        \  \__//          ||    |  |
+ * /_______/ynamic    \____/niversal  /__\  /____\usic   /|  .  . ibliotheque
+ *                                                      /  \
+ *                                                     / .  \
+ * packfile.c - Packfile input module.                / / \  \
+ *                                                   | <  /   \_
+ * By entheh.                                        |  \/ /\   /
+ *                                                    \_  /  > /
+ * Note that this does not use file compression;        | \ / /
+ * for that you must open the file yourself and         |  ' /
+ * then use dumbfile_open_packfile().                    \__/
+ */
+
+#include <allegro.h>
+
+#include "aldumb.h"
+
+
+
+static void *dumb_packfile_open(const char *filename)
+{
+	return pack_fopen(filename, F_READ);
+}
+
+
+
+static int dumb_packfile_skip(void *f, long n)
+{
+	return pack_fseek(f, n);
+}
+
+
+
+static int dumb_packfile_getc(void *f)
+{
+	return pack_getc(f);
+}
+
+
+
+static long dumb_packfile_getnc(char *ptr, long n, void *f)
+{
+	return pack_fread(ptr, n, f);
+}
+
+
+
+static void dumb_packfile_close(void *f)
+{
+	pack_fclose(f);
+}
+
+
+
+static DUMBFILE_SYSTEM packfile_dfs = {
+	&dumb_packfile_open,
+	&dumb_packfile_skip,
+	&dumb_packfile_getc,
+	&dumb_packfile_getnc,
+	&dumb_packfile_close
+};
+
+
+
+void dumb_register_packfiles(void)
+{
+	register_dumbfile_system(&packfile_dfs);
+}
+
+
+
+static DUMBFILE_SYSTEM packfile_dfs_leave_open = {
+	NULL,
+	&dumb_packfile_skip,
+	&dumb_packfile_getc,
+	&dumb_packfile_getnc,
+	NULL
+};
+
+
+
+DUMBFILE *dumbfile_open_packfile(PACKFILE *p)
+{
+	return dumbfile_open_ex(p, &packfile_dfs_leave_open);
+}
+
+
+
+DUMBFILE *dumbfile_from_packfile(PACKFILE *p)
+{
+	return p ? dumbfile_open_ex(p, &packfile_dfs) : NULL;
+}