ref: 54a1797e76b72fdc2d8aa780b920179c9c18cb24
parent: 242103a85280e574a5b881e277e43159d1aaeffb
parent: b1fd89712225fed501970ab417706453f7640fc6
author: Christopher Snowhill <kode54@gmail.com>
date: Thu May 5 19:11:48 EDT 2016
Merge pull request #29 from winterheart/allegro4 Allegro4 support
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,6 +4,7 @@
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake-scripts)
option(BUILD_EXAMPLES "Build example binaries" ON)
+option(BUILD_ALLEGRO4 "Build Allegro4 support" ON)
set(CMAKE_C_FLAGS "-Wall -DDUMB_DECLARE_DEPRECATED -D_USE_SSE -msse -Wno-unused-variable -Wno-unused-but-set-variable")
set(CMAKE_C_FLAGS_DEBUG "-ggdb -DDEBUGMODE=1 -D_DEBUG")
@@ -21,6 +22,12 @@
message(STATUS "Not building examples")
endif()
+if(BUILD_ALLEGRO4)
+ find_package(Allegro4)
+else()
+ message(STATUS "Not building Allegro 4 support")
+endif()
+
SET(SOURCES
src/core/unload.c
src/core/rendsig.c
@@ -113,9 +120,33 @@
../include/dumb.h
)
+set(ALLEGRO_SOURCES
+ src/allegro/alplay.c
+ src/allegro/datitq.c
+ src/allegro/dats3m.c
+ src/allegro/datxm.c
+ src/allegro/datduh.c
+ src/allegro/datmod.c
+ src/allegro/dats3mq.c
+ src/allegro/datxmq.c
+ src/allegro/datit.c
+ src/allegro/datmodq.c
+ src/allegro/datunld.c
+ src/allegro/packfile.c
+)
+
+
add_library(dumb ${SOURCES})
set_target_properties(dumb PROPERTIES DEBUG_POSTFIX d)
+set(ALLEGRO4_TARGETS "")
+if(BUILD_ALLEGRO4)
+ add_library(aldmb ${ALLEGRO_SOURCES})
+ set(ALLEGRO4_TARGETS ${ALLEGRO_TARGETS} aldmb)
+ set(ALLEGRO4_HEADERS indclude/aldumb.h)
+ target_link_libraries(aldmb ${ALLEGRO_LIBRARIES})
+endif()
+
set(EXAMPLE_TARGETS "")
if(BUILD_EXAMPLES)
@@ -141,7 +172,7 @@
target_link_libraries(dumb m)
-INSTALL(FILES ${INSTALL_HEADERS} DESTINATION include/)
+INSTALL(FILES ${INSTALL_HEADERS} ${ALLEGRO_HEADERS} DESTINATION include/)
INSTALL(TARGETS dumb ${EXAMPLE_TARGETS}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib${LIB_SUFFIX}
--- /dev/null
+++ b/cmake-scripts/FindAllegro4.cmake
@@ -1,0 +1,51 @@
+# - Find allegro
+# Find the native ALLEGRO includes and library
+#
+# ALLEGRO_INCLUDE_DIR - where to find allegro.h, etc.
+# ALLEGRO_LIBRARIES - List of libraries when using allegro.
+# ALLEGRO_FOUND - True if allegro found.
+
+
+IF (ALLEGRO_INCLUDE_DIR)
+ # Already in cache, be silent
+ SET(ALLEGRO_FIND_QUIETLY TRUE)
+ENDIF (ALLEGRO_INCLUDE_DIR)
+
+FIND_PATH(ALLEGRO_INCLUDE_DIR allegro.h
+/usr/local/include
+/usr/include
+$ENV{MINGDIR}/include
+)
+
+if(UNIX AND NOT CYGWIN)
+ exec_program(allegro-config ARGS --libs OUTPUT_VARIABLE ALLEGRO_LIBRARY)
+else(UNIX AND NOT CYGWIN)
+ SET(ALLEGRO_NAMES alleg alleglib alleg41 alleg42 allegdll)
+ FIND_LIBRARY(ALLEGRO_LIBRARY
+ NAMES ${ALLEGRO_NAMES}
+ PATHS /usr/lib /usr/local/lib $ENV{MINGDIR}/lib)
+endif(UNIX AND NOT CYGWIN)
+
+IF (ALLEGRO_INCLUDE_DIR AND ALLEGRO_LIBRARY)
+ SET(ALLEGRO_FOUND TRUE)
+ SET( ALLEGRO_LIBRARIES ${ALLEGRO_LIBRARY} )
+ELSE (ALLEGRO_INCLUDE_DIR AND ALLEGRO_LIBRARY)
+ SET(ALLEGRO_FOUND FALSE)
+ SET( ALLEGRO_LIBRARIES )
+ENDIF (ALLEGRO_INCLUDE_DIR AND ALLEGRO_LIBRARY)
+
+IF (ALLEGRO_FOUND)
+ IF (NOT ALLEGRO_FIND_QUIETLY)
+ MESSAGE(STATUS "Found Allegro: ${ALLEGRO_LIBRARY}")
+ ENDIF (NOT ALLEGRO_FIND_QUIETLY)
+ELSE (ALLEGRO_FOUND)
+ IF (ALLEGRO_FIND_REQUIRED)
+ MESSAGE(STATUS "Looked for Allegro libraries named ${ALLEGRO_NAMES}.")
+ MESSAGE(FATAL_ERROR "Could NOT find Allegro library")
+ ENDIF (ALLEGRO_FIND_REQUIRED)
+ENDIF (ALLEGRO_FOUND)
+
+MARK_AS_ADVANCED(
+ALLEGRO_LIBRARY
+ALLEGRO_INCLUDE_DIR
+)
\ No newline at end of file
--- /dev/null
+++ b/include/aldumb.h
@@ -1,0 +1,98 @@
+/* _______ ____ __ ___ ___
+ * \ _ \ \ / \ / \ \ / / ' ' '
+ * | | \ \ | | || | \/ | . .
+ * | | | | | | || ||\ /| |
+ * | | | | | | || || \/ | | ' ' '
+ * | | | | | | || || | | . .
+ * | |_/ / \ \__// || | |
+ * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
+ * / \
+ * / . \
+ * aldumb.h - The user header file for DUMB with / / \ \
+ * Allegro. | < / \_
+ * | \/ /\ /
+ * Include this file if you wish to use DUMB \_ / > /
+ * with Allegro. It will include dumb.h for you, | \ / /
+ * and provide extra functionality such as audio | ' /
+ * stream and datafile integration. \__/
+ */
+
+#ifndef ALDUMB_H
+#define ALDUMB_H
+
+
+#include <allegro.h>
+
+#include "dumb.h"
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* Packfile Support */
+
+void dumb_register_packfiles(void);
+
+DUMBFILE *dumbfile_open_packfile(PACKFILE *p);
+DUMBFILE *dumbfile_from_packfile(PACKFILE *p);
+
+
+/* Datafile Registration Functions */
+
+#define DUMB_DAT_DUH DAT_ID('D','U','H',' ')
+#define DUMB_DAT_IT DAT_ID('I','T',' ',' ')
+#define DUMB_DAT_XM DAT_ID('X','M',' ',' ')
+#define DUMB_DAT_S3M DAT_ID('S','3','M',' ')
+#define DUMB_DAT_MOD DAT_ID('M','O','D',' ')
+
+void dumb_register_dat_duh(long type);
+void dumb_register_dat_it(long type);
+void dumb_register_dat_xm(long type);
+void dumb_register_dat_s3m(long type);
+void dumb_register_dat_mod(long type);
+void dumb_register_dat_it_quick(long type);
+void dumb_register_dat_xm_quick(long type);
+void dumb_register_dat_s3m_quick(long type);
+void dumb_register_dat_mod_quick(long type);
+
+
+/* DUH Playing Functions */
+
+typedef struct AL_DUH_PLAYER AL_DUH_PLAYER;
+
+AL_DUH_PLAYER *al_start_duh(DUH *duh, int n_channels, long pos, float volume, long bufsize, int freq);
+void al_stop_duh(AL_DUH_PLAYER *dp);
+void al_pause_duh(AL_DUH_PLAYER *dp);
+void al_resume_duh(AL_DUH_PLAYER *dp);
+void al_duh_set_priority(AL_DUH_PLAYER *dp, int priority);
+void al_duh_set_volume(AL_DUH_PLAYER *dp, float volume);
+float al_duh_get_volume(AL_DUH_PLAYER *dp);
+int al_poll_duh(AL_DUH_PLAYER *dp);
+long al_duh_get_position(AL_DUH_PLAYER *dp);
+
+AL_DUH_PLAYER *al_duh_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer, float volume, long bufsize, int freq);
+DUH_SIGRENDERER *al_duh_get_sigrenderer(AL_DUH_PLAYER *dp);
+
+/* IMPORTANT: This function will return NULL if the music has ended. */
+DUH_SIGRENDERER *al_duh_decompose_to_sigrenderer(AL_DUH_PLAYER *dp);
+
+#ifdef DUMB_DECLARE_DEPRECATED
+
+AL_DUH_PLAYER *al_duh_encapsulate_renderer(DUH_SIGRENDERER *dr, float volume, long bufsize, int freq) DUMB_DEPRECATED;
+DUH_SIGRENDERER *al_duh_get_renderer(AL_DUH_PLAYER *dp) DUMB_DEPRECATED;
+DUH_SIGRENDERER *al_duh_decompose_to_renderer(AL_DUH_PLAYER *dp) DUMB_DEPRECATED;
+/* Replace 'renderer' with 'sigrenderer' in each case where you called one of
+ * these functions.
+ */
+
+#endif
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+
+#endif /* ALDUMB_H */
--- /dev/null
+++ b/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/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/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/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/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, 2);
+
+ 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/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, 2);
+
+ 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/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/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/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/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/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/src/allegro/packfile.c
@@ -1,0 +1,134 @@
+/* _______ ____ __ ___ ___
+ * \ _ \ \ / \ / \ \ / / ' ' '
+ * | | \ \ | | || | \/ | . .
+ * | | | | | | || ||\ /| |
+ * | | | | | | || || \/ | | ' ' '
+ * | | | | | | || || | | . .
+ * | |_/ / \ \__// || | |
+ * /_______/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"
+
+
+typedef struct dumb_packfile
+{
+ FILE * file;
+ long size;
+} dumb_packfile;
+
+
+static void *dumb_packfile_open(const char *filename)
+{
+ dumb_packfile * file = ( dumb_packfile * ) malloc( sizeof(dumb_packfile) );
+ if ( !file ) return 0;
+ file->file = fopen(filename, "rb");
+ fseek(file->file, 0, SEEK_END);
+ file->size = ftell(file->file);
+ fseek(file->file, 0, SEEK_SET);
+ return file;
+}
+
+
+
+static int dumb_packfile_skip(void *f, long n)
+{
+ dumb_packfile * file = ( dumb_packfile * ) f;
+ return fseek(file->file, n, SEEK_CUR);
+}
+
+
+
+static int dumb_packfile_getc(void *f)
+{
+ dumb_packfile * file = ( dumb_packfile * ) f;
+ return fgetc(file->file);
+}
+
+
+
+static long dumb_packfile_getnc(char *ptr, long n, void *f)
+{
+ dumb_packfile * file = ( dumb_packfile * ) f;
+ return fread(ptr, 1, n, file->file);
+}
+
+
+
+static void dumb_packfile_close(void *f)
+{
+ dumb_packfile * file = ( dumb_packfile * ) f;
+ fclose(file->file);
+ free(f);
+}
+
+static void dumb_packfile_noclose(void *f)
+{
+ free(f);
+}
+
+static int dumb_packfile_seek(void *f, long n)
+{
+ dumb_packfile * file = (dumb_packfile *) f;
+ return fseek(file->file, n, SEEK_SET);
+}
+
+static long dumb_packfile_get_size(void *f)
+{
+ dumb_packfile * file = (dumb_packfile *) f;
+ return file->size;
+}
+
+static DUMBFILE_SYSTEM packfile_dfs = {
+ &dumb_packfile_open,
+ &dumb_packfile_skip,
+ &dumb_packfile_getc,
+ &dumb_packfile_getnc,
+ &dumb_packfile_close,
+ &dumb_packfile_seek,
+ &dumb_packfile_get_size
+};
+
+
+
+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,
+ &dumb_packfile_noclose,
+ &dumb_packfile_seek,
+ &dumb_packfile_get_size
+};
+
+
+
+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;
+}