From 9537a2f5693b3f722ecec85750e8e55cafc4e425 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 3 Oct 2009 20:43:33 +0000 Subject: [PATCH] Sam Lantinga - Sat Oct 3 13:33:36 PDT 2009 * MOD support uses libmikmod and is dynamically loaded by default --- CHANGES | 2 + configure.in | 184 +- dynamic_mod.c | 276 +++ dynamic_mod.h | 63 + mikmod/AUTHORS | 124 -- mikmod/COPYING.LESSER | 504 ------ mikmod/README | 13 - mikmod/drv_nos.c | 116 -- mikmod/load_669.c | 368 ---- mikmod/load_amf.c | 569 ------- mikmod/load_dsm.c | 364 ---- mikmod/load_far.c | 346 ---- mikmod/load_gdm.c | 558 ------ mikmod/load_imf.c | 738 -------- mikmod/load_it.c | 1008 ----------- mikmod/load_m15.c | 505 ------ mikmod/load_med.c | 719 -------- mikmod/load_mod.c | 512 ------ mikmod/load_mtm.c | 285 ---- mikmod/load_okt.c | 460 ----- mikmod/load_s3m.c | 470 ----- mikmod/load_stm.c | 374 ---- mikmod/load_stx.c | 439 ----- mikmod/load_ult.c | 335 ---- mikmod/load_uni.c | 717 -------- mikmod/load_xm.c | 832 --------- mikmod/mdreg.c | 54 - mikmod/mdriver.c | 943 ----------- mikmod/mikmod.h | 741 -------- mikmod/mikmod_build.h | 717 -------- mikmod/mikmod_internals.h | 720 -------- mikmod/mloader.c | 594 ------- mikmod/mlreg.c | 72 - mikmod/mlutil.c | 336 ---- mikmod/mmalloc.c | 59 - mikmod/mmerror.c | 197 --- mikmod/mmio.c | 454 ----- mikmod/mplayer.c | 3386 ------------------------------------- mikmod/munitrk.c | 305 ---- mikmod/mwav.c | 198 --- mikmod/npertab.c | 48 - mikmod/sloader.c | 520 ------ mikmod/virtch.c | 942 ----------- mikmod/virtch2.c | 906 ---------- mikmod/virtch_common.c | 461 ----- music.c | 28 +- music_mod.c | 181 +- music_mod.h | 6 - 48 files changed, 516 insertions(+), 22233 deletions(-) create mode 100644 dynamic_mod.c create mode 100644 dynamic_mod.h delete mode 100644 mikmod/AUTHORS delete mode 100644 mikmod/COPYING.LESSER delete mode 100644 mikmod/README delete mode 100644 mikmod/drv_nos.c delete mode 100644 mikmod/load_669.c delete mode 100644 mikmod/load_amf.c delete mode 100644 mikmod/load_dsm.c delete mode 100644 mikmod/load_far.c delete mode 100644 mikmod/load_gdm.c delete mode 100644 mikmod/load_imf.c delete mode 100644 mikmod/load_it.c delete mode 100644 mikmod/load_m15.c delete mode 100644 mikmod/load_med.c delete mode 100644 mikmod/load_mod.c delete mode 100644 mikmod/load_mtm.c delete mode 100644 mikmod/load_okt.c delete mode 100644 mikmod/load_s3m.c delete mode 100644 mikmod/load_stm.c delete mode 100644 mikmod/load_stx.c delete mode 100644 mikmod/load_ult.c delete mode 100644 mikmod/load_uni.c delete mode 100644 mikmod/load_xm.c delete mode 100644 mikmod/mdreg.c delete mode 100644 mikmod/mdriver.c delete mode 100644 mikmod/mikmod.h delete mode 100644 mikmod/mikmod_build.h delete mode 100644 mikmod/mikmod_internals.h delete mode 100644 mikmod/mloader.c delete mode 100644 mikmod/mlreg.c delete mode 100644 mikmod/mlutil.c delete mode 100644 mikmod/mmalloc.c delete mode 100644 mikmod/mmerror.c delete mode 100644 mikmod/mmio.c delete mode 100644 mikmod/mplayer.c delete mode 100644 mikmod/munitrk.c delete mode 100644 mikmod/mwav.c delete mode 100644 mikmod/npertab.c delete mode 100644 mikmod/sloader.c delete mode 100644 mikmod/virtch.c delete mode 100644 mikmod/virtch2.c delete mode 100644 mikmod/virtch_common.c diff --git a/CHANGES b/CHANGES index 5b9669db..0646a3db 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ 1.2.9: +Sam Lantinga - Sat Oct 3 13:33:36 PDT 2009 + * MOD support uses libmikmod and is dynamically loaded by default Sam Lantinga - Sat Oct 3 02:49:41 PDT 2009 * Added TIMIDITY_CFG environment variable to fully locate timidity.cfg O.Sezer - 2009-10-02 08:41:50 PDT diff --git a/configure.in b/configure.in index a8640d32..04b655cf 100644 --- a/configure.in +++ b/configure.in @@ -152,6 +152,7 @@ if test x$enable_music_cmd = xyes; then SOURCES="$SOURCES $srcdir/music_cmd.c" EXTRA_CFLAGS="$EXTRA_CFLAGS -DCMD_MUSIC" fi + AC_ARG_ENABLE([music-wave], AC_HELP_STRING([--enable-music-wave], [enable streaming WAVE music [[default=yes]]]), [], [enable_music_wave=yes]) @@ -159,22 +160,27 @@ if test x$enable_music_wave = xyes; then SOURCES="$SOURCES $srcdir/wavestream.c" EXTRA_CFLAGS="$EXTRA_CFLAGS -DWAV_MUSIC" fi -no_libmikmod=yes -libmikmod_maj=3 -libmikmod_min=1 -libmikmod_rev=10 -libmikmod_ver="$libmikmod_maj.$libmikmod_min.$libmikmod_rev" -AC_ARG_ENABLE([music-libmikmod], -AC_HELP_STRING([--enable-music-libmikmod], [enable MOD music via external libmikmod [[default=no]]]), - [], [enable_music_libmikmod=no]) -if test x$enable_music_libmikmod = xyes; then + +AC_ARG_ENABLE([music-mod], +AC_HELP_STRING([--enable-music-mod], [enable MOD music via mikmod [[default=yes]]]), + [], [enable_music_mod=yes]) +AC_ARG_ENABLE([music-mod-shared], +AC_HELP_STRING([--enable-music-mod-shared], [dynamically load MOD support [[default=yes]]]), + [], [enable_music_mod_shared=yes]) +if test x$enable_music_mod = xyes; then + have_libmikmod=no + libmikmod_maj=3 + libmikmod_min=1 + libmikmod_rev=10 + libmikmod_ver="$libmikmod_maj.$libmikmod_min.$libmikmod_rev" AC_PATH_PROG(LIBMIKMOD_CONFIG, libmikmod-config, no, [$PATH]) if test "$LIBMIKMOD_CONFIG" != "no" ; then - no_libmikmod=no + CFLAGS_SAVED="$CFLAGS" LIBS_SAVED="$LIBS" CFLAGS="$CFLAGS -DLIBMIKMOD_MUSIC `$LIBMIKMOD_CONFIG --cflags`" LIBS="$LIBS `$LIBMIKMOD_CONFIG --libs`" + have_libmikmod=yes AC_MSG_CHECKING([for libmikmod - version >= $libmikmod_ver]) AC_TRY_RUN([ #include "mikmod.h" @@ -182,36 +188,48 @@ if test x$enable_music_libmikmod = xyes; then int main(int argc, char **argv) { - long maj=$libmikmod_maj,min=$libmikmod_min,rev=$libmikmod_rev,ver=MikMod_GetVersion(); - /*printf("(%d.%d.%d) ",ver>>16,(ver>>8)&0xff,ver&0xff);*/ - if(ver>=((maj<<16)|(min<<8)|(rev))) { - printf("yes\n"); - return 0; - } - printf("no\n*** libmikmod is older than %d.%d.%d, not using.\n",maj,min,rev); - return 1; +long maj=$libmikmod_maj,min=$libmikmod_min,rev=$libmikmod_rev,ver=MikMod_GetVersion(); +/*printf("(%d.%d.%d) ",ver>>16,(ver>>8)&0xff,ver&0xff);*/ +if(ver>=((maj<<16)|(min<<8)|(rev))) { + printf("yes\n"); + return 0; +} +printf("no\n*** libmikmod is older than %d.%d.%d, not using.\n",maj,min,rev); +return 1; } -], , , [echo $ac_n "cross compiling; assumed OK... $ac_c"]) +], [], have_libmikmod=no; CFLAGS="$CFLAGS_SAVED"; LIBS="$LIBS_SAVED", + [echo $ac_n "cross compiling; assumed OK... $ac_c"]) fi - CFLAGS="$CFLAGS_SAVED" - LIBS="$LIBS_SAVED" -fi -AC_ARG_ENABLE([music-mod], -AC_HELP_STRING([--enable-music-mod], [enable MOD music via mikmod [[default=yes]]]), - [], [enable_music_mod=yes]) -if test x$enable_music_mod = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS -DMOD_MUSIC" - SOURCES="$SOURCES $srcdir/music_mod.c" - - if test x$enable_music_libmikmod = xyes; then - EXTRA_CFLAGS="$EXTRA_CFLAGS -DLIBMIKMOD_MUSIC `$LIBMIKMOD_CONFIG --cflags`" - EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$LIBMIKMOD_CONFIG --libs`" + if test x$have_libmikmod = xyes; then + case "$host" in + *-*-darwin*) + mikmod_lib=[`find_lib libmikmod*.dylib`] + ;; + *-*-cygwin* | *-*-mingw32*) + mikmod_lib=[`find_lib "mikmod*.dll"`] + ;; + *) + mikmod_lib=[`find_lib "libmikmod*.so.[0-9]"`] + if test x$mikmod_lib = x; then + mikmod_lib=[`find_lib "libmikmod*.so.[0-9]*"`] + fi + ;; + esac + SOURCES="$SOURCES $srcdir/*_mod.c" + EXTRA_CFLAGS="$EXTRA_CFLAGS -DMOD_MUSIC `$LIBMIKMOD_CONFIG --cflags`" + if test x$enable_music_mod_shared = xyes && test x$mikmod_lib != x; then + echo "-- dynamic libmikmod -> $mikmod_lib" + EXTRA_CFLAGS="$EXTRA_CFLAGS -DMOD_DYNAMIC=\\\"$mikmod_lib\\\"" + else + EXTRA_LDFLAGS="$EXTRA_LDFLAGS `$LIBMIKMOD_CONFIG --libs`" + fi else - EXTRA_CFLAGS="$EXTRA_CFLAGS -I\$(srcdir)/mikmod" - SOURCES="$SOURCES $srcdir/mikmod/*.c" + AC_MSG_WARN([*** Unable to find MikMod library (http://mikmod.raphnet.net/)]) + AC_MSG_WARN([MOD support disabled]) fi fi + AC_ARG_ENABLE([music-midi], AC_HELP_STRING([--enable-music-midi], [enable MIDI music via timidity [[default=yes]]]), [], [enable_music_midi=yes]) @@ -262,11 +280,12 @@ AC_HELP_STRING([--enable-music-native-midi-gpl], [enable native MIDI on UNIX usi fi fi fi + AC_ARG_ENABLE([music-ogg], AC_HELP_STRING([--enable-music-ogg], [enable Ogg Vorbis music [[default=yes]]]), [], [enable_music_ogg=yes]) AC_ARG_ENABLE(music-ogg-tremor, -[ --enable-music-ogg-tremor enable OGG music via libtremor [[default=no]]], +AC_HELP_STRING([--enable-music-ogg-tremor], [enable OGG Vorbis music via libtremor [[default=no]]]), [], enable_music_ogg_tremor=no) AC_ARG_ENABLE([music-ogg-shared], AC_HELP_STRING([--enable-music-ogg-shared], [dynamically load Ogg Vorbis support [[default=yes]]]), @@ -304,6 +323,9 @@ if test x$enable_music_ogg = xyes; then else EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lvorbisidec" fi + else + AC_MSG_WARN([*** Unable to find Ogg Vorbis Tremor library (http://www.xiph.org/)]) + AC_MSG_WARN([Ogg Vorbis support disabled]) fi else AC_CHECK_HEADER([vorbis/vorbisfile.h], [have_ogg_hdr=yes]) @@ -331,9 +353,13 @@ if test x$enable_music_ogg = xyes; then else EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lvorbisfile -lvorbis -logg" fi + else + AC_MSG_WARN([*** Unable to find Ogg Vorbis library (http://www.xiph.org/)]) + AC_MSG_WARN([Ogg Vorbis support disabled]) fi fi fi + libflac_ver=8 AC_ARG_ENABLE([music-flac], AC_HELP_STRING([--enable-music-flac], [enable FLAC music [[default=yes]]]), @@ -359,50 +385,53 @@ int main( int argc, char *argv[] ) { #endif } ], have_flac_ver=yes, have_flac_ver=no) - LIBS="$LIBS_SAVED" - AC_MSG_RESULT($have_flac_ver) - if test x$have_flac_ver = xno; then - echo "*** FLAC support has been disabled." - else - AC_CHECK_HEADER([FLAC/stream_decoder.h], [have_flac_hdr=yes]) - AC_CHECK_LIB([FLAC], [FLAC__stream_decoder_new], [have_flac_lib=yes]) - if test x$have_flac_hdr = xyes -a x$have_flac_lib = xyes; then - case "$host" in - *-*-darwin*) - flac_lib=[`find_lib FLAC*.dylib`] - ;; - *-*-cygwin* | *-*-mingw32*) - flac_lib=[`find_lib "libFLAC*.dll"`] - ;; - *) - flac_lib=[`find_lib "libFLAC.so.[0-9]"`] - if test x$flac_lib = x; then - flac_lib=[`find_lib "libFLAC.so.[0-9]*"`] - fi - ;; - esac - SOURCES="$SOURCES $srcdir/*_flac.c" - EXTRA_CFLAGS="$EXTRA_CFLAGS -DFLAC_MUSIC" - if test x$enable_music_flac_shared = xyes && test x$flac_lib != x; then - echo "-- dynamic libFLAC -> $flac_lib" - EXTRA_CFLAGS="$EXTRA_CFLAGS -DFLAC_DYNAMIC=\\\"$flac_lib\\\"" - else - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lFLAC" - fi - fi - fi - fi + LIBS="$LIBS_SAVED" + AC_MSG_RESULT($have_flac_ver) + fi + + if test x$have_flac_ver = xyes; then + AC_CHECK_HEADER([FLAC/stream_decoder.h], [have_flac_hdr=yes]) + AC_CHECK_LIB([FLAC], [FLAC__stream_decoder_new], [have_flac_lib=yes]) + if test x$have_flac_hdr = xyes -a x$have_flac_lib = xyes; then + case "$host" in + *-*-darwin*) + flac_lib=[`find_lib libFLAC*.dylib`] + ;; + *-*-cygwin* | *-*-mingw32*) + flac_lib=[`find_lib "libFLAC*.dll"`] + ;; + *) + flac_lib=[`find_lib "libFLAC.so.[0-9]"`] + if test x$flac_lib = x; then + flac_lib=[`find_lib "libFLAC.so.[0-9]*"`] + fi + ;; + esac + SOURCES="$SOURCES $srcdir/*_flac.c" + EXTRA_CFLAGS="$EXTRA_CFLAGS -DFLAC_MUSIC" + if test x$enable_music_flac_shared = xyes && test x$flac_lib != x; then + echo "-- dynamic libFLAC -> $flac_lib" + EXTRA_CFLAGS="$EXTRA_CFLAGS -DFLAC_DYNAMIC=\\\"$flac_lib\\\"" + else + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lFLAC" + fi + fi + else + AC_MSG_WARN([*** Unable to find FLAC library (http://flac.sourceforge.net/)]) + AC_MSG_WARN([FLAC support disabled]) + fi fi + AC_ARG_ENABLE(music-mp3, -[ --enable-music-mp3 enable MP3 music via smpeg [[default=yes]]], - , enable_music_mp3=yes) +AC_HELP_STRING([--enable-music-mp3], [enable MP3 music via smpeg [[default=yes]]]), + [], enable_music_mp3=yes) +AC_ARG_ENABLE([music-mp3-shared], +AC_HELP_STRING([--enable-music-mp3-shared], [dynamically load MP3 support [[default=yes]]]), + [], [enable_music_mp3_shared=yes]) if test x$enable_music_mp3 = xyes; then SMPEG_VERSION=0.4.3 AM_PATH_SMPEG($SMPEG_VERSION, have_smpeg=yes, have_smpeg=no) if test x$have_smpeg = xyes; then - AC_ARG_ENABLE([music-mp3-shared], -AC_HELP_STRING([--enable-music-mp3-shared], [dynamically load MP3 support [[default=yes]]]), - [], [enable_music_mp3_shared=yes]) case "$host" in *-*-darwin*) smpeg_lib=[`find_lib libsmpeg*.dylib`] @@ -425,8 +454,11 @@ AC_HELP_STRING([--enable-music-mp3-shared], [dynamically load MP3 support [[defa else EXTRA_LDFLAGS="$EXTRA_LDFLAGS $SMPEG_LIBS" fi + else + AC_MSG_WARN([*** Unable to find SMPEG library (http://icculus.org/smpeg/)]) fi fi + AC_ARG_ENABLE(music-mp3-mad-gpl, AC_HELP_STRING([--enable-music-mp3-mad-gpl], [enable MP3 music via libmad GPL code [[default=no]]]), [], [enable_music_mp3_mad_gpl=no]) @@ -444,9 +476,15 @@ if test x$enable_music_mp3_mad_gpl = xyes; then SOURCES="$SOURCES $srcdir/music_mad.c" EXTRA_CFLAGS="$EXTRA_CFLAGS -DMP3_MAD_MUSIC" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmad" + else + AC_MSG_WARN([*** Unable to find MAD library (http://www.underbit.com/products/mad/)]) fi fi +if test x$have_smpeg != xyes -a x$have_libmad != xyes; then + AC_MSG_WARN([MP3 support disabled]) +fi + OBJECTS=`echo $SOURCES | sed 's,[[^ ]]*/\([[^ ]]*\)\.c,$(objects)/\1.lo,g'` OBJECTS=`echo $OBJECTS | sed 's,[[^ ]]*/\([[^ ]]*\)\.rc,$(objects)/\1.o,g'` diff --git a/dynamic_mod.c b/dynamic_mod.c new file mode 100644 index 00000000..0703036a --- /dev/null +++ b/dynamic_mod.c @@ -0,0 +1,276 @@ +/* + SDL_mixer: An audio mixer library based on the SDL library + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef MOD_MUSIC + +#include "SDL_loadso.h" + +#include "dynamic_mod.h" + +mikmod_loader mikmod = { + 0, NULL +}; + +#ifdef MOD_DYNAMIC +int Mix_InitMOD() +{ + if ( mikmod.loaded == 0 ) { + mikmod.handle = SDL_LoadObject(MOD_DYNAMIC); + if ( mikmod.handle == NULL ) { + return -1; + } + mikmod.MikMod_Exit = + (void (*)(void)) + SDL_LoadFunction(mikmod.handle, "MikMod_Exit"); + if ( mikmod.MikMod_Exit == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.MikMod_InfoDriver = + (CHAR* (*)(void)) + SDL_LoadFunction(mikmod.handle, "MikMod_InfoDriver"); + if ( mikmod.MikMod_InfoDriver == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.MikMod_InfoLoader = + (CHAR* (*)(void)) + SDL_LoadFunction(mikmod.handle, "MikMod_InfoLoader"); + if ( mikmod.MikMod_InfoLoader == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.MikMod_Init = + (BOOL (*)(CHAR*)) + SDL_LoadFunction(mikmod.handle, "MikMod_Init"); + if ( mikmod.MikMod_Init == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.MikMod_RegisterAllLoaders = + (void (*)(void)) + SDL_LoadFunction(mikmod.handle, "MikMod_RegisterAllLoaders"); + if ( mikmod.MikMod_RegisterAllLoaders == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.MikMod_RegisterDriver = + (void (*)(struct MDRIVER*)) + SDL_LoadFunction(mikmod.handle, "MikMod_RegisterDriver"); + if ( mikmod.MikMod_RegisterDriver == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.MikMod_errno = + (int*) + SDL_LoadFunction(mikmod.handle, "MikMod_errno"); + if ( mikmod.MikMod_errno == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.MikMod_strerror = + (char* (*)(int)) + SDL_LoadFunction(mikmod.handle, "MikMod_strerror"); + if ( mikmod.MikMod_strerror == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.Player_Active = + (BOOL (*)(void)) + SDL_LoadFunction(mikmod.handle, "Player_Active"); + if ( mikmod.Player_Active == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.Player_Free = + (void (*)(MODULE*)) + SDL_LoadFunction(mikmod.handle, "Player_Free"); + if ( mikmod.Player_Free == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.Player_LoadGeneric = + (MODULE* (*)(MREADER*,int,BOOL)) + SDL_LoadFunction(mikmod.handle, "Player_LoadGeneric"); + if ( mikmod.Player_LoadGeneric == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.Player_SetPosition = + (void (*)(UWORD)) + SDL_LoadFunction(mikmod.handle, "Player_SetPosition"); + if ( mikmod.Player_SetPosition == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.Player_SetVolume = + (void (*)(SWORD)) + SDL_LoadFunction(mikmod.handle, "Player_SetVolume"); + if ( mikmod.Player_SetVolume == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.Player_Start = + (void (*)(MODULE*)) + SDL_LoadFunction(mikmod.handle, "Player_Start"); + if ( mikmod.Player_Start == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.Player_Stop = + (void (*)(void)) + SDL_LoadFunction(mikmod.handle, "Player_Stop"); + if ( mikmod.Player_Stop == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.VC_WriteBytes = + (ULONG (*)(SBYTE*,ULONG)) + SDL_LoadFunction(mikmod.handle, "VC_WriteBytes"); + if ( mikmod.VC_WriteBytes == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.drv_nos = + (MDRIVER*) + SDL_LoadFunction(mikmod.handle, "drv_nos"); + if ( mikmod.drv_nos == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_device = + (UWORD*) + SDL_LoadFunction(mikmod.handle, "md_device"); + if ( mikmod.md_device == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_mixfreq = + (UWORD*) + SDL_LoadFunction(mikmod.handle, "md_mixfreq"); + if ( mikmod.md_mixfreq == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_mode = + (UWORD*) + SDL_LoadFunction(mikmod.handle, "md_mode"); + if ( mikmod.md_mode == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_musicvolume = + (UBYTE*) + SDL_LoadFunction(mikmod.handle, "md_musicvolume"); + if ( mikmod.md_musicvolume == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_pansep = + (UBYTE*) + SDL_LoadFunction(mikmod.handle, "md_pansep"); + if ( mikmod.md_pansep == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_reverb = + (UBYTE*) + SDL_LoadFunction(mikmod.handle, "md_reverb"); + if ( mikmod.md_reverb == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_sndfxvolume = + (UBYTE*) + SDL_LoadFunction(mikmod.handle, "md_sndfxvolume"); + if ( mikmod.md_sndfxvolume == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + mikmod.md_volume = + (UBYTE*) + SDL_LoadFunction(mikmod.handle, "md_volume"); + if ( mikmod.md_volume == NULL ) { + SDL_UnloadObject(mikmod.handle); + return -1; + } + } + ++mikmod.loaded; + + return 0; +} +void Mix_QuitMOD() +{ + if ( mikmod.loaded == 0 ) { + return; + } + if ( mikmod.loaded == 1 ) { + SDL_UnloadObject(mikmod.handle); + } + --mikmod.loaded; +} +#else +int Mix_InitMOD() +{ + if ( mikmod.loaded == 0 ) { + mikmod.MikMod_Exit = MikMod_Exit; + mikmod.MikMod_InfoDriver = MikMod_InfoDriver; + mikmod.MikMod_InfoLoader = MikMod_InfoLoader; + mikmod.MikMod_Init = MikMod_Init; + mikmod.MikMod_RegisterAllLoaders = MikMod_RegisterAllLoaders; + mikmod.MikMod_RegisterDriver = MikMod_RegisterDriver; + mikmod.MikMod_errno = &MikMod_errno; + mikmod.MikMod_strerror = MikMod_strerror; + mikmod.Player_Active = Player_Active; + mikmod.Player_Free = Player_Free; + mikmod.Player_LoadGeneric = Player_LoadGeneric; + mikmod.Player_SetPosition = Player_SetPosition; + mikmod.Player_SetVolume = Player_SetVolume; + mikmod.Player_Start = Player_Start; + mikmod.Player_Stop = Player_Stop; + mikmod.VC_WriteBytes = VC_WriteBytes; + mikmod.drv_nos = &drv_nos; + mikmod.md_device = &md_device; + mikmod.md_mixfreq = &md_mixfreq; + mikmod.md_mode = &md_mode; + mikmod.md_musicvolume = &md_musicvolume; + mikmod.md_pansep = &md_pansep; + mikmod.md_reverb = &md_reverb; + mikmod.md_sndfxvolume = &md_sndfxvolume; + mikmod.md_volume = &md_volume; + } + ++mikmod.loaded; + + return 0; +} +void Mix_QuitMOD() +{ + if ( mikmod.loaded == 0 ) { + return; + } + if ( mikmod.loaded == 1 ) { + } + --mikmod.loaded; +} +#endif /* MOD_DYNAMIC */ + +#endif /* MOD_MUSIC */ diff --git a/dynamic_mod.h b/dynamic_mod.h new file mode 100644 index 00000000..7294013d --- /dev/null +++ b/dynamic_mod.h @@ -0,0 +1,63 @@ +/* + SDL_mixer: An audio mixer library based on the SDL library + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef MOD_MUSIC + +#include "mikmod.h" + +typedef struct { + int loaded; + void *handle; + + void (*MikMod_Exit)(void); + CHAR* (*MikMod_InfoDriver)(void); + CHAR* (*MikMod_InfoLoader)(void); + BOOL (*MikMod_Init)(CHAR*); + void (*MikMod_RegisterAllLoaders)(void); + void (*MikMod_RegisterDriver)(struct MDRIVER*); + int* MikMod_errno; + char* (*MikMod_strerror)(int); + BOOL (*Player_Active)(void); + void (*Player_Free)(MODULE*); + MODULE* (*Player_LoadGeneric)(MREADER*,int,BOOL); + void (*Player_SetPosition)(UWORD); + void (*Player_SetVolume)(SWORD); + void (*Player_Start)(MODULE*); + void (*Player_Stop)(void); + ULONG (*VC_WriteBytes)(SBYTE*,ULONG); + struct MDRIVER* drv_nos; + UWORD* md_device; + UWORD* md_mixfreq; + UWORD* md_mode; + UBYTE* md_musicvolume; + UBYTE* md_pansep; + UBYTE* md_reverb; + UBYTE* md_sndfxvolume; + UBYTE* md_volume; +} mikmod_loader; + +extern mikmod_loader mikmod; + +extern int Mix_InitMOD(); +extern void Mix_QuitMOD(); + +#endif diff --git a/mikmod/AUTHORS b/mikmod/AUTHORS deleted file mode 100644 index 5752fdf8..00000000 --- a/mikmod/AUTHORS +++ /dev/null @@ -1,124 +0,0 @@ -libmikmod main authors ----------------------- - -* Jean-Paul Mikkers (MikMak) - wrote MikMod and maintained it until version 3. -* Jake Stine (Air Richter) - [email doesn't work anymore...] - made decisive contributions to the code (esp. IT support) and - maintained MikMod version 3 until it was discontinued. He still works - on the WinAmp module plugin, roughly based on MikMod. -* Miod Vallat - current overbooked libmikmod maintainer (since version 3.0.4), made - an audit of the code resulting in many bugs fixed. - -Previous Unix maintainers -------------------------- - -* Steve McIntyre - maintained MikMod'Unix version 2. Used to maintain the Debian package - for MikMod. -* Peter Amstutz - maintained MikMod'Unix version 3 up to version 3.0.3. - -General contributors --------------------- - -* Arne de Bruijn - wrote the compressed IT sample support. -* Shlomi Fish - wrote the Java port, bug fixes. -* Juan Linietsky - overall bug fixes. -* Claudio Matsuoka - wrote the STX loader and submitted bug fixes. -* Sebastiaan A. Megens - fixed various bugs (memory leaks, endianness issues, etc). -* ``UFO'' - wrote the OKT loader. -* Kev Vance - wrote the GDM loader. - -* Paul Fisher made decisive contributions and improvements. -* Alexander Kerkhove fixed an ULT panning effect bug. -* ``Kodiak'' helped on the interfaces of libmikmod. -* Sylvain Marchand make MikMod more portable and GCC compilable. - - -Contributors on the Unix side ------------------------------ - -* Douglas Carmichael - ported MikMod to FreeBSD. -* Chris Conn - wrote the OSS driver. -* Roine Gustaffson - wrote the Digital AudioFile driver. -* Stephan Kanthak - wrote the SGI driver. -* Lutz Vieweg - wrote the AIX and HP-UX drivers. -* Valtteri Vuorikoski - wrote the Sun driver. -* Andy Lo A Foe - wrote the Ultra driver (for the Gravis Ultrasound sound card). -* C Ray C - updated the Ultra driver to work with libmikmod 3. -* ``MenTaLguY'' - autoconfized the Unix libmikmod distribution. -* Tobias Gloth - created the new I/O interface, made the code MT-safe and submitted bug fixes. -* Simon Hosie - wrote the piped output driver, and submitted speed optimizations and bugfixes - for the software mixer. -* Gerd Rausch - wrote the sam9407 driver. -* Joseph Carter - maintains the Debian package for MikMod and libmikmod, submitted - bugfixes. - -Contributors on the Windows side --------------------------------- - -* Brian McKinney - created the DirectSound driver. -* Bjornar Henden - created the Multimedia API windows driver. - -Contributors on the Dos side ----------------------------- - -Their code isn't there anymore, but they contributed to the success of -libmikmod... - -* Jean-Philippe Ajirent wrote the EMS memory routines. -* Peter Breitling ported MikMod to DJGPP. -* Arnout Cosman wrote the PAS driver. -* Mario Koeppen wrote the WSS driver. -* Mike Leibow wrote the GUS driver. -* Jeremy McDonald wrote a fast assembly-language mixer. -* Steffen Rusitschka and Vince Vu wrote the AWE driver. - -Contributors on the Macintosh side ----------------------------------- - -* Anders Bjoerklund - ported libmikmod to the Macintosh. - -Contributors on the OS/2 side ------------------------------ - -* Stefan Tibus - ported libmikmod to OS/2. -* Andrew Zabolotny - improved the existing OS/2 drivers. - -Contributors on the BeOS side ------------------------------ - -* Thomas Neumann - integrated libmikmod into his BeOS APlayer, and contributed many bug fixes. - --- -If your name is missing, don't hesitate to remind me at - diff --git a/mikmod/COPYING.LESSER b/mikmod/COPYING.LESSER deleted file mode 100644 index 67c11819..00000000 --- a/mikmod/COPYING.LESSER +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We this -license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - Another cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does insure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/mikmod/README b/mikmod/README deleted file mode 100644 index 786ea904..00000000 --- a/mikmod/README +++ /dev/null @@ -1,13 +0,0 @@ - - --> MikMod Sound Libraries Version 3.1.12 - --- -This version of the library is based on the official UNIX MikMod -library version 3.1.12, found at: http://mikmod.raphnet.net/ - -It has been stripped down for inclusion with Simple DirectMedia Layer, -but the missing drivers and file loaders can be plugged right in from -the MikMod 3.1.12 archive. - -See COPYING.LESSER for copying information --- diff --git a/mikmod/drv_nos.c b/mikmod/drv_nos.c deleted file mode 100644 index eed87100..00000000 --- a/mikmod/drv_nos.c +++ /dev/null @@ -1,116 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Driver for no output - -==============================================================================*/ - -/* - - Written by Jean-Paul Mikkers - -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#define SDL_MIXER_ONLY - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "mikmod_internals.h" - -#define ZEROLEN 32768 - -#ifndef SDL_MIXER_ONLY -static SBYTE *zerobuf=NULL; -#endif - -static BOOL NS_IsThere(void) -{ - return 1; -} - -static BOOL NS_Init(void) -{ -#ifndef SDL_MIXER_ONLY - zerobuf=(SBYTE*)_mm_malloc(ZEROLEN); -#endif - return VC_Init(); -} - -static void NS_Exit(void) -{ - VC_Exit(); -#ifndef SDL_MIXER_ONLY - _mm_free(zerobuf); -#endif -} - -static void NS_Update(void) -{ -#ifndef SDL_MIXER_ONLY - if (zerobuf) - VC_WriteBytes(zerobuf,ZEROLEN); -#endif -} - -MIKMODAPI MDRIVER drv_nos={ - NULL, - "No Sound", - "Nosound Driver v3.0", - 255,255, - "nosound", - - NULL, - NS_IsThere, - VC_SampleLoad, - VC_SampleUnload, - VC_SampleSpace, - VC_SampleLength, - NS_Init, - NS_Exit, - NULL, - VC_SetNumVoices, - VC_PlayStart, - VC_PlayStop, - NS_Update, - NULL, - VC_VoiceSetVolume, - VC_VoiceGetVolume, - VC_VoiceSetFrequency, - VC_VoiceGetFrequency, - VC_VoiceSetPanning, - VC_VoiceGetPanning, - VC_VoicePlay, - VC_VoiceStop, - VC_VoiceStopped, - VC_VoiceGetPosition, - VC_VoiceRealVolume -}; - - -/* ex:set ts=4: */ diff --git a/mikmod/load_669.c b/mikmod/load_669.c deleted file mode 100644 index 55df89a5..00000000 --- a/mikmod/load_669.c +++ /dev/null @@ -1,368 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_669.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - Composer 669 module loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -/* header */ -typedef struct S69HEADER { - UBYTE marker[2]; - CHAR message[108]; - UBYTE nos; - UBYTE nop; - UBYTE looporder; - UBYTE orders[0x80]; - UBYTE tempos[0x80]; - UBYTE breaks[0x80]; -} S69HEADER; - -/* sample information */ -typedef struct S69SAMPLE { - CHAR filename[13]; - SLONG length; - SLONG loopbeg; - SLONG loopend; -} S69SAMPLE; - -/* encoded note */ -typedef struct S69NOTE { - UBYTE a,b,c; -} S69NOTE; - -/*========== Loader variables */ - -/* current pattern */ -static S69NOTE* s69pat=NULL; -/* Module header */ -static S69HEADER* mh=NULL; - -/* file type identification */ -static CHAR* S69_Version[]={ - "Composer 669", - "Extended 669" -}; - -/*========== Loader code */ - -BOOL S69_Test(void) -{ - UBYTE buf[0x80]; - - if(!_mm_read_UBYTES(buf,2,modreader)) - return 0; - /* look for id */ - if(!memcmp(buf,"if",2) || !memcmp(buf,"JN",2)) { - int i; - - /* skip song message */ - _mm_fseek(modreader,108,SEEK_CUR); - /* sanity checks */ - if(_mm_read_UBYTE(modreader) > 64) return 0; - if(_mm_read_UBYTE(modreader) > 128) return 0; - if(_mm_read_UBYTE(modreader) > 127) return 0; - /* check order table */ - if(!_mm_read_UBYTES(buf,0x80,modreader)) return 0; - for(i=0;i<0x80;i++) - if((buf[i]>=0x80)&&(buf[i]!=0xff)) return 0; - /* check tempos table */ - if(!_mm_read_UBYTES(buf,0x80,modreader)) return 0; - for(i=0;i<0x80;i++) - if((!buf[i])||(buf[i]>32)) return 0; - /* check pattern length table */ - if(!_mm_read_UBYTES(buf,0x80,modreader)) return 0; - for(i=0;i<0x80;i++) - if(buf[i]>0x3f) return 0; - } else - return 0; - - return 1; -} - -BOOL S69_Init(void) -{ - if(!(s69pat=(S69NOTE *)_mm_malloc(64*8*sizeof(S69NOTE)))) return 0; - if(!(mh=(S69HEADER *)_mm_malloc(sizeof(S69HEADER)))) return 0; - - return 1; -} - -void S69_Cleanup(void) -{ - _mm_free(s69pat); - _mm_free(mh); -} - -static BOOL S69_LoadPatterns(void) -{ - int track,row,channel; - UBYTE note,inst,vol,effect,lastfx,lastval; - S69NOTE *cur; - int tracks=0; - - if(!AllocPatterns()) return 0; - if(!AllocTracks()) return 0; - - for(track=0;trackbreaks[track]+1; - - /* load the 669 pattern */ - cur=s69pat; - for(row=0;row<64;row++) { - for(channel=0;channel<8;channel++,cur++) { - cur->a = _mm_read_UBYTE(modreader); - cur->b = _mm_read_UBYTE(modreader); - cur->c = _mm_read_UBYTE(modreader); - } - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - - /* translate the pattern */ - for(channel=0;channel<8;channel++) { - UniReset(); - /* set pattern tempo */ - UniPTEffect(0xf,78); - UniPTEffect(0xf,mh->tempos[track]); - - lastfx=0xff,lastval=0; - - for(row=0;row<=mh->breaks[track];row++) { - int a,b,c; - - /* fetch the encoded note */ - a=s69pat[(row*8)+channel].a; - b=s69pat[(row*8)+channel].b; - c=s69pat[(row*8)+channel].c; - - /* decode it */ - note=a>>2; - inst=((a&0x3)<<4)|((b&0xf0)>>4); - vol=b&0xf; - - if (a<0xff) { - if (a<0xfe) { - UniInstrument(inst); - UniNote(note+2*OCTAVE); - lastfx=0xff; /* reset background effect memory */ - } - UniPTEffect(0xc,vol<<2); - } - - if ((c!=0xff)||(lastfx!=0xff)) { - if(c==0xff) - c=lastfx,effect=lastval; - else - effect=c&0xf; - - switch(c>>4) { - case 0: /* porta up */ - UniPTEffect(0x1,effect); - lastfx=c,lastval=effect; - break; - case 1: /* porta down */ - UniPTEffect(0x2,effect); - lastfx=c,lastval=effect; - break; - case 2: /* porta to note */ - UniPTEffect(0x3,effect); - lastfx=c,lastval=effect; - break; - case 3: /* frequency adjust */ - /* DMP converts this effect to S3M FF1. Why not ? */ - UniEffect(UNI_S3MEFFECTF,0xf0|effect); - break; - case 4: /* vibrato */ - UniPTEffect(0x4,effect); - lastfx=c,lastval=effect; - break; - case 5: /* set speed */ - if (effect) - UniPTEffect(0xf,effect); - else - if(mh->marker[0]!=0x69) { -#ifdef MIKMOD_DEBUG - fprintf(stderr,"\r669: unsupported super fast tempo at pat=%d row=%d chan=%d\n", - track,row,channel); -#endif - } - break; - } - } - UniNewline(); - } - if(!(of.tracks[tracks++]=UniDup())) return 0; - } - } - - return 1; -} - -BOOL S69_Load(BOOL curious) -{ - int i; - SAMPLE *current; - S69SAMPLE sample; - - /* module header */ - _mm_read_UBYTES(mh->marker,2,modreader); - _mm_read_UBYTES(mh->message,108,modreader); - mh->nos=_mm_read_UBYTE(modreader); - mh->nop=_mm_read_UBYTE(modreader); - mh->looporder=_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->orders,0x80,modreader); - for(i=0;i<0x80;i++) - if ((mh->orders[i]>=0x80)&&(mh->orders[i]!=0xff)) { - _mm_errno=MMERR_NOT_A_MODULE; - return 1; - } - _mm_read_UBYTES(mh->tempos,0x80,modreader); - for(i=0;i<0x80;i++) - if ((!mh->tempos[i])||(mh->tempos[i]>32)) { - _mm_errno=MMERR_NOT_A_MODULE; - return 1; - } - _mm_read_UBYTES(mh->breaks,0x80,modreader); - for(i=0;i<0x80;i++) - if (mh->breaks[i]>0x3f) { - _mm_errno=MMERR_NOT_A_MODULE; - return 1; - } - - /* set module variables */ - of.initspeed=4; - of.inittempo=78; - of.songname=DupStr(mh->message,36,1); - of.modtype=strdup(S69_Version[memcmp(mh->marker,"JN",2)==0]); - of.numchn=8; - of.numpat=mh->nop; - of.numins=of.numsmp=mh->nos; - of.numtrk=of.numchn*of.numpat; - of.flags=UF_XMPERIODS|UF_LINEAR; - - for(i= 35;(i>= 0)&&(mh->message[i]==' ');i--) mh->message[i]=0; - for(i=36+35;(i>=36+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; - for(i=72+35;(i>=72+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; - if((mh->message[0])||(mh->message[36])||(mh->message[72])) - if((of.comment=(CHAR*)_mm_malloc(3*(36+1)+1))) { - strncpy(of.comment,mh->message,36); - strcat(of.comment,"\r"); - if (mh->message[36]) strncat(of.comment,mh->message+36,36); - strcat(of.comment,"\r"); - if (mh->message[72]) strncat(of.comment,mh->message+72,36); - strcat(of.comment,"\r"); - of.comment[3*(36+1)]=0; - } - - if(!AllocPositions(0x80)) return 0; - for(i=0;i<0x80;i++) { - if(mh->orders[i]>=mh->nop) break; - of.positions[i]=mh->orders[i]; - } - of.numpos=i; - of.reppos=mh->looporderlooporder:0; - - if(!AllocSamples()) return 0; - current=of.samples; - - for(i=0;isamplename=DupStr(sample.filename,13,1); - current->seekpos=0; - current->speed=0; - current->length=sample.length; - current->loopstart=sample.loopbeg; - current->loopend=sample.loopend; - current->flags=(sample.loopbegvolume=64; - - current++; - } - - if(!S69_LoadPatterns()) return 0; - - return 1; -} - -CHAR *S69_LoadTitle(void) -{ - CHAR s[36]; - - _mm_fseek(modreader,2,SEEK_SET); - if(!_mm_read_UBYTES(s,36,modreader)) return NULL; - - return(DupStr(s,36,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_669={ - NULL, - "669", - "669 (Composer 669, Unis 669)", - S69_Init, - S69_Test, - S69_Load, - S69_Cleanup, - S69_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_amf.c b/mikmod/load_amf.c deleted file mode 100644 index 15d03ffd..00000000 --- a/mikmod/load_amf.c +++ /dev/null @@ -1,569 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_amf.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - DMP Advanced Module Format loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -typedef struct AMFHEADER { - UBYTE id[3]; /* AMF file marker */ - UBYTE version; /* upper major, lower nibble minor version number */ - CHAR songname[32]; /* ASCIIZ songname */ - UBYTE numsamples; /* number of samples saved */ - UBYTE numorders; - UWORD numtracks; /* number of tracks saved */ - UBYTE numchannels; /* number of channels used */ - SBYTE panpos[32]; /* voice pan positions */ - UBYTE songbpm; - UBYTE songspd; -} AMFHEADER; - -typedef struct AMFSAMPLE { - UBYTE type; - CHAR samplename[32]; - CHAR filename[13]; - ULONG offset; - ULONG length; - UWORD c2spd; - UBYTE volume; - ULONG reppos; - ULONG repend; -} AMFSAMPLE; - -typedef struct AMFNOTE { - UBYTE note,instr,volume,fxcnt; - UBYTE effect[3]; - SBYTE parameter[3]; -} AMFNOTE; - -/*========== Loader variables */ - -static AMFHEADER *mh = NULL; -#define AMFTEXTLEN 22 -static CHAR AMF_Version[AMFTEXTLEN+1] = "DSMI Module Format 0.0"; -static AMFNOTE *track = NULL; - -/*========== Loader code */ - -BOOL AMF_Test(void) -{ - UBYTE id[3],ver; - - if(!_mm_read_UBYTES(id,3,modreader)) return 0; - if(memcmp(id,"AMF",3)) return 0; - - ver=_mm_read_UBYTE(modreader); - if((ver>=10)&&(ver<=14)) return 1; - return 0; -} - -BOOL AMF_Init(void) -{ - if(!(mh=(AMFHEADER*)_mm_malloc(sizeof(AMFHEADER)))) return 0; - if(!(track=(AMFNOTE*)_mm_calloc(64,sizeof(AMFNOTE)))) return 0; - - return 1; -} - -void AMF_Cleanup(void) -{ - _mm_free(mh); - _mm_free(track); -} - -static BOOL AMF_UnpackTrack(MREADER* modreader) -{ - ULONG tracksize; - UBYTE row,cmd; - SBYTE arg; - - /* empty track */ - memset(track,0,64*sizeof(AMFNOTE)); - - /* read packed track */ - if (modreader) { - tracksize=_mm_read_I_UWORD(modreader); - tracksize+=((ULONG)_mm_read_UBYTE(modreader))<<16; - if (tracksize) - while(tracksize--) { - row=_mm_read_UBYTE(modreader); - cmd=_mm_read_UBYTE(modreader); - arg=_mm_read_SBYTE(modreader); - /* unexpected end of track */ - if(!tracksize) { - if((row==0xff)&&(cmd==0xff)&&(arg==-1)) - break; - /* the last triplet should be FF FF FF, but this is not - always the case... maybe a bug in m2amf ? - else - return 0; - */ - - } - /* invalid row (probably unexpected end of row) */ - if (row>=64) - return 0; - if (cmd<0x7f) { - /* note, vol */ - track[row].note=cmd; - track[row].volume=(UBYTE)arg+1; - } else - if (cmd==0x7f) { - /* duplicate row */ - if ((arg<0)&&(row+arg>=0)) { - memcpy(track+row,track+(row+arg),sizeof(AMFNOTE)); - } - } else - if (cmd==0x80) { - /* instr */ - track[row].instr=arg+1; - } else - if (cmd==0x83) { - /* volume without note */ - track[row].volume=(UBYTE)arg+1; - } else - if (cmd==0xff) { - /* apparently, some M2AMF version fail to estimate the - size of the compressed patterns correctly, and end - up with blanks, i.e. dead triplets. Those are marked - with cmd == 0xff. Let's ignore them. */ - } else - if(track[row].fxcnt<3) { - /* effect, param */ - if(cmd>0x97) - return 0; - track[row].effect[track[row].fxcnt]=cmd&0x7f; - track[row].parameter[track[row].fxcnt]=arg; - track[row].fxcnt++; - } else - return 0; - } - } - return 1; -} - -static UBYTE* AMF_ConvertTrack(void) -{ - int row,fx4memory=0; - - /* convert track */ - UniReset(); - for (row=0;row<64;row++) { - if (track[row].instr) UniInstrument(track[row].instr-1); - if (track[row].note>OCTAVE) UniNote(track[row].note-OCTAVE); - - /* AMF effects */ - while(track[row].fxcnt--) { - SBYTE inf=track[row].parameter[track[row].fxcnt]; - - switch(track[row].effect[track[row].fxcnt]) { - case 1: /* Set speed */ - UniEffect(UNI_S3MEFFECTA,inf); - break; - case 2: /* Volume slide */ - if(inf) { - UniWriteByte(UNI_S3MEFFECTD); - if (inf>=0) - UniWriteByte((inf&0xf)<<4); - else - UniWriteByte((-inf)&0xf); - } - break; - /* effect 3, set channel volume, done in UnpackTrack */ - case 4: /* Porta up/down */ - if(inf) { - if(inf>0) { - UniEffect(UNI_S3MEFFECTE,inf); - fx4memory=UNI_S3MEFFECTE; - } else { - UniEffect(UNI_S3MEFFECTF,-inf); - fx4memory=UNI_S3MEFFECTF; - } - } else if(fx4memory) - UniEffect(fx4memory,0); - break; - /* effect 5, "Porta abs", not supported */ - case 6: /* Porta to note */ - UniEffect(UNI_ITEFFECTG,inf); - break; - case 7: /* Tremor */ - UniEffect(UNI_S3MEFFECTI,inf); - break; - case 8: /* Arpeggio */ - UniPTEffect(0x0,inf); - break; - case 9: /* Vibrato */ - UniPTEffect(0x4,inf); - break; - case 0xa: /* Porta + Volume slide */ - UniPTEffect(0x3,0); - if(inf) { - UniWriteByte(UNI_S3MEFFECTD); - if (inf>=0) - UniWriteByte((inf&0xf)<<4); - else - UniWriteByte((-inf)&0xf); - } - break; - case 0xb: /* Vibrato + Volume slide */ - UniPTEffect(0x4,0); - if(inf) { - UniWriteByte(UNI_S3MEFFECTD); - if (inf>=0) - UniWriteByte((inf&0xf)<<4); - else - UniWriteByte((-inf)&0xf); - } - break; - case 0xc: /* Pattern break (in hex) */ - UniPTEffect(0xd,inf); - break; - case 0xd: /* Pattern jump */ - UniPTEffect(0xb,inf); - break; - /* effect 0xe, "Sync", not supported */ - case 0xf: /* Retrig */ - UniEffect(UNI_S3MEFFECTQ,inf&0xf); - break; - case 0x10: /* Sample offset */ - UniPTEffect(0x9,inf); - break; - case 0x11: /* Fine volume slide */ - if(inf) { - UniWriteByte(UNI_S3MEFFECTD); - if (inf>=0) - UniWriteByte((inf&0xf)<<4|0xf); - else - UniWriteByte(0xf0|((-inf)&0xf)); - } - break; - case 0x12: /* Fine portamento */ - if(inf) { - if(inf>0) { - UniEffect(UNI_S3MEFFECTE,0xf0|(inf&0xf)); - fx4memory=UNI_S3MEFFECTE; - } else { - UniEffect(UNI_S3MEFFECTF,0xf0|((-inf)&0xf)); - fx4memory=UNI_S3MEFFECTF; - } - } else if(fx4memory) - UniEffect(fx4memory,0); - break; - case 0x13: /* Delay note */ - UniPTEffect(0xe,0xd0|(inf&0xf)); - break; - case 0x14: /* Note cut */ - UniPTEffect(0xc,0); - track[row].volume=0; - break; - case 0x15: /* Set tempo */ - UniEffect(UNI_S3MEFFECTT,inf); - break; - case 0x16: /* Extra fine portamento */ - if(inf) { - if(inf>0) { - UniEffect(UNI_S3MEFFECTE,0xe0|((inf>>2)&0xf)); - fx4memory=UNI_S3MEFFECTE; - } else { - UniEffect(UNI_S3MEFFECTF,0xe0|(((-inf)>>2)&0xf)); - fx4memory=UNI_S3MEFFECTF; - } - } else if(fx4memory) - UniEffect(fx4memory,0); - break; - case 0x17: /* Panning */ - if (inf>64) - UniEffect(UNI_ITEFFECTS0,0x91); /* surround */ - else - UniPTEffect(0x8,(inf==64)?255:(inf+64)<<1); - of.flags |= UF_PANNING; - break; - } - - } - if (track[row].volume) UniVolEffect(VOL_VOLUME,track[row].volume-1); - UniNewline(); - } - return UniDup(); -} - -BOOL AMF_Load(BOOL curious) -{ - int t,u,realtrackcnt,realsmpcnt,defaultpanning; - AMFSAMPLE s; - SAMPLE *q; - UWORD *track_remap; - ULONG samplepos; - int channel_remap[16]; - - /* try to read module header */ - _mm_read_UBYTES(mh->id,3,modreader); - mh->version =_mm_read_UBYTE(modreader); - _mm_read_string(mh->songname,32,modreader); - mh->numsamples =_mm_read_UBYTE(modreader); - mh->numorders =_mm_read_UBYTE(modreader); - mh->numtracks =_mm_read_I_UWORD(modreader); - mh->numchannels =_mm_read_UBYTE(modreader); - if((!mh->numchannels)||(mh->numchannels>(mh->version>=12?32:16))) { - _mm_errno=MMERR_NOT_A_MODULE; - return 0; - } - - if(mh->version>=11) { - memset(mh->panpos,0,32); - _mm_read_SBYTES(mh->panpos,(mh->version>=13)?32:16,modreader); - } else - _mm_read_UBYTES(channel_remap,16,modreader); - - if (mh->version>=13) { - mh->songbpm=_mm_read_UBYTE(modreader); - if(mh->songbpm<32) { - _mm_errno=MMERR_NOT_A_MODULE; - return 0; - } - mh->songspd=_mm_read_UBYTE(modreader); - if(mh->songspd>32) { - _mm_errno=MMERR_NOT_A_MODULE; - return 0; - } - } else { - mh->songbpm=125; - mh->songspd=6; - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - of.initspeed = mh->songspd; - of.inittempo = mh->songbpm; - AMF_Version[AMFTEXTLEN-3]='0'+(mh->version/10); - AMF_Version[AMFTEXTLEN-1]='0'+(mh->version%10); - of.modtype = strdup(AMF_Version); - of.numchn = mh->numchannels; - of.numtrk = mh->numorders*mh->numchannels; - if (mh->numtracks>of.numtrk) - of.numtrk=mh->numtracks; - of.numtrk++; /* add room for extra, empty track */ - of.songname = DupStr(mh->songname,32,1); - of.numpos = mh->numorders; - of.numpat = mh->numorders; - of.reppos = 0; - of.flags |= UF_S3MSLIDES; - /* XXX whenever possible, we should try to determine the original format. - Here we assume it was S3M-style wrt bpmlimit... */ - of.bpmlimit = 32; - - /* - * Play with the panning table. Although the AMF format embeds a - * panning table, if the module was a MOD or an S3M with default - * panning and didn't use any panning commands, don't flag - * UF_PANNING, to use our preferred panning table for this case. - */ - defaultpanning = 1; - for (t = 0; t < 32; t++) { - if (mh->panpos[t] > 64) { - of.panning[t] = PAN_SURROUND; - defaultpanning = 0; - } else - if (mh->panpos[t] == 64) - of.panning[t] = PAN_RIGHT; - else - of.panning[t] = (mh->panpos[t] + 64) << 1; - } - if (defaultpanning) { - for (t = 0; t < of.numchn; t++) - if (of.panning[t] == (((t + 1) & 2) ? PAN_RIGHT : PAN_LEFT)) { - defaultpanning = 0; /* not MOD canonical panning */ - break; - } - } - if (defaultpanning) - of.flags |= UF_PANNING; - - of.numins=of.numsmp=mh->numsamples; - - if(!AllocPositions(of.numpos)) return 0; - for(t=0;tversion>=14) - /* track size */ - of.pattrows[t]=_mm_read_I_UWORD(modreader); - if (mh->version>=10) - _mm_read_I_UWORDS(of.patterns+(t*of.numchn),of.numchn,modreader); - else - for(u=0;uversion>=11) { - s.reppos =_mm_read_I_ULONG(modreader); - s.repend =_mm_read_I_ULONG(modreader); - } else { - s.reppos =_mm_read_I_UWORD(modreader); - s.repend =s.length; - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - q->samplename = DupStr(s.samplename,32,1); - q->speed = s.c2spd; - q->volume = s.volume; - if (s.type) { - q->seekpos = s.offset; - q->length = s.length; - q->loopstart = s.reppos; - q->loopend = s.repend; - if((s.repend-s.reppos)>2) q->flags |= SF_LOOP; - } - q++; - } - - /* read track table */ - if(!(track_remap=_mm_calloc(mh->numtracks+1,sizeof(UWORD)))) - return 0; - _mm_read_I_UWORDS(track_remap+1,mh->numtracks,modreader); - if(_mm_eof(modreader)) { - free(track_remap); - _mm_errno=MMERR_LOADING_TRACK; - return 0; - } - - for(realtrackcnt=t=0;t<=mh->numtracks;t++) - if (realtrackcntnumtracks)? - track_remap[of.patterns[t]]-1:realtrackcnt; - - free(track_remap); - - /* unpack tracks */ - for(t=0;tseekpos!=t) q++; - q->seekpos=samplepos; - samplepos+=q->length; - } - - return 1; -} - -CHAR *AMF_LoadTitle(void) -{ - CHAR s[32]; - - _mm_fseek(modreader,4,SEEK_SET); - if(!_mm_read_UBYTES(s,32,modreader)) return NULL; - - return(DupStr(s,32,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_amf={ - NULL, - "AMF", - "AMF (DSMI Advanced Module Format)", - AMF_Init, - AMF_Test, - AMF_Load, - AMF_Cleanup, - AMF_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_dsm.c b/mikmod/load_dsm.c deleted file mode 100644 index 8878c795..00000000 --- a/mikmod/load_dsm.c +++ /dev/null @@ -1,364 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_dsm.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - DSIK internal format (DSM) module loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -#define DSM_MAXCHAN (16) -#define DSM_MAXORDERS (128) - -typedef struct DSMSONG { - CHAR songname[28]; - UWORD version; - UWORD flags; - ULONG reserved2; - UWORD numord; - UWORD numsmp; - UWORD numpat; - UWORD numtrk; - UBYTE globalvol; - UBYTE mastervol; - UBYTE speed; - UBYTE bpm; - UBYTE panpos[DSM_MAXCHAN]; - UBYTE orders[DSM_MAXORDERS]; -} DSMSONG; - -typedef struct DSMINST { - CHAR filename[13]; - UWORD flags; - UBYTE volume; - ULONG length; - ULONG loopstart; - ULONG loopend; - ULONG reserved1; - UWORD c2spd; - UWORD period; - CHAR samplename[28]; -} DSMINST; - -typedef struct DSMNOTE { - UBYTE note,ins,vol,cmd,inf; -} DSMNOTE; - -#define DSM_SURROUND (0xa4) - -/*========== Loader variables */ - -static CHAR* SONGID="SONG"; -static CHAR* INSTID="INST"; -static CHAR* PATTID="PATT"; - -static UBYTE blockid[4]; -static ULONG blockln; -static ULONG blocklp; -static DSMSONG* mh=NULL; -static DSMNOTE* dsmbuf=NULL; - -static CHAR DSM_Version[]="DSIK DSM-format"; - -static unsigned char DSMSIG[4+4]={'R','I','F','F','D','S','M','F'}; - -/*========== Loader code */ - -BOOL DSM_Test(void) -{ - UBYTE id[12]; - - if(!_mm_read_UBYTES(id,12,modreader)) return 0; - if(!memcmp(id,DSMSIG,4) && !memcmp(id+8,DSMSIG+4,4)) return 1; - - return 0; -} - -BOOL DSM_Init(void) -{ - if(!(dsmbuf=(DSMNOTE *)_mm_malloc(DSM_MAXCHAN*64*sizeof(DSMNOTE)))) return 0; - if(!(mh=(DSMSONG *)_mm_calloc(1,sizeof(DSMSONG)))) return 0; - return 1; -} - -void DSM_Cleanup(void) -{ - _mm_free(dsmbuf); - _mm_free(mh); -} - -static BOOL GetBlockHeader(void) -{ - /* make sure we're at the right position for reading the - next riff block, no matter how many bytes read */ - _mm_fseek(modreader, blocklp+blockln, SEEK_SET); - - while(1) { - _mm_read_UBYTES(blockid,4,modreader); - blockln=_mm_read_I_ULONG(modreader); - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - if(memcmp(blockid,SONGID,4) && memcmp(blockid,INSTID,4) && - memcmp(blockid,PATTID,4)) { -#ifdef MIKMOD_DEBUG - fprintf(stderr,"\rDSM: Skipping unknown block type %4.4s\n",blockid); -#endif - _mm_fseek(modreader, blockln, SEEK_CUR); - } else - break; - } - - blocklp = _mm_ftell(modreader); - - return 1; -} - -static BOOL DSM_ReadPattern(void) -{ - int flag,row=0; - SWORD length; - DSMNOTE *n; - - /* clear pattern data */ - memset(dsmbuf,255,DSM_MAXCHAN*64*sizeof(DSMNOTE)); - length=_mm_read_I_SWORD(modreader); - - while(row<64) { - flag=_mm_read_UBYTE(modreader); - if((_mm_eof(modreader))||(--length<0)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - - if(flag) { - n=&dsmbuf[((flag&0xf)*64)+row]; - if(flag&0x80) n->note=_mm_read_UBYTE(modreader); - if(flag&0x40) n->ins=_mm_read_UBYTE(modreader); - if(flag&0x20) n->vol=_mm_read_UBYTE(modreader); - if(flag&0x10) { - n->cmd=_mm_read_UBYTE(modreader); - n->inf=_mm_read_UBYTE(modreader); - } - } else - row++; - } - - return 1; -} - -static UBYTE *DSM_ConvertTrack(DSMNOTE *tr) -{ - int t; - UBYTE note,ins,vol,cmd,inf; - - UniReset(); - for(t=0;t<64;t++) { - note=tr[t].note; - ins=tr[t].ins; - vol=tr[t].vol; - cmd=tr[t].cmd; - inf=tr[t].inf; - - if(ins!=0 && ins!=255) UniInstrument(ins-1); - if(note!=255) UniNote(note-1); /* normal note */ - if(vol<65) UniPTEffect(0xc,vol); - - if(cmd!=255) { - if(cmd==0x8) { - if(inf==DSM_SURROUND) - UniEffect(UNI_ITEFFECTS0,0x91); - else - if(inf<=0x80) { - inf=(inf<0x80)?inf<<1:255; - UniPTEffect(cmd,inf); - } - } else - if(cmd==0xb) { - if(inf<=0x7f) UniPTEffect(cmd,inf); - } else { - /* Convert pattern jump from Dec to Hex */ - if(cmd == 0xd) - inf = (((inf&0xf0)>>4)*10)+(inf&0xf); - UniPTEffect(cmd,inf); - } - } - UniNewline(); - } - return UniDup(); -} - -BOOL DSM_Load(BOOL curious) -{ - int t; - DSMINST s; - SAMPLE *q; - int cursmp=0,curpat=0,track=0; - - blocklp=0; - blockln=12; - - if(!GetBlockHeader()) return 0; - if(memcmp(blockid,SONGID,4)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - _mm_read_UBYTES(mh->songname,28,modreader); - mh->version=_mm_read_I_UWORD(modreader); - mh->flags=_mm_read_I_UWORD(modreader); - mh->reserved2=_mm_read_I_ULONG(modreader); - mh->numord=_mm_read_I_UWORD(modreader); - mh->numsmp=_mm_read_I_UWORD(modreader); - mh->numpat=_mm_read_I_UWORD(modreader); - mh->numtrk=_mm_read_I_UWORD(modreader); - mh->globalvol=_mm_read_UBYTE(modreader); - mh->mastervol=_mm_read_UBYTE(modreader); - mh->speed=_mm_read_UBYTE(modreader); - mh->bpm=_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->panpos,DSM_MAXCHAN,modreader); - _mm_read_UBYTES(mh->orders,DSM_MAXORDERS,modreader); - - /* set module variables */ - of.initspeed=mh->speed; - of.inittempo=mh->bpm; - of.modtype=strdup(DSM_Version); - of.numchn=mh->numtrk; - of.numpat=mh->numpat; - of.numtrk=of.numchn*of.numpat; - of.songname=DupStr(mh->songname,28,1); /* make a cstr of songname */ - of.reppos=0; - of.flags |= UF_PANNING; - /* XXX whenever possible, we should try to determine the original format. - Here we assume it was S3M-style wrt bpmlimit... */ - of.bpmlimit = 32; - - for(t=0;tpanpos[t]==DSM_SURROUND?PAN_SURROUND: - mh->panpos[t]<0x80?(mh->panpos[t]<<1):255; - - if(!AllocPositions(mh->numord)) return 0; - of.numpos=0; - for(t=0;tnumord;t++) { - int order=mh->orders[t]; - if(order==255) order=LAST_PATTERN; - of.positions[of.numpos]=order; - if(mh->orders[t]<254) of.numpos++; - } - - of.numins=of.numsmp=mh->numsmp; - - if(!AllocSamples()) return 0; - if(!AllocTracks()) return 0; - if(!AllocPatterns()) return 0; - - while(cursmpsamplename=DupStr(s.samplename,28,1); - q->seekpos=_mm_ftell(modreader); - q->speed=s.c2spd; - q->length=s.length; - q->loopstart=s.loopstart; - q->loopend=s.loopend; - q->volume=s.volume; - - if(s.flags&1) q->flags|=SF_LOOP; - if(s.flags&2) q->flags|=SF_SIGNED; - /* (s.flags&4) means packed sample, - but did they really exist in dsm ?*/ - cursmp++; - } else - if(!memcmp(blockid,PATTID,4) && curpat -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -typedef struct FARHEADER1 { - UBYTE id[4]; /* file magic */ - CHAR songname[40]; /* songname */ - CHAR blah[3]; /* 13,10,26 */ - UWORD headerlen; /* remaining length of header in bytes */ - UBYTE version; - UBYTE onoff[16]; - UBYTE edit1[9]; - UBYTE speed; - UBYTE panning[16]; - UBYTE edit2[4]; - UWORD stlen; -} FARHEADER1; - -typedef struct FARHEADER2 { - UBYTE orders[256]; - UBYTE numpat; - UBYTE snglen; - UBYTE loopto; - UWORD patsiz[256]; -} FARHEADER2; - -typedef struct FARSAMPLE { - CHAR samplename[32]; - ULONG length; - UBYTE finetune; - UBYTE volume; - ULONG reppos; - ULONG repend; - UBYTE type; - UBYTE loop; -} FARSAMPLE; - -typedef struct FARNOTE { - UBYTE note,ins,vol,eff; -} FARNOTE; - -/*========== Loader variables */ - -static CHAR FAR_Version[] = "Farandole"; -static FARHEADER1 *mh1 = NULL; -static FARHEADER2 *mh2 = NULL; -static FARNOTE *pat = NULL; - -static unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26}; - -/*========== Loader code */ - -BOOL FAR_Test(void) -{ - UBYTE id[47]; - - if(!_mm_read_UBYTES(id,47,modreader)) return 0; - if((memcmp(id,FARSIG,4))||(memcmp(id+44,FARSIG+4,3))) return 0; - return 1; -} - -BOOL FAR_Init(void) -{ - if(!(mh1 = (FARHEADER1*)_mm_malloc(sizeof(FARHEADER1)))) return 0; - if(!(mh2 = (FARHEADER2*)_mm_malloc(sizeof(FARHEADER2)))) return 0; - if(!(pat = (FARNOTE*)_mm_malloc(256*16*4*sizeof(FARNOTE)))) return 0; - - return 1; -} - -void FAR_Cleanup(void) -{ - _mm_free(mh1); - _mm_free(mh2); - _mm_free(pat); -} - -static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows) -{ - int t,vibdepth=1; - - UniReset(); - for(t=0;tnote) { - UniInstrument(n->ins); - UniNote(n->note+3*OCTAVE-1); - } - if (n->vol&0xf) UniPTEffect(0xc,(n->vol&0xf)<<2); - if (n->eff) - switch(n->eff>>4) { - case 0x3: /* porta to note */ - UniPTEffect(0x3,(n->eff&0xf)<<4); - break; - case 0x4: /* retrigger */ - UniPTEffect(0x0e, 0x90 | (n->eff & 0x0f)); - break; - case 0x5: /* set vibrato depth */ - vibdepth=n->eff&0xf; - break; - case 0x6: /* vibrato */ - UniPTEffect(0x4,((n->eff&0xf)<<4)|vibdepth); - break; - case 0x7: /* volume slide up */ - UniPTEffect(0xa,(n->eff&0xf)<<4); - break; - case 0x8: /* volume slide down */ - UniPTEffect(0xa,n->eff&0xf); - break; - case 0xb: /* panning */ - UniPTEffect(0xe,0x80|(n->eff&0xf)); - break; - case 0xf: /* set speed */ - UniPTEffect(0xf,n->eff&0xf); - break; - - /* others not yet implemented */ - default: -#ifdef MIKMOD_DEBUG - fprintf(stderr,"\rFAR: unsupported effect %02X\n",n->eff); -#endif - break; - } - - UniNewline(); - n+=16; - } - return UniDup(); -} - -BOOL FAR_Load(BOOL curious) -{ - int t,u,tracks=0; - SAMPLE *q; - FARSAMPLE s; - FARNOTE *crow; - UBYTE smap[8]; - - /* try to read module header (first part) */ - _mm_read_UBYTES(mh1->id,4,modreader); - _mm_read_SBYTES(mh1->songname,40,modreader); - _mm_read_SBYTES(mh1->blah,3,modreader); - mh1->headerlen = _mm_read_I_UWORD (modreader); - mh1->version = _mm_read_UBYTE (modreader); - _mm_read_UBYTES(mh1->onoff,16,modreader); - _mm_read_UBYTES(mh1->edit1,9,modreader); - mh1->speed = _mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh1->panning,16,modreader); - _mm_read_UBYTES(mh1->edit2,4,modreader); - mh1->stlen = _mm_read_I_UWORD (modreader); - - /* init modfile data */ - of.modtype = strdup(FAR_Version); - of.songname = DupStr(mh1->songname,40,1); - of.numchn = 16; - of.initspeed = mh1->speed; - of.inittempo = 80; - of.reppos = 0; - of.flags |= UF_PANNING; - for(t=0;t<16;t++) of.panning[t]=mh1->panning[t]<<4; - - /* read songtext into comment field */ - if(mh1->stlen) - if (!ReadLinedComment(mh1->stlen, 66)) return 0; - - /* try to read module header (second part) */ - _mm_read_UBYTES(mh2->orders,256,modreader); - mh2->numpat = _mm_read_UBYTE(modreader); - mh2->snglen = _mm_read_UBYTE(modreader); - mh2->loopto = _mm_read_UBYTE(modreader); - _mm_read_I_UWORDS(mh2->patsiz,256,modreader); - - of.numpos = mh2->snglen; - if(!AllocPositions(of.numpos)) return 0; - for(t=0;torders[t]==0xff) break; - of.positions[t] = mh2->orders[t]; - } - - /* count number of patterns stored in file */ - of.numpat = 0; - for(t=0;t<256;t++) - if(mh2->patsiz[t]) - if((t+1)>of.numpat) of.numpat=t+1; - of.numtrk = of.numpat*of.numchn; - - /* seek across eventual new data */ - _mm_fseek(modreader,mh1->headerlen-(869+mh1->stlen),SEEK_CUR); - - /* alloc track and pattern structures */ - if(!AllocTracks()) return 0; - if(!AllocPatterns()) return 0; - - for(t=0;tpatsiz[t]) { - rows = _mm_read_UBYTE(modreader); - tempo = _mm_read_UBYTE(modreader); - - crow = pat; - /* file often allocates 64 rows even if there are less in pattern */ - if (mh2->patsiz[t]<2+(rows*16*4)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - for(u=(mh2->patsiz[t]-2)/4;u;u--,crow++) { - crow->note = _mm_read_UBYTE(modreader); - crow->ins = _mm_read_UBYTE(modreader); - crow->vol = _mm_read_UBYTE(modreader); - crow->eff = _mm_read_UBYTE(modreader); - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - - crow=pat; - of.pattrows[t] = rows; - for(u=16;u;u--,crow++) - if(!(of.tracks[tracks++]=FAR_ConvertTrack(crow,rows))) { - _mm_errno=MMERR_LOADING_PATTERN; - return 0; - } - } else - tracks+=16; - } - - /* read sample map */ - if(!_mm_read_UBYTES(smap,8,modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* count number of samples used */ - of.numins = 0; - for(t=0;t<64;t++) - if(smap[t>>3]&(1<<(t&7))) of.numins=t+1; - of.numsmp = of.numins; - - /* alloc sample structs */ - if(!AllocSamples()) return 0; - - q = of.samples; - for(t=0;tspeed = 8363; - q->flags = SF_SIGNED; - if(smap[t>>3]&(1<<(t&7))) { - _mm_read_SBYTES(s.samplename,32,modreader); - s.length = _mm_read_I_ULONG(modreader); - s.finetune = _mm_read_UBYTE(modreader); - s.volume = _mm_read_UBYTE(modreader); - s.reppos = _mm_read_I_ULONG(modreader); - s.repend = _mm_read_I_ULONG(modreader); - s.type = _mm_read_UBYTE(modreader); - s.loop = _mm_read_UBYTE(modreader); - - q->samplename = DupStr(s.samplename,32,1); - q->length = s.length; - q->loopstart = s.reppos; - q->loopend = s.repend; - q->volume = s.volume<<2; - - if(s.type&1) q->flags|=SF_16BITS; - if(s.loop&8) q->flags|=SF_LOOP; - - q->seekpos = _mm_ftell(modreader); - _mm_fseek(modreader,q->length,SEEK_CUR); - } else - q->samplename = DupStr(NULL,0,0); - q++; - } - return 1; -} - -CHAR *FAR_LoadTitle(void) -{ - CHAR s[40]; - - _mm_fseek(modreader,4,SEEK_SET); - if(!_mm_read_UBYTES(s,40,modreader)) return NULL; - - return(DupStr(s,40,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_far={ - NULL, - "FAR", - "FAR (Farandole Composer)", - FAR_Init, - FAR_Test, - FAR_Load, - FAR_Cleanup, - FAR_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_gdm.c b/mikmod/load_gdm.c deleted file mode 100644 index c2f861b8..00000000 --- a/mikmod/load_gdm.c +++ /dev/null @@ -1,558 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software;you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation;either version 2 of - the License,or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY;without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library;if not,write to the Free Software - Foundation,Inc.,59 Temple Place - Suite 330,Boston,MA - 02111-1307,USA. -*/ - -/*============================================================================== - - $Id: load_gdm.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - General DigiMusic (GDM) module loader - -==============================================================================*/ - -/* - - Written by Kev Vance - based on the file format description written by 'MenTaLguY' - - -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -typedef struct GDMNOTE { - UBYTE note; - UBYTE samp; - struct { - UBYTE effect; - UBYTE param; - } effect[4]; -} GDMNOTE; - -typedef GDMNOTE GDMTRACK[64]; - -typedef struct GDMHEADER { - CHAR id1[4]; - CHAR songname[32]; - CHAR author[32]; - CHAR eofmarker[3]; - CHAR id2[4]; - - UBYTE majorver; - UBYTE minorver; - UWORD trackerid; - UBYTE t_majorver; - UBYTE t_minorver; - UBYTE pantable[32]; - UBYTE mastervol; - UBYTE mastertempo; - UBYTE masterbpm; - UWORD flags; - - ULONG orderloc; - UBYTE ordernum; - ULONG patternloc; - UBYTE patternnum; - ULONG samhead; - ULONG samdata; - UBYTE samnum; - ULONG messageloc; - ULONG messagelen; - ULONG scrollyloc; - UWORD scrollylen; - ULONG graphicloc; - UWORD graphiclen; -} GDMHEADER; - -typedef struct GDMSAMPLE { - CHAR sampname[32]; - CHAR filename[13]; - UBYTE ems; - ULONG length; - ULONG loopbeg; - ULONG loopend; - UBYTE flags; - UWORD c4spd; - UBYTE vol; - UBYTE pan; -} GDMSAMPLE; - -static GDMHEADER *mh=NULL; /* pointer to GDM header */ -static GDMNOTE *gdmbuf=NULL; /* pointer to a complete GDM pattern */ - -CHAR GDM_Version[]="General DigiMusic 1.xx"; - -BOOL GDM_Test(void) -{ - /* test for gdm magic numbers */ - UBYTE id[4]; - - _mm_fseek(modreader,0x00,SEEK_SET); - if (!_mm_read_UBYTES(id,4,modreader)) - return 0; - if (!memcmp(id,"GDM\xfe",4)) { - _mm_fseek(modreader,71,SEEK_SET); - if (!_mm_read_UBYTES(id,4,modreader)) - return 0; - if (!memcmp(id,"GMFS",4)) - return 1; - } - return 0; -} - -BOOL GDM_Init(void) -{ - if (!(gdmbuf=(GDMNOTE*)_mm_malloc(32*64*sizeof(GDMNOTE)))) return 0; - if (!(mh=(GDMHEADER*)_mm_malloc(sizeof(GDMHEADER)))) return 0; - - return 1; -} - -void GDM_Cleanup(void) -{ - _mm_free(mh); - _mm_free(gdmbuf); -} - -BOOL GDM_ReadPattern(void) -{ - int pos,flag,ch,i,maxch; - GDMNOTE n; - UWORD length,x=0; - - /* get pattern length */ - length=_mm_read_I_UWORD(modreader)-2; - - /* clear pattern data */ - memset(gdmbuf,255,32*64*sizeof(GDMNOTE)); - pos=0; - maxch=0; - - while (xmaxch) maxch=ch; - if (!flag) { - pos++; - continue; - } - if (flag&0x60) { - if (flag&0x20) { - /* new note */ - n.note=_mm_read_UBYTE(modreader)&127; - n.samp=_mm_read_UBYTE(modreader); - x +=2; - } - if (flag&0x40) { - do { - /* effect channel set */ - i=_mm_read_UBYTE(modreader); - n.effect[i>>6].effect=i&31; - n.effect[i>>6].param=_mm_read_UBYTE(modreader); - x +=2; - } while (i&32); - } - memcpy(gdmbuf+(64U*ch)+pos,&n,sizeof(GDMNOTE)); - } - } - return 1; -} - -UBYTE *GDM_ConvertTrack(GDMNOTE*tr) -{ - int t,i=0; - UBYTE note,ins,inf; - - UniReset(); - for (t=0;t<64;t++) { - note=tr[t].note; - ins=tr[t].samp; - - if ((ins)&&(ins!=255)) - UniInstrument(ins-1); - if (note!=255) { - UniNote(((note>>4)*OCTAVE)+(note&0xf)-1); - } - for (i=0;i<4;i++) { - inf = tr[t].effect[i].param; - switch (tr[t].effect[i].effect) { - case 1: /* toneslide up */ - UniEffect(UNI_S3MEFFECTF,inf); - break; - case 2: /* toneslide down */ - UniEffect(UNI_S3MEFFECTE,inf); - break; - case 3: /* glissando to note */ - UniEffect(UNI_ITEFFECTG,inf); - break; - case 4: /* vibrato */ - UniEffect(UNI_ITEFFECTH,inf); - break; - case 5: /* portamento+volslide */ - UniEffect(UNI_ITEFFECTG,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 6: /* vibrato+volslide */ - UniEffect(UNI_ITEFFECTH,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 7: /* tremolo */ - UniEffect(UNI_S3MEFFECTR,inf); - break; - case 8: /* tremor */ - UniEffect(UNI_S3MEFFECTI,inf); - break; - case 9: /* offset */ - UniPTEffect(0x09,inf); - break; - case 0x0a: /* volslide */ - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 0x0b: /* jump to order */ - UniPTEffect(0x0b,inf); - break; - case 0x0c: /* volume set */ - UniPTEffect(0x0c,inf); - break; - case 0x0d: /* pattern break */ - UniPTEffect(0x0d,inf); - break; - case 0x0e: /* extended */ - switch (inf&0xf0) { - case 0x10: /* fine portamento up */ - UniEffect(UNI_S3MEFFECTF, 0x0f|((inf<<4)&0x0f)); - break; - case 0x20: /* fine portamento down */ - UniEffect(UNI_S3MEFFECTE, 0xf0|(inf&0x0f)); - break; - case 0x30: /* glissando control */ - UniEffect(SS_GLISSANDO, inf&0x0f); - break; - case 0x40: /* vibrato waveform */ - UniEffect(SS_VIBWAVE, inf&0x0f); - break; - case 0x50: /* set c4spd */ - UniEffect(SS_FINETUNE, inf&0x0f); - break; - case 0x60: /* loop fun */ - UniEffect(UNI_ITEFFECTS0, (inf&0x0f)|0xb0); - break; - case 0x70: /* tremolo waveform */ - UniEffect(SS_TREMWAVE, inf&0x0f); - break; - case 0x80: /* extra fine porta up */ - UniEffect(UNI_S3MEFFECTF, 0x0e|((inf<<4)&0x0f)); - break; - case 0x90: /* extra fine porta down */ - UniEffect(UNI_S3MEFFECTE, 0xe0|(inf&0x0f)); - break; - case 0xa0: /* fine volslide up */ - UniEffect(UNI_S3MEFFECTD, 0x0f|((inf<<4)&0x0f)); - break; - case 0xb0: /* fine volslide down */ - UniEffect(UNI_S3MEFFECTE, 0xf0|(inf&0x0f)); - break; - case 0xc0: /* note cut */ - case 0xd0: /* note delay */ - case 0xe0: /* extend row */ - UniPTEffect(0xe,inf); - break; - } - break; - case 0x0f: /* set tempo */ - UniEffect(UNI_S3MEFFECTA,inf); - break; - case 0x10: /* arpeggio */ - UniPTEffect(0x0,inf); - break; - case 0x12: /* retrigger */ - UniEffect(UNI_S3MEFFECTQ,inf); - break; - case 0x13: /* set global volume */ - UniEffect(UNI_XMEFFECTG,inf<<1); - break; - case 0x14: /* fine vibrato */ - UniEffect(UNI_ITEFFECTU,inf); - break; - case 0x1e: /* special */ - switch (inf&0xf0) { - case 8: /* set pan position */ - if (inf >=128) - UniPTEffect(0x08,255); - else - UniPTEffect(0x08,inf<<1); - break; - } - break; - case 0x1f: /* set bpm */ - if (inf >=0x20) - UniEffect(UNI_S3MEFFECTT,inf); - break; - } - } - UniNewline(); - } - return UniDup(); -} - -BOOL GDM_Load(BOOL curious) -{ - int i,x,u,track; - SAMPLE *q; - GDMSAMPLE s; - ULONG position; - - /* read header */ - _mm_read_string(mh->id1,4,modreader); - _mm_read_string(mh->songname,32,modreader); - _mm_read_string(mh->author,32,modreader); - _mm_read_string(mh->eofmarker,3,modreader); - _mm_read_string(mh->id2,4,modreader); - - mh->majorver=_mm_read_UBYTE(modreader); - mh->minorver=_mm_read_UBYTE(modreader); - mh->trackerid=_mm_read_I_UWORD(modreader); - mh->t_majorver=_mm_read_UBYTE(modreader); - mh->t_minorver=_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->pantable,32,modreader); - mh->mastervol=_mm_read_UBYTE(modreader); - mh->mastertempo=_mm_read_UBYTE(modreader); - mh->masterbpm=_mm_read_UBYTE(modreader); - mh->flags=_mm_read_I_UWORD(modreader); - - mh->orderloc=_mm_read_I_ULONG(modreader); - mh->ordernum=_mm_read_UBYTE(modreader); - mh->patternloc=_mm_read_I_ULONG(modreader); - mh->patternnum=_mm_read_UBYTE(modreader); - mh->samhead=_mm_read_I_ULONG(modreader); - mh->samdata=_mm_read_I_ULONG(modreader); - mh->samnum=_mm_read_UBYTE(modreader); - mh->messageloc=_mm_read_I_ULONG(modreader); - mh->messagelen=_mm_read_I_ULONG(modreader); - mh->scrollyloc=_mm_read_I_ULONG(modreader); - mh->scrollylen=_mm_read_I_UWORD(modreader); - mh->graphicloc=_mm_read_I_ULONG(modreader); - mh->graphiclen=_mm_read_I_UWORD(modreader); - - /* have we ended abruptly? */ - if (_mm_eof(modreader)) { - _mm_errno=MMERR_LOADING_HEADER; - return 0; - } - - /* any orders? */ - if(mh->ordernum==255) { - _mm_errno=MMERR_LOADING_PATTERN; - return 0; - } - - /* now we fill */ - of.modtype=strdup(GDM_Version); - of.modtype[18]=mh->majorver+'0'; - of.modtype[20]=mh->minorver/10+'0'; - of.modtype[21]=mh->minorver%10+'0'; - of.songname=DupStr(mh->songname,32,0); - of.numpat=mh->patternnum+1; - of.reppos=0; - of.numins=of.numsmp=mh->samnum+1; - of.initspeed=mh->mastertempo; - of.inittempo=mh->masterbpm; - of.initvolume=mh->mastervol<<1; - of.flags|=UF_S3MSLIDES | UF_PANNING; - /* XXX whenever possible, we should try to determine the original format. - Here we assume it was S3M-style wrt bpmlimit... */ - of.bpmlimit = 32; - - /* read the order data */ - if (!AllocPositions(mh->ordernum+1)) { - _mm_errno=MMERR_OUT_OF_MEMORY; - return 0; - } - - _mm_fseek(modreader,mh->orderloc,SEEK_SET); - for (i=0;iordernum+1;i++) - of.positions[i]=_mm_read_UBYTE(modreader); - - of.numpos=0; - for (i=0;iordernum+1;i++) { - int order=of.positions[i]; - if(order==255) order=LAST_PATTERN; - of.positions[of.numpos]=order; - if (of.positions[i]<254) of.numpos++; - } - - /* have we ended abruptly yet? */ - if (_mm_eof(modreader)) { - _mm_errno=MMERR_LOADING_HEADER; - return 0; - } - - /* time to load the samples */ - if (!AllocSamples()) { - _mm_errno=MMERR_OUT_OF_MEMORY; - return 0; - } - - q=of.samples; - position=mh->samdata; - - /* seek to instrument position */ - _mm_fseek(modreader,mh->samhead,SEEK_SET); - - for (i=0;isamplename=DupStr(s.sampname,32,0); - q->speed=s.c4spd; - q->length=s.length; - q->loopstart=s.loopbeg; - q->loopend=s.loopend; - q->volume=s.vol; - q->panning=s.pan; - q->seekpos=position; - - position +=s.length; - - if (s.flags&1) - q->flags |=SF_LOOP; - if (s.flags&2) - q->flags |=SF_16BITS; - if (s.flags&16) - q->flags |=SF_STEREO; - q++; - } - - /* set the panning */ - for (i=x=0;i<32;i++) { - of.panning[i]=mh->pantable[i]; - if (!of.panning[i]) - of.panning[i]=PAN_LEFT; - else if (of.panning[i]==8) - of.panning[i]=PAN_CENTER; - else if (of.panning[i]==15) - of.panning[i]=PAN_RIGHT; - else if (of.panning[i]==16) - of.panning[i]=PAN_SURROUND; - else if (of.panning[i]==255) - of.panning[i]=128; - else - of.panning[i]<<=3; - if (mh->pantable[i]!=255) - x=i; - } - - of.numchn=x+1; - if (of.numchn<1) - of.numchn=1; /* for broken counts */ - - /* load the pattern info */ - of.numtrk=of.numpat*of.numchn; - - /* jump to patterns */ - _mm_fseek(modreader,mh->patternloc,SEEK_SET); - - if (!AllocTracks()) { - _mm_errno=MMERR_OUT_OF_MEMORY; - return 0; - } - - if (!AllocPatterns()) { - _mm_errno=MMERR_OUT_OF_MEMORY; - return 0; - } - - for (i=track=0;i -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -/* module header */ -typedef struct IMFHEADER { - CHAR songname[32]; - UWORD ordnum; - UWORD patnum; - UWORD insnum; - UWORD flags; - UBYTE initspeed; - UBYTE inittempo; - UBYTE mastervol; - UBYTE mastermult; - UBYTE orders[256]; -} IMFHEADER; - -/* channel settings */ -typedef struct IMFCHANNEL { - CHAR name[12]; - UBYTE chorus; - UBYTE reverb; - UBYTE pan; - UBYTE status; -} IMFCHANNEL; - -/* instrument header */ -#define IMFNOTECNT (10*OCTAVE) -#define IMFENVCNT (16*2) -typedef struct IMFINSTHEADER { - CHAR name[32]; - UBYTE what[IMFNOTECNT]; - UWORD volenv[IMFENVCNT]; - UWORD panenv[IMFENVCNT]; - UWORD pitenv[IMFENVCNT]; - UBYTE volpts; - UBYTE volsus; - UBYTE volbeg; - UBYTE volend; - UBYTE volflg; - UBYTE panpts; - UBYTE pansus; - UBYTE panbeg; - UBYTE panend; - UBYTE panflg; - UBYTE pitpts; - UBYTE pitsus; - UBYTE pitbeg; - UBYTE pitend; - UBYTE pitflg; - UWORD volfade; - UWORD numsmp; - ULONG signature; -} IMFINSTHEADER; - -/* sample header */ -typedef struct IMFWAVHEADER { - CHAR samplename[13]; - ULONG length; - ULONG loopstart; - ULONG loopend; - ULONG samplerate; - UBYTE volume; - UBYTE pan; - UBYTE flags; -} IMFWAVHEADER; - -typedef struct IMFNOTE { - UBYTE note,ins,eff1,dat1,eff2,dat2; -} IMFNOTE; - -/*========== Loader variables */ - -static CHAR IMF_Version[]="Imago Orpheus"; - -static IMFNOTE *imfpat=NULL; -static IMFHEADER *mh=NULL; - -/*========== Loader code */ - -BOOL IMF_Test(void) -{ - UBYTE id[4]; - - _mm_fseek(modreader,0x3c,SEEK_SET); - if(!_mm_read_UBYTES(id,4,modreader)) return 0; - if(!memcmp(id,"IM10",4)) return 1; - return 0; -} - -BOOL IMF_Init(void) -{ - if(!(imfpat=(IMFNOTE*)_mm_malloc(32*256*sizeof(IMFNOTE)))) return 0; - if(!(mh=(IMFHEADER*)_mm_malloc(sizeof(IMFHEADER)))) return 0; - - return 1; -} - -void IMF_Cleanup(void) -{ - FreeLinear(); - - _mm_free(imfpat); - _mm_free(mh); -} - -static BOOL IMF_ReadPattern(SLONG size,UWORD rows) -{ - int row=0,flag,ch; - IMFNOTE *n,dummy; - - /* clear pattern data */ - memset(imfpat,255,32*256*sizeof(IMFNOTE)); - - while((size>0)&&(rownote=_mm_read_UBYTE(modreader); - if(n->note>=0xa0) n->note=0xa0; /* note off */ - n->ins =_mm_read_UBYTE(modreader); - size-=2; - } - if(flag&64) { - size-=2; - n->eff2=_mm_read_UBYTE(modreader); - n->dat2=_mm_read_UBYTE(modreader); - } - if(flag&128) { - n->eff1=_mm_read_UBYTE(modreader); - n->dat1=_mm_read_UBYTE(modreader); - size-=2; - } - } else row++; - } - if((size)||(row!=rows)) { - _mm_errno=MMERR_LOADING_PATTERN; - return 0; - } - return 1; -} - -static void IMF_ProcessCmd(UBYTE eff,UBYTE inf) -{ - if((eff)&&(eff!=255)) - switch (eff) { - case 0x01: /* set tempo */ - UniEffect(UNI_S3MEFFECTA,inf); - break; - case 0x02: /* set BPM */ - if(inf>=0x20) UniEffect(UNI_S3MEFFECTT,inf); - break; - case 0x03: /* tone portamento */ - UniEffect(UNI_ITEFFECTG,inf); - break; - case 0x04: /* porta + volslide */ - UniEffect(UNI_ITEFFECTG,inf); - UniEffect(UNI_S3MEFFECTD,0); - break; - case 0x05: /* vibrato */ - UniEffect(UNI_XMEFFECT4,inf); - break; - case 0x06: /* vibrato + volslide */ - UniEffect(UNI_XMEFFECT6,inf); - break; - case 0x07: /* fine vibrato */ - UniEffect(UNI_ITEFFECTU,inf); - break; - case 0x08: /* tremolo */ - UniEffect(UNI_S3MEFFECTR,inf); - break; - case 0x09: /* arpeggio */ - UniPTEffect(0x0,inf); - break; - case 0x0a: /* panning */ - UniPTEffect(0x8,(inf>=128)?255:(inf<<1)); - break; - case 0x0b: /* pan slide */ - UniEffect(UNI_XMEFFECTP,inf); - break; - case 0x0c: /* set channel volume */ - if(inf<=64) UniPTEffect(0xc,inf); - break; - case 0x0d: /* volume slide */ - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 0x0e: /* fine volume slide */ - if(inf) { - if(inf>>4) - UniEffect(UNI_S3MEFFECTD,0x0f|inf); - else - UniEffect(UNI_S3MEFFECTD,0xf0|inf); - } else - UniEffect(UNI_S3MEFFECTD,0); - break; - case 0x0f: /* set finetune */ - UniPTEffect(0xe,0x50|(inf>>4)); - break; -#ifdef MIKMOD_DEBUG - case 0x10: /* note slide up */ - case 0x11: /* not slide down */ - fprintf(stderr,"\rIMF effect 0x10/0x11 (note slide)" - " not implemented (eff=%2X inf=%2X)\n",eff,inf); - break; -#endif - case 0x12: /* slide up */ - UniEffect(UNI_S3MEFFECTF,inf); - break; - case 0x13: /* slide down */ - UniEffect(UNI_S3MEFFECTE,inf); - break; - case 0x14: /* fine slide up */ - if (inf) { - if (inf<0x40) - UniEffect(UNI_S3MEFFECTF,0xe0|(inf>>2)); - else - UniEffect(UNI_S3MEFFECTF,0xf0|(inf>>4)); - } else - UniEffect(UNI_S3MEFFECTF,0); - break; - case 0x15: /* fine slide down */ - if (inf) { - if (inf<0x40) - UniEffect(UNI_S3MEFFECTE,0xe0|(inf>>2)); - else - UniEffect(UNI_S3MEFFECTE,0xf0|(inf>>4)); - } else - UniEffect(UNI_S3MEFFECTE,0); - break; - /* 0x16 set filter cutoff (awe32) */ - /* 0x17 filter side + resonance (awe32) */ - case 0x18: /* sample offset */ - UniPTEffect(0x9,inf); - break; -#ifdef MIKMOD_DEBUG - case 0x19: /* set fine sample offset */ - fprintf(stderr,"\rIMF effect 0x19 (fine sample offset)" - " not implemented (inf=%2X)\n",inf); - break; -#endif - case 0x1a: /* keyoff */ - UniWriteByte(UNI_KEYOFF); - break; - case 0x1b: /* retrig */ - UniEffect(UNI_S3MEFFECTQ,inf); - break; - case 0x1c: /* tremor */ - UniEffect(UNI_S3MEFFECTI,inf); - break; - case 0x1d: /* position jump */ - UniPTEffect(0xb,inf); - break; - case 0x1e: /* pattern break */ - UniPTEffect(0xd,(inf>>4)*10+(inf&0xf)); - break; - case 0x1f: /* set master volume */ - if(inf<=64) UniEffect(UNI_XMEFFECTG,inf<<1); - break; - case 0x20: /* master volume slide */ - UniEffect(UNI_XMEFFECTH,inf); - break; - case 0x21: /* extended effects */ - switch(inf>>4) { - case 0x1: /* set filter */ - case 0x5: /* vibrato waveform */ - case 0x8: /* tremolo waveform */ - UniPTEffect(0xe,inf-0x10); - break; - case 0xa: /* pattern loop */ - UniPTEffect(0xe,0x60|(inf&0xf)); - break; - case 0xb: /* pattern delay */ - UniPTEffect(0xe,0xe0|(inf&0xf)); - break; - case 0x3: /* glissando */ - case 0xc: /* note cut */ - case 0xd: /* note delay */ - case 0xf: /* invert loop */ - UniPTEffect(0xe,inf); - break; - case 0xe: /* ignore envelope */ - UniEffect(UNI_ITEFFECTS0, 0x77); /* vol */ - UniEffect(UNI_ITEFFECTS0, 0x79); /* pan */ - UniEffect(UNI_ITEFFECTS0, 0x7b); /* pit */ - break; - } - break; - /* 0x22 chorus (awe32) */ - /* 0x23 reverb (awe32) */ - } -} - -static UBYTE* IMF_ConvertTrack(IMFNOTE* tr,UWORD rows) -{ - int t; - UBYTE note,ins; - - UniReset(); - for(t=0;t>4)*OCTAVE)+(note&0xf)); - } - - IMF_ProcessCmd(tr[t].eff1,tr[t].dat1); - IMF_ProcessCmd(tr[t].eff2,tr[t].dat2); - UniNewline(); - } - return UniDup(); -} - -BOOL IMF_Load(BOOL curious) -{ -#define IMF_SMPINCR 64 - int t,u,track=0,oldnumsmp; - IMFCHANNEL channels[32]; - INSTRUMENT *d; - SAMPLE *q; - IMFWAVHEADER *wh=NULL,*s=NULL; - ULONG *nextwav=NULL; - UWORD wavcnt=0; - UBYTE id[4]; - - /* try to read the module header */ - _mm_read_string(mh->songname,32,modreader); - mh->ordnum=_mm_read_I_UWORD(modreader); - mh->patnum=_mm_read_I_UWORD(modreader); - mh->insnum=_mm_read_I_UWORD(modreader); - mh->flags =_mm_read_I_UWORD(modreader); - _mm_fseek(modreader,8,SEEK_CUR); - mh->initspeed =_mm_read_UBYTE(modreader); - mh->inittempo =_mm_read_UBYTE(modreader); - mh->mastervol =_mm_read_UBYTE(modreader); - mh->mastermult=_mm_read_UBYTE(modreader); - _mm_fseek(modreader,64,SEEK_SET); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - of.songname=DupStr(mh->songname,31,1); - of.modtype=strdup(IMF_Version); - of.numpat=mh->patnum; - of.numins=mh->insnum; - of.reppos=0; - of.initspeed=mh->initspeed; - of.inittempo=mh->inittempo; - of.initvolume=mh->mastervol<<1; - of.flags |= UF_INST | UF_ARPMEM | UF_PANNING; - if(mh->flags&1) of.flags |= UF_LINEAR; - of.bpmlimit=32; - - /* read channel information */ - of.numchn=0; - memset(remap,-1,32*sizeof(UBYTE)); - for(t=0;t<32;t++) { - _mm_read_string(channels[t].name,12,modreader); - channels[t].chorus=_mm_read_UBYTE(modreader); - channels[t].reverb=_mm_read_UBYTE(modreader); - channels[t].pan =_mm_read_UBYTE(modreader); - channels[t].status=_mm_read_UBYTE(modreader); - } - /* bug in Imago Orpheus ? If only channel 1 is enabled, in fact we have to - enable 16 channels */ - if(!channels[0].status) { - for(t=1;t<16;t++) if(channels[t].status!=1) break; - if(t==16) for(t=1;t<16;t++) channels[t].status=0; - } - for(t=0;t<32;t++) { - if(channels[t].status!=2) - remap[t]=of.numchn++; - else - remap[t]=-1; - } - for(t=0;t<32;t++) - if(remap[t]!=-1) { - of.panning[remap[t]]=channels[t].pan; - of.chanvol[remap[t]]=channels[t].status?0:64; - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* read order list */ - _mm_read_UBYTES(mh->orders,256,modreader); - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - of.numpos=0; - for(t=0;tordnum;t++) - if(mh->orders[t]!=0xff) of.numpos++; - if(!AllocPositions(of.numpos)) return 0; - for(t=u=0;tordnum;t++) - if(mh->orders[t]!=0xff) of.positions[u++]=mh->orders[t]; - - /* load pattern info */ - of.numtrk=of.numpat*of.numchn; - if(!AllocTracks()) return 0; - if(!AllocPatterns()) return 0; - - for(t=0;t256)||(size<4)) { - _mm_errno=MMERR_LOADING_PATTERN; - return 0; - } - - of.pattrows[t]=rows; - if(!IMF_ReadPattern(size-4,rows)) return 0; - for(u=0;usamplenumber,0xff,INSTNOTES*sizeof(UWORD)); - - /* read instrument header */ - _mm_read_string(ih.name,32,modreader); - d->insname=DupStr(ih.name,31,1); - _mm_read_UBYTES(ih.what,IMFNOTECNT,modreader); - _mm_fseek(modreader,8,SEEK_CUR); - _mm_read_I_UWORDS(ih.volenv,IMFENVCNT,modreader); - _mm_read_I_UWORDS(ih.panenv,IMFENVCNT,modreader); - _mm_read_I_UWORDS(ih.pitenv,IMFENVCNT,modreader); - -#if defined __STDC__ || defined _MSC_VER -#define IMF_FinishLoadingEnvelope(name) \ - ih. name##pts=_mm_read_UBYTE(modreader); \ - ih. name##sus=_mm_read_UBYTE(modreader); \ - ih. name##beg=_mm_read_UBYTE(modreader); \ - ih. name##end=_mm_read_UBYTE(modreader); \ - ih. name##flg=_mm_read_UBYTE(modreader); \ - _mm_read_UBYTE(modreader); \ - _mm_read_UBYTE(modreader); \ - _mm_read_UBYTE(modreader) -#else -#define IMF_FinishLoadingEnvelope(name) \ - ih. name/**/pts=_mm_read_UBYTE(modreader); \ - ih. name/**/sus=_mm_read_UBYTE(modreader); \ - ih. name/**/beg=_mm_read_UBYTE(modreader); \ - ih. name/**/end=_mm_read_UBYTE(modreader); \ - ih. name/**/flg=_mm_read_UBYTE(modreader); \ - _mm_read_UBYTE(modreader); \ - _mm_read_UBYTE(modreader); \ - _mm_read_UBYTE(modreader) -#endif - - IMF_FinishLoadingEnvelope(vol); - IMF_FinishLoadingEnvelope(pan); - IMF_FinishLoadingEnvelope(pit); - - ih.volfade=_mm_read_I_UWORD(modreader); - ih.numsmp =_mm_read_I_UWORD(modreader); - - _mm_read_UBYTES(id,4,modreader); - /* Looks like Imago Orpheus forgets the signature for empty - instruments following a multi-sample instrument... */ - if(memcmp(id,"II10",4) && - (oldnumsmp && memcmp(id,"\x0\x0\x0\x0",4))) { - if(nextwav) free(nextwav); - if(wh) free(wh); - _mm_errno=MMERR_LOADING_SAMPLEINFO; - return 0; - } - oldnumsmp=ih.numsmp; - - if((ih.numsmp>16)||(ih.volpts>IMFENVCNT/2)||(ih.panpts>IMFENVCNT/2)|| - (ih.pitpts>IMFENVCNT/2)||(_mm_eof(modreader))) { - if(nextwav) free(nextwav); - if(wh) free(wh); - _mm_errno=MMERR_LOADING_SAMPLEINFO; - return 0; - } - - for(u=0;usamplenumber[u]=ih.what[u]>ih.numsmp?0xffff:ih.what[u]+of.numsmp; - d->volfade=ih.volfade; - -#if defined __STDC__ || defined _MSC_VER -#define IMF_ProcessEnvelope(name) \ - for (u = 0; u < (IMFENVCNT >> 1); u++) { \ - d-> name##env[u].pos = ih. name##env[u << 1]; \ - d-> name##env[u].val = ih. name##env[(u << 1)+ 1]; \ - } \ - if (ih. name##flg&1) d-> name##flg|=EF_ON; \ - if (ih. name##flg&2) d-> name##flg|=EF_SUSTAIN; \ - if (ih. name##flg&4) d-> name##flg|=EF_LOOP; \ - d-> name##susbeg=d-> name##susend=ih. name##sus; \ - d-> name##beg=ih. name##beg; \ - d-> name##end=ih. name##end; \ - d-> name##pts=ih. name##pts; \ - \ - if ((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \ - d-> name##flg&=~EF_ON -#else -#define IMF_ProcessEnvelope(name) \ - for (u = 0; u < (IMFENVCNT >> 1); u++) { \ - d-> name/**/env[u].pos = ih. name/**/env[u << 1]; \ - d-> name/**/env[u].val = ih. name/**/env[(u << 1)+ 1]; \ - } \ - if (ih. name/**/flg&1) d-> name/**/flg|=EF_ON; \ - if (ih. name/**/flg&2) d-> name/**/flg|=EF_SUSTAIN; \ - if (ih. name/**/flg&4) d-> name/**/flg|=EF_LOOP; \ - d-> name/**/susbeg=d-> name/**/susend=ih. name/**/sus; \ - d-> name/**/beg=ih. name/**/beg; \ - d-> name/**/end=ih. name/**/end; \ - d-> name/**/pts=ih. name/**/pts; \ - \ - if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \ - d-> name/**/flg&=~EF_ON -#endif - - IMF_ProcessEnvelope(vol); - IMF_ProcessEnvelope(pan); - IMF_ProcessEnvelope(pit); -#undef IMF_ProcessEnvelope - - if(ih.pitflg&1) { - d->pitflg&=~EF_ON; -#ifdef MIKMOD_DEBUG - fprintf(stderr, "\rFilter envelopes not supported yet\n"); -#endif - } - - /* gather sample information */ - for(u=0;usamplename,13,modreader); - _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader); - s->length =_mm_read_I_ULONG(modreader); - s->loopstart =_mm_read_I_ULONG(modreader); - s->loopend =_mm_read_I_ULONG(modreader); - s->samplerate=_mm_read_I_ULONG(modreader); - s->volume =_mm_read_UBYTE(modreader)&0x7f; - s->pan =_mm_read_UBYTE(modreader); - _mm_fseek(modreader,14,SEEK_CUR); - s->flags =_mm_read_UBYTE(modreader); - _mm_fseek(modreader,11,SEEK_CUR); - _mm_read_UBYTES(id,4,modreader); - if(((memcmp(id,"IS10",4))&&(memcmp(id,"IW10",4)))|| - (_mm_eof(modreader))) { - free(nextwav);free(wh); - _mm_errno=MMERR_LOADING_SAMPLEINFO; - return 0; - } - nextwav[of.numsmp+u]=_mm_ftell(modreader); - _mm_fseek(modreader,s->length,SEEK_CUR); - } - - of.numsmp+=ih.numsmp; - d++; - } - - /* sanity check */ - if(!of.numsmp) { - if(nextwav) free(nextwav); - if(wh) free(wh); - _mm_errno=MMERR_LOADING_SAMPLEINFO; - return 0; - } - - /* load samples */ - if(!AllocSamples()) { - free(nextwav);free(wh); - return 0; - } - if(!AllocLinear()) { - free(nextwav);free(wh); - return 0; - } - q=of.samples; - s=wh; - for(u=0;usamplename=DupStr(s->samplename,12,1); - q->length =s->length; - q->loopstart=s->loopstart; - q->loopend =s->loopend; - q->volume =s->volume; - q->speed =s->samplerate; - if(of.flags&UF_LINEAR) - q->speed=speed_to_finetune(s->samplerate<<1,u); - q->panning =s->pan; - q->seekpos =nextwav[u]; - - q->flags|=SF_SIGNED; - if(s->flags&0x1) q->flags|=SF_LOOP; - if(s->flags&0x2) q->flags|=SF_BIDI; - if(s->flags&0x8) q->flags|=SF_OWNPAN; - if(s->flags&0x4) { - q->flags|=SF_16BITS; - q->length >>=1; - q->loopstart>>=1; - q->loopend >>=1; - } - } - - d=of.instruments; - s=wh; - for(u=0;usamplenumber[t]>=of.numsmp) - d->samplenote[t]=255; - else if (of.flags&UF_LINEAR) { - int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]]; - d->samplenote[u]=(note<0)?0:(note>255?255:note); - } else - d->samplenote[t]=t; - } - } - - free(wh);free(nextwav); - return 1; -} - -CHAR *IMF_LoadTitle(void) -{ - CHAR s[31]; - - _mm_fseek(modreader,0,SEEK_SET); - if(!_mm_read_UBYTES(s,31,modreader)) return NULL; - - return(DupStr(s,31,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_imf={ - NULL, - "IMF", - "IMF (Imago Orpheus)", - IMF_Init, - IMF_Test, - IMF_Load, - IMF_Cleanup, - IMF_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_it.c b/mikmod/load_it.c deleted file mode 100644 index 1bf81945..00000000 --- a/mikmod/load_it.c +++ /dev/null @@ -1,1008 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Impulse tracker (IT) module loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -extern int toupper(int); -#endif - -/*========== Module structure */ - -/* header */ -typedef struct ITHEADER { - CHAR songname[26]; - UBYTE blank01[2]; - UWORD ordnum; - UWORD insnum; - UWORD smpnum; - UWORD patnum; - UWORD cwt; /* Created with tracker (y.xx = 0x0yxx) */ - UWORD cmwt; /* Compatible with tracker ver > than val. */ - UWORD flags; - UWORD special; /* bit 0 set = song message attached */ - UBYTE globvol; - UBYTE mixvol; /* mixing volume [ignored] */ - UBYTE initspeed; - UBYTE inittempo; - UBYTE pansep; /* panning separation between channels */ - UBYTE zerobyte; - UWORD msglength; - ULONG msgoffset; - UBYTE blank02[4]; - UBYTE pantable[64]; - UBYTE voltable[64]; -} ITHEADER; - -/* sample information */ -typedef struct ITSAMPLE { - CHAR filename[12]; - UBYTE zerobyte; - UBYTE globvol; - UBYTE flag; - UBYTE volume; - UBYTE panning; - CHAR sampname[28]; - UWORD convert; /* sample conversion flag */ - ULONG length; - ULONG loopbeg; - ULONG loopend; - ULONG c5spd; - ULONG susbegin; - ULONG susend; - ULONG sampoffset; - UBYTE vibspeed; - UBYTE vibdepth; - UBYTE vibrate; - UBYTE vibwave; /* 0=sine, 1=rampdown, 2=square, 3=random (speed ignored) */ -} ITSAMPLE; - -/* instrument information */ - -#define ITENVCNT 25 -#define ITNOTECNT 120 -typedef struct ITINSTHEADER { - ULONG size; /* (dword) Instrument size */ - CHAR filename[12]; /* (char) Instrument filename */ - UBYTE zerobyte; /* (byte) Instrument type (always 0) */ - UBYTE volflg; - UBYTE volpts; - UBYTE volbeg; /* (byte) Volume loop start (node) */ - UBYTE volend; /* (byte) Volume loop end (node) */ - UBYTE volsusbeg; /* (byte) Volume sustain begin (node) */ - UBYTE volsusend; /* (byte) Volume Sustain end (node) */ - UBYTE panflg; - UBYTE panpts; - UBYTE panbeg; /* (byte) channel loop start (node) */ - UBYTE panend; /* (byte) channel loop end (node) */ - UBYTE pansusbeg; /* (byte) channel sustain begin (node) */ - UBYTE pansusend; /* (byte) channel Sustain end (node) */ - UBYTE pitflg; - UBYTE pitpts; - UBYTE pitbeg; /* (byte) pitch loop start (node) */ - UBYTE pitend; /* (byte) pitch loop end (node) */ - UBYTE pitsusbeg; /* (byte) pitch sustain begin (node) */ - UBYTE pitsusend; /* (byte) pitch Sustain end (node) */ - UWORD blank; - UBYTE globvol; - UBYTE chanpan; - UWORD fadeout; /* Envelope end / NNA volume fadeout */ - UBYTE dnc; /* Duplicate note check */ - UBYTE dca; /* Duplicate check action */ - UBYTE dct; /* Duplicate check type */ - UBYTE nna; /* New Note Action [0,1,2,3] */ - UWORD trkvers; /* tracker version used to save [files only] */ - UBYTE ppsep; /* Pitch-pan Separation */ - UBYTE ppcenter; /* Pitch-pan Center */ - UBYTE rvolvar; /* random volume varations */ - UBYTE rpanvar; /* random panning varations */ - UWORD numsmp; /* Number of samples in instrument [files only] */ - CHAR name[26]; /* Instrument name */ - UBYTE blank01[6]; - UWORD samptable[ITNOTECNT];/* sample for each note [note / samp pairs] */ - UBYTE volenv[200]; /* volume envelope (IT 1.x stuff) */ - UBYTE oldvoltick[ITENVCNT];/* volume tick position (IT 1.x stuff) */ - UBYTE volnode[ITENVCNT]; /* amplitude of volume nodes */ - UWORD voltick[ITENVCNT]; /* tick value of volume nodes */ - SBYTE pannode[ITENVCNT]; /* panenv - node points */ - UWORD pantick[ITENVCNT]; /* tick value of panning nodes */ - SBYTE pitnode[ITENVCNT]; /* pitchenv - node points */ - UWORD pittick[ITENVCNT]; /* tick value of pitch nodes */ -} ITINSTHEADER; - -/* unpacked note */ - -typedef struct ITNOTE { - UBYTE note,ins,volpan,cmd,inf; -} ITNOTE; - -/*========== Loader data */ - -static ULONG *paraptr=NULL; /* parapointer array (see IT docs) */ -static ITHEADER *mh=NULL; -static ITNOTE *itpat=NULL; /* allocate to space for one full pattern */ -static UBYTE *mask=NULL; /* arrays allocated to 64 elements and used for */ -static ITNOTE *last=NULL; /* uncompressing IT's pattern information */ -static int numtrk=0; -static unsigned int old_effect; /* if set, use S3M old-effects stuffs */ - -static CHAR* IT_Version[]={ - "ImpulseTracker . ", - "Compressed ImpulseTracker . ", - "ImpulseTracker 2.14p3", - "Compressed ImpulseTracker 2.14p3", - "ImpulseTracker 2.14p4", - "Compressed ImpulseTracker 2.14p4", -}; - -/* table for porta-to-note command within volume/panning column */ -static UBYTE portatable[10]= {0,1,4,8,16,32,64,96,128,255}; - -/*========== Loader code */ - -BOOL IT_Test(void) -{ - UBYTE id[4]; - - if(!_mm_read_UBYTES(id,4,modreader)) return 0; - if(!memcmp(id,"IMPM",4)) return 1; - return 0; -} - -BOOL IT_Init(void) -{ - if(!(mh=(ITHEADER*)_mm_malloc(sizeof(ITHEADER)))) return 0; - if(!(poslookup=(UBYTE*)_mm_malloc(256*sizeof(UBYTE)))) return 0; - if(!(itpat=(ITNOTE*)_mm_malloc(200*64*sizeof(ITNOTE)))) return 0; - if(!(mask=(UBYTE*)_mm_malloc(64*sizeof(UBYTE)))) return 0; - if(!(last=(ITNOTE*)_mm_malloc(64*sizeof(ITNOTE)))) return 0; - - return 1; -} - -void IT_Cleanup(void) -{ - FreeLinear(); - - _mm_free(mh); - _mm_free(poslookup); - _mm_free(itpat); - _mm_free(mask); - _mm_free(last); - _mm_free(paraptr); - _mm_free(origpositions); -} - -/* Because so many IT files have 64 channels as the set number used, but really - only use far less (usually from 8 to 24 still), I had to make this function, - which determines the number of channels that are actually USED by a pattern. - - NOTE: You must first seek to the file location of the pattern before calling - this procedure. - - Returns 1 on error -*/ -static BOOL IT_GetNumChannels(UWORD patrows) -{ - int row=0,flag,ch; - - do { - if((flag=_mm_read_UBYTE(modreader))==EOF) { - _mm_errno=MMERR_LOADING_PATTERN; - return 1; - } - if(!flag) - row++; - else { - ch=(flag-1)&63; - remap[ch]=0; - if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader); - if(mask[ch]&1) _mm_read_UBYTE(modreader); - if(mask[ch]&2) _mm_read_UBYTE(modreader); - if(mask[ch]&4) _mm_read_UBYTE(modreader); - if(mask[ch]&8) { _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader); } - } - } while(rownote=n->note=_mm_read_UBYTE(modreader))==255) - l->note=n->note=253; - if(mask[ch]&2) - l->ins=n->ins=_mm_read_UBYTE(modreader); - if(mask[ch]&4) - l->volpan=n->volpan=_mm_read_UBYTE(modreader); - if(mask[ch]&8) { - l->cmd=n->cmd=_mm_read_UBYTE(modreader); - l->inf=n->inf=_mm_read_UBYTE(modreader); - } - if(mask[ch]&16) - n->note=l->note; - if(mask[ch]&32) - n->ins=l->ins; - if(mask[ch]&64) - n->volpan=l->volpan; - if(mask[ch]&128) { - n->cmd=l->cmd; - n->inf=l->inf; - } - } - } while(rowsongname,26,modreader); - _mm_read_UBYTES(mh->blank01,2,modreader); - mh->ordnum =_mm_read_I_UWORD(modreader); - mh->insnum =_mm_read_I_UWORD(modreader); - mh->smpnum =_mm_read_I_UWORD(modreader); - mh->patnum =_mm_read_I_UWORD(modreader); - mh->cwt =_mm_read_I_UWORD(modreader); - mh->cmwt =_mm_read_I_UWORD(modreader); - mh->flags =_mm_read_I_UWORD(modreader); - mh->special =_mm_read_I_UWORD(modreader); - mh->globvol =_mm_read_UBYTE(modreader); - mh->mixvol =_mm_read_UBYTE(modreader); - mh->initspeed =_mm_read_UBYTE(modreader); - mh->inittempo =_mm_read_UBYTE(modreader); - mh->pansep =_mm_read_UBYTE(modreader); - mh->zerobyte =_mm_read_UBYTE(modreader); - mh->msglength =_mm_read_I_UWORD(modreader); - mh->msgoffset =_mm_read_I_ULONG(modreader); - _mm_read_UBYTES(mh->blank02,4,modreader); - _mm_read_UBYTES(mh->pantable,64,modreader); - _mm_read_UBYTES(mh->voltable,64,modreader); - - if(_mm_eof(modreader)) { - _mm_errno=MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */ - of.reppos = 0; - of.numpat = mh->patnum; - of.numins = mh->insnum; - of.numsmp = mh->smpnum; - of.initspeed = mh->initspeed; - of.inittempo = mh->inittempo; - of.initvolume = mh->globvol; - of.flags |= UF_BGSLIDES | UF_ARPMEM; - if (!(mh->flags & 1)) - of.flags |= UF_PANNING; - of.bpmlimit=32; - - if(mh->songname[25]) { - of.numvoices=1+mh->songname[25]; -#ifdef MIKMOD_DEBUG - fprintf(stderr,"Embedded IT limitation to %d voices\n",of.numvoices); -#endif - } - - /* set the module type */ - /* 2.17 : IT 2.14p4 */ - /* 2.16 : IT 2.14p3 with resonant filters */ - /* 2.15 : IT 2.14p3 (improved compression) */ - if((mh->cwt<=0x219)&&(mh->cwt>=0x217)) - of.modtype=strdup(IT_Version[mh->cmwt<0x214?4:5]); - else if (mh->cwt>=0x215) - of.modtype=strdup(IT_Version[mh->cmwt<0x214?2:3]); - else { - of.modtype = strdup(IT_Version[mh->cmwt<0x214?0:1]); - of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0'; - of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0'; - of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0'; - } - - if(mh->flags&8) - of.flags |= UF_XMPERIODS | UF_LINEAR; - - if((mh->cwt>=0x106)&&(mh->flags&16)) - old_effect=S3MIT_OLDSTYLE; - else - old_effect=0; - - /* set panning positions */ - if (mh->flags & 1) - for(t=0;t<64;t++) { - mh->pantable[t]&=0x7f; - if(mh->pantable[t]<64) - of.panning[t]=mh->pantable[t]<<2; - else if(mh->pantable[t]==64) - of.panning[t]=255; - else if(mh->pantable[t]==100) - of.panning[t]=PAN_SURROUND; - else if(mh->pantable[t]==127) - of.panning[t]=PAN_CENTER; - else { - _mm_errno=MMERR_LOADING_HEADER; - return 0; - } - } - else - for(t=0;t<64;t++) - of.panning[t]=PAN_CENTER; - - /* set channel volumes */ - memcpy(of.chanvol,mh->voltable,64); - - /* read the order data */ - if(!AllocPositions(mh->ordnum)) return 0; - if(!(origpositions=_mm_calloc(mh->ordnum,sizeof(UWORD)))) return 0; - - for(t=0;tordnum;t++) { - origpositions[t]=_mm_read_UBYTE(modreader); - if((origpositions[t]>mh->patnum)&&(origpositions[t]<254)) - origpositions[t]=255; - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - poslookupcnt=mh->ordnum; - S3MIT_CreateOrders(curious); - - if(!(paraptr=(ULONG*)_mm_malloc((mh->insnum+mh->smpnum+of.numpat)* - sizeof(ULONG)))) return 0; - - /* read the instrument, sample, and pattern parapointers */ - _mm_read_I_ULONGS(paraptr,mh->insnum+mh->smpnum+of.numpat,modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* Check for and load midi information for resonant filters */ - if(mh->cmwt>=0x216) { - if(mh->special&8) { - IT_LoadMidiConfiguration(modreader); - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - } else - IT_LoadMidiConfiguration(NULL); - filters=1; - } - - /* Check for and load song comment */ - if((mh->special&1)&&(mh->cwt>=0x104)&&(mh->msglength)) { - _mm_fseek(modreader,(long)(mh->msgoffset),SEEK_SET); - if(!ReadComment(mh->msglength)) return 0; - } - - if(!(mh->flags&4)) of.numins=of.numsmp; - if(!AllocSamples()) return 0; - - if(!AllocLinear()) return 0; - - /* Load all samples */ - q = of.samples; - for(t=0;tsmpnum;t++) { - ITSAMPLE s; - - /* seek to sample position */ - _mm_fseek(modreader,(long)(paraptr[mh->insnum+t]+4),SEEK_SET); - - /* load sample info */ - _mm_read_string(s.filename,12,modreader); - s.zerobyte = _mm_read_UBYTE(modreader); - s.globvol = _mm_read_UBYTE(modreader); - s.flag = _mm_read_UBYTE(modreader); - s.volume = _mm_read_UBYTE(modreader); - _mm_read_string(s.sampname,26,modreader); - s.convert = _mm_read_UBYTE(modreader); - s.panning = _mm_read_UBYTE(modreader); - s.length = _mm_read_I_ULONG(modreader); - s.loopbeg = _mm_read_I_ULONG(modreader); - s.loopend = _mm_read_I_ULONG(modreader); - s.c5spd = _mm_read_I_ULONG(modreader); - s.susbegin = _mm_read_I_ULONG(modreader); - s.susend = _mm_read_I_ULONG(modreader); - s.sampoffset = _mm_read_I_ULONG(modreader); - s.vibspeed = _mm_read_UBYTE(modreader); - s.vibdepth = _mm_read_UBYTE(modreader); - s.vibrate = _mm_read_UBYTE(modreader); - s.vibwave = _mm_read_UBYTE(modreader); - - /* Generate an error if c5spd is > 512k, or samplelength > 256 megs - (nothing would EVER be that high) */ - - if(_mm_eof(modreader)||(s.c5spd>0x7ffffL)||(s.length>0xfffffffUL)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - /* Reality check for sample loop information */ - if((s.flag&16)&& - ((s.loopbeg>0xfffffffUL)||(s.loopend>0xfffffffUL))) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - q->samplename = DupStr(s.sampname,26,0); - q->speed = s.c5spd / 2; - q->panning = ((s.panning&127)==64)?255:(s.panning&127)<<2; - q->length = s.length; - q->loopstart = s.loopbeg; - q->loopend = s.loopend; - q->volume = s.volume; - q->globvol = s.globvol; - q->seekpos = s.sampoffset; - - /* Convert speed to XM linear finetune */ - if(of.flags&UF_LINEAR) - q->speed=speed_to_finetune(s.c5spd,t); - - if(s.panning&128) q->flags|=SF_OWNPAN; - - if(s.vibrate) { - q->vibflags |= AV_IT; - q->vibtype = s.vibwave; - q->vibsweep = s.vibrate * 2; - q->vibdepth = s.vibdepth; - q->vibrate = s.vibspeed; - } - - if(s.flag&2) q->flags|=SF_16BITS; - if((s.flag&8)&&(mh->cwt>=0x214)) { - q->flags|=SF_ITPACKED; - compressed=1; - } - if(s.flag&16) q->flags|=SF_LOOP; - if(s.flag&64) q->flags|=SF_BIDI; - - if(mh->cwt>=0x200) { - if(s.convert&1) q->flags|=SF_SIGNED; - if(s.convert&4) q->flags|=SF_DELTA; - } - q++; - } - - /* Load instruments if instrument mode flag enabled */ - if(mh->flags&4) { - if(!AllocInstruments()) return 0; - d=of.instruments; - of.flags|=UF_NNA|UF_INST; - - for(t=0;tinsnum;t++) { - ITINSTHEADER ih; - - /* seek to instrument position */ - _mm_fseek(modreader,paraptr[t]+4,SEEK_SET); - - /* load instrument info */ - _mm_read_string(ih.filename,12,modreader); - ih.zerobyte = _mm_read_UBYTE(modreader); - if(mh->cwt<0x200) { - /* load IT 1.xx inst header */ - ih.volflg = _mm_read_UBYTE(modreader); - ih.volbeg = _mm_read_UBYTE(modreader); - ih.volend = _mm_read_UBYTE(modreader); - ih.volsusbeg = _mm_read_UBYTE(modreader); - ih.volsusend = _mm_read_UBYTE(modreader); - _mm_read_I_UWORD(modreader); - ih.fadeout = _mm_read_I_UWORD(modreader); - ih.nna = _mm_read_UBYTE(modreader); - ih.dnc = _mm_read_UBYTE(modreader); - } else { - /* Read IT200+ header */ - ih.nna = _mm_read_UBYTE(modreader); - ih.dct = _mm_read_UBYTE(modreader); - ih.dca = _mm_read_UBYTE(modreader); - ih.fadeout = _mm_read_I_UWORD(modreader); - ih.ppsep = _mm_read_UBYTE(modreader); - ih.ppcenter = _mm_read_UBYTE(modreader); - ih.globvol = _mm_read_UBYTE(modreader); - ih.chanpan = _mm_read_UBYTE(modreader); - ih.rvolvar = _mm_read_UBYTE(modreader); - ih.rpanvar = _mm_read_UBYTE(modreader); - } - - ih.trkvers = _mm_read_I_UWORD(modreader); - ih.numsmp = _mm_read_UBYTE(modreader); - _mm_read_UBYTE(modreader); - _mm_read_string(ih.name,26,modreader); - _mm_read_UBYTES(ih.blank01,6,modreader); - _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader); - if(mh->cwt<0x200) { - /* load IT 1xx volume envelope */ - _mm_read_UBYTES(ih.volenv,200,modreader); - for(lp=0;lpvolflg|=EF_VOLENV; - d->insname = DupStr(ih.name,26,0); - d->nnatype = ih.nna & NNA_MASK; - - if(mh->cwt<0x200) { - d->volfade=ih.fadeout<< 6; - if(ih.dnc) { - d->dct=DCT_NOTE; - d->dca=DCA_CUT; - } - - if(ih.volflg&1) d->volflg|=EF_ON; - if(ih.volflg&2) d->volflg|=EF_LOOP; - if(ih.volflg&4) d->volflg|=EF_SUSTAIN; - - /* XM conversion of IT envelope Array */ - d->volbeg = ih.volbeg; - d->volend = ih.volend; - d->volsusbeg = ih.volsusbeg; - d->volsusend = ih.volsusend; - - if(ih.volflg&1) { - for(u=0;uvolpts]!=0xff) { - d->volenv[d->volpts].val=(ih.volnode[d->volpts]<<2); - d->volenv[d->volpts].pos=ih.oldvoltick[d->volpts]; - d->volpts++; - } else - break; - } - } else { - d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2; - if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN; - - if(!(ih.ppsep & 128)) { - d->pitpansep=ih.ppsep<<2; - d->pitpancenter=ih.ppcenter; - d->flags|=IF_PITCHPAN; - } - d->globvol=ih.globvol>>1; - d->volfade=ih.fadeout<<5; - d->dct =ih.dct; - d->dca =ih.dca; - - if(mh->cwt>=0x204) { - d->rvolvar = ih.rvolvar; - d->rpanvar = ih.rpanvar; - } - -#if defined __STDC__ || defined _MSC_VER -#define IT_ProcessEnvelope(name) \ - if(ih. name##flg&1) d-> name##flg|=EF_ON; \ - if(ih. name##flg&2) d-> name##flg|=EF_LOOP; \ - if(ih. name##flg&4) d-> name##flg|=EF_SUSTAIN; \ - d-> name##pts=ih. name##pts; \ - d-> name##beg=ih. name##beg; \ - d-> name##end=ih. name##end; \ - d-> name##susbeg=ih. name##susbeg; \ - d-> name##susend=ih. name##susend; \ - \ - for(u=0;u name##env[u].pos=ih. name##tick[u]; \ - \ - if((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \ - d-> name##flg&=~EF_ON -#else -#define IT_ProcessEnvelope(name) \ - if(ih. name/**/flg&1) d-> name/**/flg|=EF_ON; \ - if(ih. name/**/flg&2) d-> name/**/flg|=EF_LOOP; \ - if(ih. name/**/flg&4) d-> name/**/flg|=EF_SUSTAIN; \ - d-> name/**/pts=ih. name/**/pts; \ - d-> name/**/beg=ih. name/**/beg; \ - d-> name/**/end=ih. name/**/end; \ - d-> name/**/susbeg=ih. name/**/susbeg; \ - d-> name/**/susend=ih. name/**/susend; \ - \ - for(u=0;u name/**/env[u].pos=ih. name/**/tick[u]; \ - \ - if((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \ - d-> name/**/flg&=~EF_ON -#endif - - IT_ProcessEnvelope(vol); - for(u=0;uvolenv[u].val=(ih.volnode[u]<<2); - - IT_ProcessEnvelope(pan); - for(u=0;upanenv[u].val= - ih.pannode[u]==32?255:(ih.pannode[u]+32)<<2; - - IT_ProcessEnvelope(pit); - for(u=0;upitenv[u].val=ih.pitnode[u]+32; -#undef IT_ProcessEnvelope - - if(ih.pitflg&0x80) { - /* filter envelopes not supported yet */ - d->pitflg&=~EF_ON; - ih.pitpts=ih.pitbeg=ih.pitend=0; -#ifdef MIKMOD_DEBUG - { - static int warn=0; - - if(!warn) - fprintf(stderr, "\rFilter envelopes not supported yet\n"); - warn=1; - } -#endif - } - } - - for(u=0;usamplenote[u]=(ih.samptable[u]&255); - d->samplenumber[u]= - (ih.samptable[u]>>8)?((ih.samptable[u]>>8)-1):0xffff; - if(d->samplenumber[u]>=of.numsmp) - d->samplenote[u]=255; - else if (of.flags&UF_LINEAR) { - int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]]; - d->samplenote[u]=(note<0)?0:(note>255?255:note); - } - } - - d++; - } - } else if(of.flags & UF_LINEAR) { - if(!AllocInstruments()) return 0; - d=of.instruments; - of.flags|=UF_INST; - - for(t=0;tsmpnum;t++,d++) - for(u=0;usamplenumber[u]>=of.numsmp) - d->samplenote[u]=255; - else { - int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]]; - d->samplenote[u]=(note<0)?0:(note>255?255:note); - } - } - } - - /* Figure out how many channels this song actually uses */ - of.numchn=0; - memset(remap,-1,UF_MAXCHAN*sizeof(UBYTE)); - for(t=0;tinsnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */ - _mm_fseek(modreader,((long)paraptr[mh->insnum+mh->smpnum+t]),SEEK_SET); - _mm_read_I_UWORD(modreader); - /* read pattern length (# of rows) - Impulse Tracker never creates patterns with less than 32 rows, - but some other trackers do, so we only check for more than 256 - rows */ - packlen=_mm_read_I_UWORD(modreader); - if(packlen>256) { - _mm_errno=MMERR_LOADING_PATTERN; - return 0; - } - _mm_read_I_ULONG(modreader); - if(IT_GetNumChannels(packlen)) return 0; - } - } - - /* give each of them a different number */ - for(t=0;tinsnum+mh->smpnum+t]) { /* 0 -> empty 64 row pattern */ - of.pattrows[t]=64; - for(u=0;uinsnum+mh->smpnum+t]),SEEK_SET); - packlen=_mm_read_I_UWORD(modreader); - of.pattrows[t]=_mm_read_I_UWORD(modreader); - _mm_read_I_ULONG(modreader); - if(!IT_ReadPattern(of.pattrows[t])) return 0; - } - } - - return 1; -} - -CHAR *IT_LoadTitle(void) -{ - CHAR s[26]; - - _mm_fseek(modreader,4,SEEK_SET); - if(!_mm_read_UBYTES(s,26,modreader)) return NULL; - - return(DupStr(s,26,0)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_it={ - NULL, - "IT", - "IT (Impulse Tracker)", - IT_Init, - IT_Test, - IT_Load, - IT_Cleanup, - IT_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_m15.c b/mikmod/load_m15.c deleted file mode 100644 index efa0dba4..00000000 --- a/mikmod/load_m15.c +++ /dev/null @@ -1,505 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_m15.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - 15 instrument MOD loader - Also supports Ultimate Sound Tracker (old M15 format) - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module Structure */ - -typedef struct MSAMPINFO { - CHAR samplename[23]; /* 22 in module, 23 in memory */ - UWORD length; - UBYTE finetune; - UBYTE volume; - UWORD reppos; - UWORD replen; -} MSAMPINFO; - -typedef struct MODULEHEADER { - CHAR songname[21]; /* the songname.., 20 in module, 21 in memory */ - MSAMPINFO samples[15]; /* all sampleinfo */ - UBYTE songlength; /* number of patterns used */ - UBYTE magic1; /* should be 127 */ - UBYTE positions[128]; /* which pattern to play at pos */ -} MODULEHEADER; - -typedef struct MODNOTE { - UBYTE a,b,c,d; -} MODNOTE; - -/*========== Loader variables */ - -static MODULEHEADER *mh = NULL; -static MODNOTE *patbuf = NULL; -static BOOL ust_loader = 0; /* if TRUE, load as an ust module. */ - -/* known file formats which can confuse the loader */ -#define REJECT 2 -static char *signatures[REJECT]={ - "CAKEWALK", /* cakewalk midi files */ - "SZDD" /* Microsoft compressed files */ -}; -static int siglen[REJECT]={8,4}; - -/*========== Loader code */ - -static BOOL LoadModuleHeader(MODULEHEADER *mh) -{ - int t,u; - - _mm_read_string(mh->songname,20,modreader); - mh->songname[20]=0; /* just in case */ - - /* sanity check : title should contain printable characters and a bunch - of null chars */ - for(t=0;t<20;t++) - if((mh->songname[t])&&(mh->songname[t]<32)) return 0; - for(t=0;(mh->songname[t])&&(t<20);t++); - if(t<20) for(;t<20;t++) if(mh->songname[t]) return 0; - - for(t=0;t<15;t++) { - MSAMPINFO *s=&mh->samples[t]; - - _mm_read_string(s->samplename,22,modreader); - s->samplename[22]=0; /* just in case */ - s->length =_mm_read_M_UWORD(modreader); - s->finetune =_mm_read_UBYTE(modreader); - s->volume =_mm_read_UBYTE(modreader); - s->reppos =_mm_read_M_UWORD(modreader); - s->replen =_mm_read_M_UWORD(modreader); - - /* sanity check : sample title should contain printable characters and - a bunch of null chars */ - for(u=0;u<20;u++) - if((s->samplename[u])&&(s->samplename[u]samplename[u])&&(u<20);u++); - if(u<20) for(;u<20;u++) if(s->samplename[u]) return 0; - - /* sanity check : finetune values */ - if(s->finetune>>4) return 0; - } - - mh->songlength =_mm_read_UBYTE(modreader); - mh->magic1 =_mm_read_UBYTE(modreader); /* should be 127 */ - - /* sanity check : no more than 128 positions, restart position in range */ - if((!mh->songlength)||(mh->songlength>128)) return 0; - /* values encountered so far are 0x6a and 0x78 */ - if(((mh->magic1&0xf8)!=0x78)&&(mh->magic1!=0x6a)&&(mh->magic1>mh->songlength)) return 0; - - _mm_read_UBYTES(mh->positions,128,modreader); - - /* sanity check : pattern range is 0..63 */ - for(t=0;t<128;t++) - if(mh->positions[t]>63) return 0; - - return(!_mm_eof(modreader)); -} - -/* Checks the patterns in the modfile for UST / 15-inst indications. - For example, if an effect 3xx is found, it is assumed that the song - is 15-inst. If a 1xx effect has dat greater than 0x20, it is UST. - - Returns: 0 indecisive; 1 = UST; 2 = 15-inst */ -static int CheckPatternType(int numpat) -{ - int t; - UBYTE eff, dat; - - for(t=0;t0x1f) return 1; - if(dat<0x3) return 2; - break; - case 2: - if(dat>0x1f) return 1; - return 2; - case 3: - if (dat) return 2; - break; - default: - return 2; - } - } - return 0; -} - -static BOOL M15_Test(void) -{ - int t, numpat; - MODULEHEADER mh; - - ust_loader = 0; - if(!LoadModuleHeader(&mh)) return 0; - - /* reject other file types */ - for(t=0;t127) return 0; - if((!mh.songlength)||(mh.songlength>mh.magic1)) return 0; - - for(t=0;t<15;t++) { - /* all finetunes should be zero */ - if(mh.samples[t].finetune) return 0; - - /* all volumes should be <= 64 */ - if(mh.samples[t].volume>64) return 0; - - /* all instrument names should begin with s, st-, or a number */ - if((mh.samples[t].samplename[0]=='s')|| - (mh.samples[t].samplename[0]=='S')) { - if((memcmp(mh.samples[t].samplename,"st-",3)) && - (memcmp(mh.samples[t].samplename,"ST-",3)) && - (*mh.samples[t].samplename)) - ust_loader = 1; - } else - if(!isdigit((int)mh.samples[t].samplename[0])) - ust_loader = 1; - - if(mh.samples[t].length>4999||mh.samples[t].reppos>9999) { - ust_loader = 0; - if(mh.samples[t].length>32768) return 0; - } - - /* if loop information is incorrect as words, but correct as bytes, - this is likely to be an ust-style module */ - if((mh.samples[t].reppos+mh.samples[t].replen>mh.samples[t].length)&& - (mh.samples[t].reppos+mh.samples[t].replen<(mh.samples[t].length<<1))){ - ust_loader = 1; - return 1; - } - - if(!ust_loader) return 1; - } - - for(numpat=0,t=0;tnumpat) - numpat = mh.positions[t]; - numpat++; - switch(CheckPatternType(numpat)) { - case 0: /* indecisive, so check more clues... */ - break; - case 1: - ust_loader = 1; - break; - case 2: - ust_loader = 0; - break; - } - return 1; -} - -static BOOL M15_Init(void) -{ - if(!(mh=(MODULEHEADER*)_mm_malloc(sizeof(MODULEHEADER)))) return 0; - return 1; -} - -static void M15_Cleanup(void) -{ - _mm_free(mh); - _mm_free(patbuf); -} - -/* -Old (amiga) noteinfo: - - _____byte 1_____ byte2_ _____byte 3_____ byte4_ -/ \ / \ / \ / \ -0000 0000-00000000 0000 0000-00000000 - -Upper four 12 bits for Lower four Effect command. -bits of sam- note period. bits of sam- -ple number. ple number. -*/ - -static UBYTE M15_ConvertNote(MODNOTE* n, UBYTE lasteffect) -{ - UBYTE instrument,effect,effdat,note; - UWORD period; - UBYTE lastnote=0; - - /* decode the 4 bytes that make up a single note */ - instrument = n->c>>4; - period = (((UWORD)n->a&0xf)<<8)+n->b; - effect = n->c&0xf; - effdat = n->d; - - /* Convert the period to a note number */ - note=0; - if(period) { - for(note=0;note<7*OCTAVE;note++) - if(period>=npertab[note]) break; - if(note==7*OCTAVE) note=0; - else note++; - } - - if(instrument) { - /* if instrument does not exist, note cut */ - if((instrument>15)||(!mh->samples[instrument-1].length)) { - UniPTEffect(0xc,0); - if(effect==0xc) effect=effdat=0; - } else { - /* if we had a note, then change instrument... */ - if(note) - UniInstrument(instrument-1); - /* ...otherwise, only adjust volume... */ - else { - /* ...unless an effect was specified, which forces a new note - to be played */ - if(effect||effdat) { - UniInstrument(instrument-1); - note=lastnote; - } else - UniPTEffect(0xc,mh->samples[instrument-1].volume&0x7f); - } - } - } - if(note) { - UniNote(note+2*OCTAVE-1); - lastnote=note; - } - - /* Convert pattern jump from Dec to Hex */ - if(effect == 0xd) - effdat=(((effdat&0xf0)>>4)*10)+(effdat&0xf); - - /* Volume slide, up has priority */ - if((effect==0xa)&&(effdat&0xf)&&(effdat&0xf0)) - effdat&=0xf0; - - /* Handle ``heavy'' volumes correctly */ - if ((effect == 0xc) && (effdat > 0x40)) - effdat = 0x40; - - if(ust_loader) { - switch(effect) { - case 0: - case 3: - break; - case 1: - UniPTEffect(0,effdat); - break; - case 2: - if(effdat&0xf) UniPTEffect(1,effdat&0xf); - else if(effdat>>2) UniPTEffect(2,effdat>>2); - break; - default: - UniPTEffect(effect,effdat); - break; - } - } else { - /* An isolated 100, 200 or 300 effect should be ignored (no - "standalone" porta memory in mod files). However, a sequence - such as 1XX, 100, 100, 100 is fine. */ - if ((!effdat) && ((effect == 1)||(effect == 2)||(effect ==3)) && - (lasteffect < 0x10) && (effect != lasteffect)) - effect = 0; - - UniPTEffect(effect,effdat); - } - if (effect == 8) - of.flags |= UF_PANNING; - - return effect; -} - -static UBYTE *M15_ConvertTrack(MODNOTE* n) -{ - int t; - UBYTE lasteffect = 0x10; /* non existant effect */ - - UniReset(); - for(t=0;t<64;t++) { - lasteffect = M15_ConvertNote(n,lasteffect); - UniNewline(); - n+=4; - } - return UniDup(); -} - -/* Loads all patterns of a modfile and converts them into the 3 byte format. */ -static BOOL M15_LoadPatterns(void) -{ - int t,s,tracks=0; - - if(!AllocPatterns()) return 0; - if(!AllocTracks()) return 0; - - /* Allocate temporary buffer for loading and converting the patterns */ - if(!(patbuf=(MODNOTE*)_mm_calloc(64U*4,sizeof(MODNOTE)))) return 0; - - for(t=0;tsongname,21,1); - of.numpos = mh->songlength; - of.reppos = 0; - - /* Count the number of patterns */ - of.numpat = 0; - for(t=0;tpositions[t]>of.numpat) - of.numpat=mh->positions[t]; - /* since some old modules embed extra patterns, we have to check the - whole list to get the samples' file offsets right - however we can find - garbage here, so check carefully */ - scan=1; - for(t=of.numpos;t<128;t++) - if(mh->positions[t]>=0x80) scan=0; - if (scan) - for(t=of.numpos;t<128;t++) { - if(mh->positions[t]>of.numpat) - of.numpat=mh->positions[t]; - if((curious)&&(mh->positions[t])) of.numpos=t+1; - } - of.numpat++; - of.numtrk = of.numpat*of.numchn; - - if(!AllocPositions(of.numpos)) return 0; - for(t=0;tpositions[t]; - - /* Finally, init the sampleinfo structures */ - of.numins=of.numsmp=15; - if(!AllocSamples()) return 0; - - s = mh->samples; - q = of.samples; - - for(t=0;tsamplename = DupStr(s->samplename,23,1); - - /* init the sampleinfo variables and convert the size pointers */ - q->speed = finetune[s->finetune&0xf]; - q->volume = s->volume; - if(ust_loader) - q->loopstart = s->reppos; - else - q->loopstart = s->reppos<<1; - q->loopend = q->loopstart+(s->replen<<1); - q->length = s->length<<1; - - q->flags = SF_SIGNED; - if(ust_loader) q->flags |= SF_UST_LOOP; - if(s->replen>2) q->flags |= SF_LOOP; - - s++; - q++; - } - - if(!M15_LoadPatterns()) return 0; - ust_loader = 0; - - return 1; -} - -static CHAR *M15_LoadTitle(void) -{ - CHAR s[21]; - - _mm_fseek(modreader,0,SEEK_SET); - if(!_mm_read_UBYTES(s,20,modreader)) return NULL; - s[20]=0; /* just in case */ - return(DupStr(s,21,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_m15={ - NULL, - "15-instrument module", - "MOD (15 instrument)", - M15_Init, - M15_Test, - M15_Load, - M15_Cleanup, - M15_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_med.c b/mikmod/load_med.c deleted file mode 100644 index 932ca0c9..00000000 --- a/mikmod/load_med.c +++ /dev/null @@ -1,719 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_med.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - Amiga MED module loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module information */ - -typedef struct MEDHEADER { - ULONG id; - ULONG modlen; - ULONG MEDSONGP; /* struct MEDSONG *song; */ - UWORD psecnum; /* for the player routine, MMD2 only */ - UWORD pseq; /* " " " " */ - ULONG MEDBlockPP; /* struct MEDBlock **blockarr; */ - ULONG reserved1; - ULONG MEDINSTHEADERPP; /* struct MEDINSTHEADER **smplarr; */ - ULONG reserved2; - ULONG MEDEXPP; /* struct MEDEXP *expdata; */ - ULONG reserved3; - UWORD pstate; /* some data for the player routine */ - UWORD pblock; - UWORD pline; - UWORD pseqnum; - SWORD actplayline; - UBYTE counter; - UBYTE extra_songs; /* number of songs - 1 */ -} MEDHEADER; - -typedef struct MEDSAMPLE { - UWORD rep, replen; /* offs: 0(s), 2(s) */ - UBYTE midich; /* offs: 4(s) */ - UBYTE midipreset; /* offs: 5(s) */ - UBYTE svol; /* offs: 6(s) */ - SBYTE strans; /* offs: 7(s) */ -} MEDSAMPLE; - -typedef struct MEDSONG { - MEDSAMPLE sample[63]; /* 63 * 8 bytes = 504 bytes */ - UWORD numblocks; /* offs: 504 */ - UWORD songlen; /* offs: 506 */ - UBYTE playseq[256]; /* offs: 508 */ - UWORD deftempo; /* offs: 764 */ - SBYTE playtransp; /* offs: 766 */ - UBYTE flags; /* offs: 767 */ - UBYTE flags2; /* offs: 768 */ - UBYTE tempo2; /* offs: 769 */ - UBYTE trkvol[16]; /* offs: 770 */ - UBYTE mastervol; /* offs: 786 */ - UBYTE numsamples; /* offs: 787 */ -} MEDSONG; - -typedef struct MEDEXP { - ULONG nextmod; /* pointer to next module */ - ULONG exp_smp; /* pointer to MEDINSTEXT array */ - UWORD s_ext_entries; - UWORD s_ext_entrsz; - ULONG annotxt; /* pointer to annotation text */ - ULONG annolen; - ULONG iinfo; /* pointer to MEDINSTINFO array */ - UWORD i_ext_entries; - UWORD i_ext_entrsz; - ULONG jumpmask; - ULONG rgbtable; - ULONG channelsplit; - ULONG n_info; - ULONG songname; /* pointer to songname */ - ULONG songnamelen; - ULONG dumps; - ULONG reserved2[7]; -} MEDEXP; - -typedef struct MMD0NOTE { - UBYTE a, b, c; -} MMD0NOTE; - -typedef struct MMD1NOTE { - UBYTE a, b, c, d; -} MMD1NOTE; - -typedef struct MEDINSTHEADER { - ULONG length; - SWORD type; - /* Followed by actual data */ -} MEDINSTHEADER; - -typedef struct MEDINSTEXT { - UBYTE hold; - UBYTE decay; - UBYTE suppress_midi_off; - SBYTE finetune; -} MEDINSTEXT; - -typedef struct MEDINSTINFO { - UBYTE name[40]; -} MEDINSTINFO; - -/*========== Loader variables */ - -#define MMD0_string 0x4D4D4430 -#define MMD1_string 0x4D4D4431 - -static MEDHEADER *mh = NULL; -static MEDSONG *ms = NULL; -static MEDEXP *me = NULL; -static ULONG *ba = NULL; -static MMD0NOTE *mmd0pat = NULL; -static MMD1NOTE *mmd1pat = NULL; - -static BOOL decimalvolumes; -static BOOL bpmtempos; - -#define d0note(row,col) mmd0pat[((row)*(UWORD)of.numchn)+(col)] -#define d1note(row,col) mmd1pat[((row)*(UWORD)of.numchn)+(col)] - -static CHAR MED_Version[] = "OctaMED (MMDx)"; - -/*========== Loader code */ - -BOOL MED_Test(void) -{ - UBYTE id[4]; - - if (!_mm_read_UBYTES(id, 4, modreader)) - return 0; - if ((!memcmp(id, "MMD0", 4)) || (!memcmp(id, "MMD1", 4))) - return 1; - return 0; -} - -BOOL MED_Init(void) -{ - if (!(me = (MEDEXP *)_mm_malloc(sizeof(MEDEXP)))) - return 0; - if (!(mh = (MEDHEADER *)_mm_malloc(sizeof(MEDHEADER)))) - return 0; - if (!(ms = (MEDSONG *)_mm_malloc(sizeof(MEDSONG)))) - return 0; - return 1; -} - -void MED_Cleanup(void) -{ - _mm_free(me); - _mm_free(mh); - _mm_free(ms); - _mm_free(ba); - _mm_free(mmd0pat); - _mm_free(mmd1pat); -} - -static void EffectCvt(UBYTE eff, UBYTE dat) -{ - switch (eff) { - /* 0x0 0x1 0x2 0x3 0x4 PT effects */ - case 0x5: /* PT vibrato with speed/depth nibbles swapped */ - UniPTEffect(0x4, (dat >> 4) | ((dat & 0xf) << 4)); - break; - /* 0x6 0x7 not used */ - case 0x6: - case 0x7: - break; - case 0x8: /* midi hold/decay */ - break; - case 0x9: - if (bpmtempos) { - if (!dat) - dat = of.initspeed; - UniEffect(UNI_S3MEFFECTA, dat); - } else { - if (dat <= 0x20) { - if (!dat) - dat = of.initspeed; - else - dat /= 4; - UniPTEffect(0xf, dat); - } else - UniEffect(UNI_MEDSPEED, ((UWORD)dat * 125) / (33 * 4)); - } - break; - /* 0xa 0xb PT effects */ - case 0xc: - if (decimalvolumes) - dat = (dat >> 4) * 10 + (dat & 0xf); - UniPTEffect(0xc, dat); - break; - case 0xd: /* same as PT volslide */ - UniPTEffect(0xa, dat); - break; - case 0xe: /* synth jmp - midi */ - break; - case 0xf: - switch (dat) { - case 0: /* patternbreak */ - UniPTEffect(0xd, 0); - break; - case 0xf1: /* play note twice */ - UniWriteByte(UNI_MEDEFFECTF1); - break; - case 0xf2: /* delay note */ - UniWriteByte(UNI_MEDEFFECTF2); - break; - case 0xf3: /* play note three times */ - UniWriteByte(UNI_MEDEFFECTF3); - break; - case 0xfe: /* stop playing */ - UniPTEffect(0xb, of.numpat); - break; - case 0xff: /* note cut */ - UniPTEffect(0xc, 0); - break; - default: - if (dat <= 10) - UniPTEffect(0xf, dat); - else if (dat <= 240) { - if (bpmtempos) - UniPTEffect(0xf, (dat < 32) ? 32 : dat); - else - UniEffect(UNI_MEDSPEED, ((UWORD)dat * 125) / 33); - } - } - break; - default: /* all normal PT effects are handled here */ - UniPTEffect(eff, dat); - break; - } -} - -static UBYTE *MED_Convert1(int count, int col) -{ - int t; - UBYTE inst, note, eff, dat; - MMD1NOTE *n; - - UniReset(); - for (t = 0; t < count; t++) { - n = &d1note(t, col); - - note = n->a & 0x7f; - inst = n->b & 0x3f; - eff = n->c & 0xf; - dat = n->d; - - if (inst) - UniInstrument(inst - 1); - if (note) - UniNote(note + 3 * OCTAVE - 1); - EffectCvt(eff, dat); - UniNewline(); - } - return UniDup(); -} - -static UBYTE *MED_Convert0(int count, int col) -{ - int t; - UBYTE a, b, inst, note, eff, dat; - MMD0NOTE *n; - - UniReset(); - for (t = 0; t < count; t++) { - n = &d0note(t, col); - a = n->a; - b = n->b; - - note = a & 0x3f; - a >>= 6; - a = ((a & 1) << 1) | (a >> 1); - inst = (b >> 4) | (a << 4); - eff = b & 0xf; - dat = n->c; - - if (inst) - UniInstrument(inst - 1); - if (note) - UniNote(note + 3 * OCTAVE - 1); - EffectCvt(eff, dat); - UniNewline(); - } - return UniDup(); -} - -static BOOL LoadMEDPatterns(void) -{ - int t, row, col; - UWORD numtracks, numlines, maxlines = 0, track = 0; - MMD0NOTE *mmdp; - - /* first, scan patterns to see how many channels are used */ - for (t = 0; t < of.numpat; t++) { - _mm_fseek(modreader, ba[t], SEEK_SET); - numtracks = _mm_read_UBYTE(modreader); - numlines = _mm_read_UBYTE(modreader); - - if (numtracks > of.numchn) - of.numchn = numtracks; - if (numlines > maxlines) - maxlines = numlines; - } - - of.numtrk = of.numpat * of.numchn; - if (!AllocTracks()) - return 0; - if (!AllocPatterns()) - return 0; - - if (! - (mmd0pat = - (MMD0NOTE *)_mm_calloc(of.numchn * (maxlines + 1), - sizeof(MMD0NOTE)))) return 0; - - /* second read: read and convert patterns */ - for (t = 0; t < of.numpat; t++) { - _mm_fseek(modreader, ba[t], SEEK_SET); - numtracks = _mm_read_UBYTE(modreader); - numlines = _mm_read_UBYTE(modreader); - - of.pattrows[t] = ++numlines; - memset(mmdp = mmd0pat, 0, of.numchn * maxlines * sizeof(MMD0NOTE)); - for (row = numlines; row; row--) { - for (col = numtracks; col; col--, mmdp++) { - mmdp->a = _mm_read_UBYTE(modreader); - mmdp->b = _mm_read_UBYTE(modreader); - mmdp->c = _mm_read_UBYTE(modreader); - } - } - - for (col = 0; col < of.numchn; col++) - of.tracks[track++] = MED_Convert0(numlines, col); - } - return 1; -} - -static BOOL LoadMMD1Patterns(void) -{ - int t, row, col; - UWORD numtracks, numlines, maxlines = 0, track = 0; - MMD1NOTE *mmdp; - - /* first, scan patterns to see how many channels are used */ - for (t = 0; t < of.numpat; t++) { - _mm_fseek(modreader, ba[t], SEEK_SET); - numtracks = _mm_read_M_UWORD(modreader); - numlines = _mm_read_M_UWORD(modreader); - if (numtracks > of.numchn) - of.numchn = numtracks; - if (numlines > maxlines) - maxlines = numlines; - } - - of.numtrk = of.numpat * of.numchn; - if (!AllocTracks()) - return 0; - if (!AllocPatterns()) - return 0; - - if (! - (mmd1pat = - (MMD1NOTE *)_mm_calloc(of.numchn * (maxlines + 1), - sizeof(MMD1NOTE)))) return 0; - - /* second read: really read and convert patterns */ - for (t = 0; t < of.numpat; t++) { - _mm_fseek(modreader, ba[t], SEEK_SET); - numtracks = _mm_read_M_UWORD(modreader); - numlines = _mm_read_M_UWORD(modreader); - - _mm_fseek(modreader, sizeof(ULONG), SEEK_CUR); - of.pattrows[t] = ++numlines; - memset(mmdp = mmd1pat, 0, of.numchn * maxlines * sizeof(MMD1NOTE)); - - for (row = numlines; row; row--) { - for (col = numtracks; col; col--, mmdp++) { - mmdp->a = _mm_read_UBYTE(modreader); - mmdp->b = _mm_read_UBYTE(modreader); - mmdp->c = _mm_read_UBYTE(modreader); - mmdp->d = _mm_read_UBYTE(modreader); - } - } - - for (col = 0; col < of.numchn; col++) - of.tracks[track++] = MED_Convert1(numlines, col); - } - return 1; -} - -BOOL MED_Load(BOOL curious) -{ - int t; - ULONG sa[64]; - MEDINSTHEADER s; - SAMPLE *q; - MEDSAMPLE *mss; - - /* try to read module header */ - mh->id = _mm_read_M_ULONG(modreader); - mh->modlen = _mm_read_M_ULONG(modreader); - mh->MEDSONGP = _mm_read_M_ULONG(modreader); - mh->psecnum = _mm_read_M_UWORD(modreader); - mh->pseq = _mm_read_M_UWORD(modreader); - mh->MEDBlockPP = _mm_read_M_ULONG(modreader); - mh->reserved1 = _mm_read_M_ULONG(modreader); - mh->MEDINSTHEADERPP = _mm_read_M_ULONG(modreader); - mh->reserved2 = _mm_read_M_ULONG(modreader); - mh->MEDEXPP = _mm_read_M_ULONG(modreader); - mh->reserved3 = _mm_read_M_ULONG(modreader); - mh->pstate = _mm_read_M_UWORD(modreader); - mh->pblock = _mm_read_M_UWORD(modreader); - mh->pline = _mm_read_M_UWORD(modreader); - mh->pseqnum = _mm_read_M_UWORD(modreader); - mh->actplayline = _mm_read_M_SWORD(modreader); - mh->counter = _mm_read_UBYTE(modreader); - mh->extra_songs = _mm_read_UBYTE(modreader); - - /* Seek to MEDSONG struct */ - _mm_fseek(modreader, mh->MEDSONGP, SEEK_SET); - - /* Load the MED Song Header */ - mss = ms->sample; /* load the sample data first */ - for (t = 63; t; t--, mss++) { - mss->rep = _mm_read_M_UWORD(modreader); - mss->replen = _mm_read_M_UWORD(modreader); - mss->midich = _mm_read_UBYTE(modreader); - mss->midipreset = _mm_read_UBYTE(modreader); - mss->svol = _mm_read_UBYTE(modreader); - mss->strans = _mm_read_SBYTE(modreader); - } - - ms->numblocks = _mm_read_M_UWORD(modreader); - ms->songlen = _mm_read_M_UWORD(modreader); - _mm_read_UBYTES(ms->playseq, 256, modreader); - ms->deftempo = _mm_read_M_UWORD(modreader); - ms->playtransp = _mm_read_SBYTE(modreader); - ms->flags = _mm_read_UBYTE(modreader); - ms->flags2 = _mm_read_UBYTE(modreader); - ms->tempo2 = _mm_read_UBYTE(modreader); - _mm_read_UBYTES(ms->trkvol, 16, modreader); - ms->mastervol = _mm_read_UBYTE(modreader); - ms->numsamples = _mm_read_UBYTE(modreader); - - /* check for a bad header */ - if (_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* load extension structure */ - if (mh->MEDEXPP) { - _mm_fseek(modreader, mh->MEDEXPP, SEEK_SET); - me->nextmod = _mm_read_M_ULONG(modreader); - me->exp_smp = _mm_read_M_ULONG(modreader); - me->s_ext_entries = _mm_read_M_UWORD(modreader); - me->s_ext_entrsz = _mm_read_M_UWORD(modreader); - me->annotxt = _mm_read_M_ULONG(modreader); - me->annolen = _mm_read_M_ULONG(modreader); - me->iinfo = _mm_read_M_ULONG(modreader); - me->i_ext_entries = _mm_read_M_UWORD(modreader); - me->i_ext_entrsz = _mm_read_M_UWORD(modreader); - me->jumpmask = _mm_read_M_ULONG(modreader); - me->rgbtable = _mm_read_M_ULONG(modreader); - me->channelsplit = _mm_read_M_ULONG(modreader); - me->n_info = _mm_read_M_ULONG(modreader); - me->songname = _mm_read_M_ULONG(modreader); - me->songnamelen = _mm_read_M_ULONG(modreader); - me->dumps = _mm_read_M_ULONG(modreader); - } - - /* seek to and read the samplepointer array */ - _mm_fseek(modreader, mh->MEDINSTHEADERPP, SEEK_SET); - if (!_mm_read_M_ULONGS(sa, ms->numsamples, modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* alloc and read the blockpointer array */ - if (!(ba = (ULONG *)_mm_calloc(ms->numblocks, sizeof(ULONG)))) - return 0; - _mm_fseek(modreader, mh->MEDBlockPP, SEEK_SET); - if (!_mm_read_M_ULONGS(ba, ms->numblocks, modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* copy song positions */ - if (!AllocPositions(ms->songlen)) - return 0; - for (t = 0; t < ms->songlen; t++) - of.positions[t] = ms->playseq[t]; - - decimalvolumes = (ms->flags & 0x10) ? 0 : 1; - bpmtempos = (ms->flags2 & 0x20) ? 1 : 0; - - if (bpmtempos) { - int bpmlen = (ms->flags2 & 0x1f) + 1; - of.initspeed = ms->tempo2; - of.inittempo = ms->deftempo * bpmlen / 4; - - if (bpmlen != 4) { - /* Let's do some math : compute GCD of BPM beat length and speed */ - int a, b; - - a = bpmlen; - b = ms->tempo2; - - if (a > b) { - t = b; - b = a; - a = t; - } - while ((a != b) && (a)) { - t = a; - a = b - a; - b = t; - if (a > b) { - t = b; - b = a; - a = t; - } - } - - of.initspeed /= b; - of.inittempo = ms->deftempo * bpmlen / (4 * b); - } - } else { - of.initspeed = ms->tempo2; - of.inittempo = ms->deftempo ? ((UWORD)ms->deftempo * 125) / 33 : 128; - if ((ms->deftempo <= 10) && (ms->deftempo)) - of.inittempo = (of.inittempo * 33) / 6; - of.flags |= UF_HIGHBPM; - } - MED_Version[12] = mh->id; - of.modtype = strdup(MED_Version); - of.numchn = 0; /* will be counted later */ - of.numpat = ms->numblocks; - of.numpos = ms->songlen; - of.numins = ms->numsamples; - of.numsmp = of.numins; - of.reppos = 0; - if ((mh->MEDEXPP) && (me->songname) && (me->songnamelen)) { - char *name; - - _mm_fseek(modreader, me->songname, SEEK_SET); - name = _mm_malloc(me->songnamelen); - _mm_read_UBYTES(name, me->songnamelen, modreader); - of.songname = DupStr(name, me->songnamelen, 1); - free(name); - } else - of.songname = DupStr(NULL, 0, 0); - if ((mh->MEDEXPP) && (me->annotxt) && (me->annolen)) { - _mm_fseek(modreader, me->annotxt, SEEK_SET); - ReadComment(me->annolen); - } - - if (!AllocSamples()) - return 0; - q = of.samples; - for (t = 0; t < of.numins; t++) { - q->flags = SF_SIGNED; - q->volume = 64; - if (sa[t]) { - _mm_fseek(modreader, sa[t], SEEK_SET); - s.length = _mm_read_M_ULONG(modreader); - s.type = _mm_read_M_SWORD(modreader); - - if (s.type) { -#ifdef MIKMOD_DEBUG - fprintf(stderr, "\rNon-sample instruments not supported in MED loader yet\n"); -#endif - if (!curious) { - _mm_errno = MMERR_MED_SYNTHSAMPLES; - return 0; - } - s.length = 0; - } - - if (_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - q->length = s.length; - q->seekpos = _mm_ftell(modreader); - q->loopstart = ms->sample[t].rep << 1; - q->loopend = q->loopstart + (ms->sample[t].replen << 1); - - if (ms->sample[t].replen > 1) - q->flags |= SF_LOOP; - - /* don't load sample if length>='MMD0'... - such kluges make libmikmod's code unique !!! */ - if (q->length >= MMD0_string) - q->length = 0; - } else - q->length = 0; - - if ((mh->MEDEXPP) && (me->exp_smp) && - (t < me->s_ext_entries) && (me->s_ext_entrsz >= 4)) { - MEDINSTEXT ie; - - _mm_fseek(modreader, me->exp_smp + t * me->s_ext_entrsz, - SEEK_SET); - ie.hold = _mm_read_UBYTE(modreader); - ie.decay = _mm_read_UBYTE(modreader); - ie.suppress_midi_off = _mm_read_UBYTE(modreader); - ie.finetune = _mm_read_SBYTE(modreader); - - q->speed = finetune[ie.finetune & 0xf]; - } else - q->speed = 8363; - - if ((mh->MEDEXPP) && (me->iinfo) && - (t < me->i_ext_entries) && (me->i_ext_entrsz >= 40)) { - MEDINSTINFO ii; - - _mm_fseek(modreader, me->iinfo + t * me->i_ext_entrsz, SEEK_SET); - _mm_read_UBYTES(ii.name, 40, modreader); - q->samplename = DupStr((char*)ii.name, 40, 1); - } else - q->samplename = NULL; - - q++; - } - - if (mh->id == MMD0_string) { - if (!LoadMEDPatterns()) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - } else if (mh->id == MMD1_string) { - if (!LoadMMD1Patterns()) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - } else { - _mm_errno = MMERR_NOT_A_MODULE; - return 0; - } - return 1; -} - -CHAR *MED_LoadTitle(void) -{ - ULONG posit, namelen; - CHAR *name, *retvalue = NULL; - - _mm_fseek(modreader, 0x20, SEEK_SET); - posit = _mm_read_M_ULONG(modreader); - - if (posit) { - _mm_fseek(modreader, posit + 0x2C, SEEK_SET); - posit = _mm_read_M_ULONG(modreader); - namelen = _mm_read_M_ULONG(modreader); - - _mm_fseek(modreader, posit, SEEK_SET); - name = _mm_malloc(namelen); - _mm_read_UBYTES(name, namelen, modreader); - retvalue = DupStr(name, namelen, 1); - free(name); - } - - return retvalue; -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_med = { - NULL, - "MED", - "MED (OctaMED)", - MED_Init, - MED_Test, - MED_Load, - MED_Cleanup, - MED_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_mod.c b/mikmod/load_mod.c deleted file mode 100644 index 55d284a2..00000000 --- a/mikmod/load_mod.c +++ /dev/null @@ -1,512 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Generic MOD loader (Protracker, StarTracker, FastTracker, etc) - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -typedef struct MSAMPINFO { - CHAR samplename[23]; /* 22 in module, 23 in memory */ - UWORD length; - UBYTE finetune; - UBYTE volume; - UWORD reppos; - UWORD replen; -} MSAMPINFO; - -typedef struct MODULEHEADER { - CHAR songname[21]; /* the songname.. 20 in module, 21 in memory */ - MSAMPINFO samples[31]; /* all sampleinfo */ - UBYTE songlength; /* number of patterns used */ - UBYTE magic1; /* should be 127 */ - UBYTE positions[128]; /* which pattern to play at pos */ - UBYTE magic2[4]; /* string "M.K." or "FLT4" or "FLT8" */ -} MODULEHEADER; - -typedef struct MODTYPE { - CHAR id[5]; - UBYTE channels; - CHAR *name; -} MODTYPE; - -typedef struct MODNOTE { - UBYTE a, b, c, d; -} MODNOTE; - -/*========== Loader variables */ - -#define MODULEHEADERSIZE 0x438 - -static CHAR protracker[] = "Protracker"; -static CHAR startrekker[] = "Startrekker"; -static CHAR fasttracker[] = "Fasttracker"; -static CHAR oktalyser[] = "Oktalyser"; -static CHAR oktalyzer[] = "Oktalyzer"; -static CHAR taketracker[] = "TakeTracker"; -static CHAR orpheus[] = "Imago Orpheus (MOD format)"; - -static MODULEHEADER *mh = NULL; -static MODNOTE *patbuf = NULL; -static int modtype, trekker; - -/*========== Loader code */ - -/* given the module ID, determine the number of channels and the tracker - description ; also alters modtype */ -static BOOL MOD_CheckType(UBYTE *id, UBYTE *numchn, CHAR **descr) -{ - modtype = trekker = 0; - - /* Protracker and variants */ - if ((!memcmp(id, "M.K.", 4)) || (!memcmp(id, "M!K!", 4))) { - *descr = protracker; - modtype = 0; - *numchn = 4; - return 1; - } - - /* Star Tracker */ - if (((!memcmp(id, "FLT", 3)) || (!memcmp(id, "EXO", 3))) && - (isdigit(id[3]))) { - *descr = startrekker; - modtype = trekker = 1; - *numchn = id[3] - '0'; - if (*numchn == 4 || *numchn == 8) - return 1; -#ifdef MIKMOD_DEBUG - else - fprintf(stderr, "\rUnknown FLT%d module type\n", *numchn); -#endif - return 0; - } - - /* Oktalyzer (Amiga) */ - if (!memcmp(id, "OKTA", 4)) { - *descr = oktalyzer; - modtype = 1; - *numchn = 8; - return 1; - } - - /* Oktalyser (Atari) */ - if (!memcmp(id, "CD81", 4)) { - *descr = oktalyser; - modtype = 1; - *numchn = 8; - return 1; - } - - /* Fasttracker */ - if ((!memcmp(id + 1, "CHN", 3)) && (isdigit(id[0]))) { - *descr = fasttracker; - modtype = 1; - *numchn = id[0] - '0'; - return 1; - } - /* Fasttracker or Taketracker */ - if (((!memcmp(id + 2, "CH", 2)) || (!memcmp(id + 2, "CN", 2))) - && (isdigit(id[0])) && (isdigit(id[1]))) { - if (id[3] == 'H') { - *descr = fasttracker; - modtype = 2; /* this can also be Imago Orpheus */ - } else { - *descr = taketracker; - modtype = 1; - } - *numchn = (id[0] - '0') * 10 + (id[1] - '0'); - return 1; - } - - return 0; -} - -static BOOL MOD_Test(void) -{ - UBYTE id[4], numchn; - CHAR *descr; - - _mm_fseek(modreader, MODULEHEADERSIZE, SEEK_SET); - if (!_mm_read_UBYTES(id, 4, modreader)) - return 0; - - if (MOD_CheckType(id, &numchn, &descr)) - return 1; - - return 0; -} - -static BOOL MOD_Init(void) -{ - if (!(mh = (MODULEHEADER *)_mm_malloc(sizeof(MODULEHEADER)))) - return 0; - return 1; -} - -static void MOD_Cleanup(void) -{ - _mm_free(mh); - _mm_free(patbuf); -} - -/* -Old (amiga) noteinfo: - -_____byte 1_____ byte2_ _____byte 3_____ byte4_ -/ \ / \ / \ / \ -0000 0000-00000000 0000 0000-00000000 - -Upper four 12 bits for Lower four Effect command. -bits of sam- note period. bits of sam- -ple number. ple number. - -*/ - -static UBYTE ConvertNote(MODNOTE *n, UBYTE lasteffect) -{ - UBYTE instrument, effect, effdat, note; - UWORD period; - UBYTE lastnote = 0; - - /* extract the various information from the 4 bytes that make up a note */ - instrument = (n->a & 0x10) | (n->c >> 4); - period = (((UWORD)n->a & 0xf) << 8) + n->b; - effect = n->c & 0xf; - effdat = n->d; - - /* Convert the period to a note number */ - note = 0; - if (period) { - for (note = 0; note < 7 * OCTAVE; note++) - if (period >= npertab[note]) - break; - if (note == 7 * OCTAVE) - note = 0; - else - note++; - } - - if (instrument) { - /* if instrument does not exist, note cut */ - if ((instrument > 31) || (!mh->samples[instrument - 1].length)) { - UniPTEffect(0xc, 0); - if (effect == 0xc) - effect = effdat = 0; - } else { - /* Protracker handling */ - if (!modtype) { - /* if we had a note, then change instrument... */ - if (note) - UniInstrument(instrument - 1); - /* ...otherwise, only adjust volume... */ - else { - /* ...unless an effect was specified, which forces a new - note to be played */ - if (effect || effdat) { - UniInstrument(instrument - 1); - note = lastnote; - } else - UniPTEffect(0xc, - mh->samples[instrument - - 1].volume & 0x7f); - } - } else { - /* Fasttracker handling */ - UniInstrument(instrument - 1); - if (!note) - note = lastnote; - } - } - } - if (note) { - UniNote(note + 2 * OCTAVE - 1); - lastnote = note; - } - - /* Convert pattern jump from Dec to Hex */ - if (effect == 0xd) - effdat = (((effdat & 0xf0) >> 4) * 10) + (effdat & 0xf); - - /* Volume slide, up has priority */ - if ((effect == 0xa) && (effdat & 0xf) && (effdat & 0xf0)) - effdat &= 0xf0; - - /* Handle ``heavy'' volumes correctly */ - if ((effect == 0xc) && (effdat > 0x40)) - effdat = 0x40; - - /* An isolated 100, 200 or 300 effect should be ignored (no - "standalone" porta memory in mod files). However, a sequence such - as 1XX, 100, 100, 100 is fine. */ - if ((!effdat) && ((effect == 1)||(effect == 2)||(effect ==3)) && - (lasteffect < 0x10) && (effect != lasteffect)) - effect = 0; - - UniPTEffect(effect, effdat); - if (effect == 8) - of.flags |= UF_PANNING; - - return effect; -} - -static UBYTE *ConvertTrack(MODNOTE *n, int numchn) -{ - int t; - UBYTE lasteffect = 0x10; /* non existant effect */ - - UniReset(); - for (t = 0; t < 64; t++) { - lasteffect = ConvertNote(n,lasteffect); - UniNewline(); - n += numchn; - } - return UniDup(); -} - -/* Loads all patterns of a modfile and converts them into the 3 byte format. */ -static BOOL ML_LoadPatterns(void) -{ - int t, s, tracks = 0; - - if (!AllocPatterns()) - return 0; - if (!AllocTracks()) - return 0; - - /* Allocate temporary buffer for loading and converting the patterns */ - if (!(patbuf = (MODNOTE *)_mm_calloc(64U * of.numchn, sizeof(MODNOTE)))) - return 0; - - if (trekker && of.numchn == 8) { - /* Startrekker module dual pattern */ - for (t = 0; t < of.numpat; t++) { - for (s = 0; s < (64U * 4); s++) { - patbuf[s].a = _mm_read_UBYTE(modreader); - patbuf[s].b = _mm_read_UBYTE(modreader); - patbuf[s].c = _mm_read_UBYTE(modreader); - patbuf[s].d = _mm_read_UBYTE(modreader); - } - for (s = 0; s < 4; s++) - if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4))) - return 0; - for (s = 0; s < (64U * 4); s++) { - patbuf[s].a = _mm_read_UBYTE(modreader); - patbuf[s].b = _mm_read_UBYTE(modreader); - patbuf[s].c = _mm_read_UBYTE(modreader); - patbuf[s].d = _mm_read_UBYTE(modreader); - } - for (s = 0; s < 4; s++) - if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, 4))) - return 0; - } - } else { - /* Generic module pattern */ - for (t = 0; t < of.numpat; t++) { - /* Load the pattern into the temp buffer and convert it */ - for (s = 0; s < (64U * of.numchn); s++) { - patbuf[s].a = _mm_read_UBYTE(modreader); - patbuf[s].b = _mm_read_UBYTE(modreader); - patbuf[s].c = _mm_read_UBYTE(modreader); - patbuf[s].d = _mm_read_UBYTE(modreader); - } - for (s = 0; s < of.numchn; s++) - if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s, of.numchn))) - return 0; - } - } - return 1; -} - -static BOOL MOD_Load(BOOL curious) -{ - int t, scan; - SAMPLE *q; - MSAMPINFO *s; - CHAR *descr; - - /* try to read module header */ - _mm_read_string((CHAR *)mh->songname, 20, modreader); - mh->songname[20] = 0; /* just in case */ - - for (t = 0; t < 31; t++) { - s = &mh->samples[t]; - _mm_read_string(s->samplename, 22, modreader); - s->samplename[22] = 0; /* just in case */ - s->length = _mm_read_M_UWORD(modreader); - s->finetune = _mm_read_UBYTE(modreader); - s->volume = _mm_read_UBYTE(modreader); - s->reppos = _mm_read_M_UWORD(modreader); - s->replen = _mm_read_M_UWORD(modreader); - } - - mh->songlength = _mm_read_UBYTE(modreader); - - /* this fixes mods which declare more than 128 positions. - * eg: beatwave.mod */ - if (mh->songlength > 128) { mh->songlength = 128; } - - mh->magic1 = _mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->positions, 128, modreader); - _mm_read_UBYTES(mh->magic2, 4, modreader); - - if (_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - of.initspeed = 6; - of.inittempo = 125; - if (!(MOD_CheckType(mh->magic2, &of.numchn, &descr))) { - _mm_errno = MMERR_NOT_A_MODULE; - return 0; - } - if (trekker && of.numchn == 8) - for (t = 0; t < 128; t++) - /* if module pretends to be FLT8, yet the order table - contains odd numbers, chances are it's a lying FLT4... */ - if (mh->positions[t] & 1) { - of.numchn = 4; - break; - } - if (trekker && of.numchn == 8) - for (t = 0; t < 128; t++) - mh->positions[t] >>= 1; - - of.songname = DupStr(mh->songname, 21, 1); - of.numpos = mh->songlength; - of.reppos = 0; - - /* Count the number of patterns */ - of.numpat = 0; - for (t = 0; t < of.numpos; t++) - if (mh->positions[t] > of.numpat) - of.numpat = mh->positions[t]; - - /* since some old modules embed extra patterns, we have to check the - whole list to get the samples' file offsets right - however we can find - garbage here, so check carefully */ - scan = 1; - for (t = of.numpos; t < 128; t++) - if (mh->positions[t] >= 0x80) - scan = 0; - if (scan) - for (t = of.numpos; t < 128; t++) { - if (mh->positions[t] > of.numpat) - of.numpat = mh->positions[t]; - if ((curious) && (mh->positions[t])) - of.numpos = t + 1; - } - of.numpat++; - of.numtrk = of.numpat * of.numchn; - - if (!AllocPositions(of.numpos)) - return 0; - for (t = 0; t < of.numpos; t++) - of.positions[t] = mh->positions[t]; - - /* Finally, init the sampleinfo structures */ - of.numins = of.numsmp = 31; - if (!AllocSamples()) - return 0; - s = mh->samples; - q = of.samples; - for (t = 0; t < of.numins; t++) { - /* convert the samplename */ - q->samplename = DupStr(s->samplename, 23, 1); - /* init the sampleinfo variables and convert the size pointers */ - q->speed = finetune[s->finetune & 0xf]; - q->volume = s->volume & 0x7f; - q->loopstart = (ULONG)s->reppos << 1; - q->loopend = q->loopstart + ((ULONG)s->replen << 1); - q->length = (ULONG)s->length << 1; - q->flags = SF_SIGNED; - /* Imago Orpheus creates MODs with 16 bit samples, check */ - if ((modtype == 2) && (s->volume & 0x80)) { - q->flags |= SF_16BITS; - descr = orpheus; - } - if (s->replen > 2) - q->flags |= SF_LOOP; - - s++; - q++; - } - - of.modtype = strdup(descr); - - if (!ML_LoadPatterns()) - return 0; - - return 1; -} - -static CHAR *MOD_LoadTitle(void) -{ - CHAR s[21]; - - _mm_fseek(modreader, 0, SEEK_SET); - if (!_mm_read_UBYTES(s, 20, modreader)) - return NULL; - s[20] = 0; /* just in case */ - - return (DupStr(s, 21, 1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_mod = { - NULL, - "Standard module", - "MOD (31 instruments)", - MOD_Init, - MOD_Test, - MOD_Load, - MOD_Cleanup, - MOD_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_mtm.c b/mikmod/load_mtm.c deleted file mode 100644 index 032962d0..00000000 --- a/mikmod/load_mtm.c +++ /dev/null @@ -1,285 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_mtm.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - MTM module loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -typedef struct MTMHEADER { - UBYTE id[3]; /* MTM file marker */ - UBYTE version; /* upper major, lower nibble minor version number */ - CHAR songname[20]; /* ASCIIZ songname */ - UWORD numtracks; /* number of tracks saved */ - UBYTE lastpattern; /* last pattern number saved */ - UBYTE lastorder; /* last order number to play (songlength-1) */ - UWORD commentsize; /* length of comment field */ - UBYTE numsamples; /* number of samples saved */ - UBYTE attribute; /* attribute byte (unused) */ - UBYTE beatspertrack; - UBYTE numchannels; /* number of channels used */ - UBYTE panpos[32]; /* voice pan positions */ -} MTMHEADER; - -typedef struct MTMSAMPLE { - CHAR samplename[22]; - ULONG length; - ULONG reppos; - ULONG repend; - UBYTE finetune; - UBYTE volume; - UBYTE attribute; -} MTMSAMPLE; - -typedef struct MTMNOTE { - UBYTE a,b,c; -} MTMNOTE; - -/*========== Loader variables */ - -static MTMHEADER *mh = NULL; -static MTMNOTE *mtmtrk = NULL; -static UWORD pat[32]; - -static CHAR MTM_Version[] = "MTM"; - -/*========== Loader code */ - -BOOL MTM_Test(void) -{ - UBYTE id[3]; - - if(!_mm_read_UBYTES(id,3,modreader)) return 0; - if(!memcmp(id,"MTM",3)) return 1; - return 0; -} - -BOOL MTM_Init(void) -{ - if(!(mtmtrk=(MTMNOTE*)_mm_calloc(64,sizeof(MTMNOTE)))) return 0; - if(!(mh=(MTMHEADER*)_mm_malloc(sizeof(MTMHEADER)))) return 0; - - return 1; -} - -void MTM_Cleanup(void) -{ - _mm_free(mtmtrk); - _mm_free(mh); -} - -static UBYTE* MTM_Convert(void) -{ - int t; - UBYTE a,b,inst,note,eff,dat; - - UniReset(); - for(t=0;t<64;t++) { - a=mtmtrk[t].a; - b=mtmtrk[t].b; - inst=((a&0x3)<<4)|(b>>4); - note=a>>2; - eff=b&0xf; - dat=mtmtrk[t].c; - - if(inst) UniInstrument(inst-1); - if(note) UniNote(note+2*OCTAVE); - - /* MTM bug workaround : when the effect is volslide, slide-up *always* - overrides slide-down. */ - if(eff==0xa && (dat&0xf0)) dat&=0xf0; - - /* Convert pattern jump from Dec to Hex */ - if(eff==0xd) - dat=(((dat&0xf0)>>4)*10)+(dat&0xf); - UniPTEffect(eff,dat); - UniNewline(); - } - return UniDup(); -} - -BOOL MTM_Load(BOOL curious) -{ - int t,u; - MTMSAMPLE s; - SAMPLE *q; - - /* try to read module header */ - _mm_read_UBYTES(mh->id,3,modreader); - mh->version =_mm_read_UBYTE(modreader); - _mm_read_string(mh->songname,20,modreader); - mh->numtracks =_mm_read_I_UWORD(modreader); - mh->lastpattern =_mm_read_UBYTE(modreader); - mh->lastorder =_mm_read_UBYTE(modreader); - mh->commentsize =_mm_read_I_UWORD(modreader); - mh->numsamples =_mm_read_UBYTE(modreader); - mh->attribute =_mm_read_UBYTE(modreader); - mh->beatspertrack=_mm_read_UBYTE(modreader); - mh->numchannels =_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->panpos,32,modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - of.initspeed = 6; - of.inittempo = 125; - of.modtype = strdup(MTM_Version); - of.numchn = mh->numchannels; - of.numtrk = mh->numtracks+1; /* get number of channels */ - of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */ - of.numpos = mh->lastorder+1; /* copy the songlength */ - of.numpat = mh->lastpattern+1; - of.reppos = 0; - of.flags |= UF_PANNING; - for(t=0;t<32;t++) of.panning[t]=mh->panpos[t]<< 4; - of.numins=of.numsmp=mh->numsamples; - - if(!AllocSamples()) return 0; - q=of.samples; - for(t=0;tsamplename = DupStr(s.samplename,22,1); - q->seekpos = 0; - q->speed = finetune[s.finetune]; - q->length = s.length; - q->loopstart = s.reppos; - q->loopend = s.repend; - q->volume = s.volume; - if((s.repend-s.reppos)>2) q->flags |= SF_LOOP; - - if(s.attribute&1) { - /* If the sample is 16-bits, convert the length and replen - byte-values into sample-values */ - q->flags|=SF_16BITS; - q->length>>=1; - q->loopstart>>=1; - q->loopend>>=1; - } - q++; - } - - if(!AllocPositions(of.numpos)) return 0; - for(t=0;tcommentsize) - if(!ReadLinedComment(mh->commentsize, 40)) return 0; - - return 1; -} - -CHAR *MTM_LoadTitle(void) -{ - CHAR s[20]; - - _mm_fseek(modreader,4,SEEK_SET); - if(!_mm_read_UBYTES(s,20,modreader)) return NULL; - - return(DupStr(s,20,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_mtm={ - NULL, - "MTM", - "MTM (MultiTracker Module editor)", - MTM_Init, - MTM_Test, - MTM_Load, - MTM_Cleanup, - MTM_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_okt.c b/mikmod/load_okt.c deleted file mode 100644 index 8763a0eb..00000000 --- a/mikmod/load_okt.c +++ /dev/null @@ -1,460 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_okt.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - Oktalyzer (OKT) module loader - -==============================================================================*/ - -/* - Written by UFO - based on the file description compiled by Harald Zappe - - -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module blocks */ - -/* sample information */ -typedef struct OKTSAMPLE { - CHAR sampname[20]; - ULONG len; - UWORD loopbeg; - UWORD looplen; - UBYTE volume; -} OKTSAMPLE; - -typedef struct OKTNOTE { - UBYTE note, ins, eff, dat; -} OKTNOTE; - -/*========== Loader variables */ - -static OKTNOTE *okttrk = NULL; - -/*========== Loader code */ - -BOOL OKT_Test(void) -{ - CHAR id[8]; - - if (!_mm_read_UBYTES(id, 8, modreader)) - return 0; - if (!memcmp(id, "OKTASONG", 8)) - return 1; - - return 0; -} - -/* Pattern analysis routine. - Effects not implemented (yet) : (in decimal) - 11 Arpeggio 4: Change note every 50Hz tick between N,H,N,L - 12 Arpeggio 5: Change note every 50Hz tick between H,H,N - N = normal note being played in this channel (1-36) - L = normal note number minus upper four bits of 'data'. - H = normal note number plus lower four bits of 'data'. - 13 Decrease note number by 'data' once per tick. - 17 Increase note number by 'data' once per tick. - 21 Decrease note number by 'data' once per line. - 30 Increase note number by 'data' once per line. -*/ -static UBYTE *OKT_ConvertTrack(UBYTE patrows) -{ - int t; - UBYTE ins, note, eff, dat; - - UniReset(); - for (t = 0; t < patrows; t++) { - note = okttrk[t].note; - ins = okttrk[t].ins; - eff = okttrk[t].eff; - dat = okttrk[t].dat; - - if (note) { - UniNote(note + 3 * OCTAVE - 1); - UniInstrument(ins); - } - - if (eff) - switch (eff) { - case 1: /* Porta Up */ - UniPTEffect(0x1, dat); - break; - case 2: /* Portamento Down */ - UniPTEffect(0x2, dat); - break; - /* case 9: what is this? */ - case 10: /* Arpeggio 3 */ - case 11: /* Arpeggio 4 */ - case 12: /* Arpeggio 5 */ - UniWriteByte(UNI_OKTARP); - UniWriteByte(eff + 3 - 10); - UniWriteByte(dat); - break; - case 15: /* Amiga filter toggle, ignored */ - break; - case 25: /* Pattern Jump */ - dat = (dat >> 4) * 10 + (dat & 0x0f); - UniPTEffect(0xb, dat); - break; - case 27: /* Release - similar to Keyoff */ - UniWriteByte(UNI_KEYOFF); - break; - case 28: /* Set Tempo */ - UniPTEffect(0xf, dat & 0x0f); - break; - case 31: /* volume Control */ - if (dat <= 0x40) - UniPTEffect(0xc, dat); - else if (dat <= 0x50) - UniEffect(UNI_XMEFFECTA, (dat - 0x40)); /* fast fade out */ - else if (dat <= 0x60) - UniEffect(UNI_XMEFFECTA, (dat - 0x50) << 4); /* fast fade in */ - else if (dat <= 0x70) - UniEffect(UNI_XMEFFECTEB, (dat - 0x60)); /* slow fade out */ - else if (dat <= 0x80) - UniEffect(UNI_XMEFFECTEA, (dat - 0x70)); /* slow fade in */ - break; -#ifdef MIKMOD_DEBUG - default: - fprintf(stderr, "\rUnimplemented effect (%02d,%02x)\n", - eff, dat); -#endif - } - - UniNewline(); - } - return UniDup(); -} - -/* Read "channel modes" i.e. channel number and panning information */ -static void OKT_doCMOD(void) -{ - /* amiga channel panning table */ - UBYTE amigapan[4] = { 0x00, 0xff, 0xff, 0x00 }; - int t; - - of.numchn = 0; - of.flags |= UF_PANNING; - - for (t = 0; t < 4; t++) - if (_mm_read_M_UWORD(modreader)) { - /* two channels tied to the same Amiga hardware voice */ - of.panning[of.numchn++] = amigapan[t]; - of.panning[of.numchn++] = amigapan[t]; - } else - /* one channel tied to the Amiga hardware voice */ - of.panning[of.numchn++] = amigapan[t]; -} - -/* Read sample information */ -static BOOL OKT_doSAMP(int len) -{ - int t; - SAMPLE *q; - OKTSAMPLE s; - - of.numins = of.numsmp = (len / 0x20); - if (!AllocSamples()) - return 0; - - for (t = 0, q = of.samples; t < of.numins; t++, q++) { - _mm_read_UBYTES(s.sampname, 20, modreader); - s.len = _mm_read_M_ULONG(modreader); - s.loopbeg = _mm_read_M_UWORD(modreader) * 2; - s.looplen = _mm_read_M_UWORD(modreader) * 2; - _mm_read_UBYTE(modreader); - s.volume = _mm_read_UBYTE(modreader); - _mm_read_M_UWORD(modreader); - - if (_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - if (!s.len) - q->seekpos = q->length = q->loopstart = q->loopend = q->flags = 0; - else { - s.len--; - /* sanity checks */ - if (s.loopbeg > s.len) - s.loopbeg = s.len; - if (s.loopbeg + s.looplen > s.len) - s.looplen = s.len - s.loopbeg; - if (s.looplen < 2) - s.looplen = 0; - - q->length = s.len; - q->loopstart = s.loopbeg; - q->loopend = s.looplen + q->loopstart; - q->volume = s.volume; - q->flags = SF_SIGNED; - - if (s.looplen) - q->flags |= SF_LOOP; - } - q->samplename = DupStr(s.sampname, 20, 1); - q->speed = 8287; - } - return 1; -} - -/* Read speed information */ -static void OKT_doSPEE(void) -{ - int tempo = _mm_read_M_UWORD(modreader); - - of.initspeed = tempo; -} - -/* Read song length information */ -static void OKT_doSLEN(void) -{ - of.numpat = _mm_read_M_UWORD(modreader); -} - -/* Read pattern length information */ -static void OKT_doPLEN(void) -{ - of.numpos = _mm_read_M_UWORD(modreader); -} - -/* Read order table */ -static BOOL OKT_doPATT(void) -{ - int t; - - if (!of.numpos || !AllocPositions(of.numpos)) - return 0; - - for (t = 0; t < 128; t++) - if (t < of.numpos) - of.positions[t] = _mm_read_UBYTE(modreader); - else - break; - - return 1; -} - -static BOOL OKT_doPBOD(int patnum) -{ - char *patbuf; - int rows, i; - int u; - - if (!patnum) { - of.numtrk = of.numpat * of.numchn; - - if (!AllocTracks() || !AllocPatterns()) - return 0; - } - - /* Read pattern */ - of.pattrows[patnum] = rows = _mm_read_M_UWORD(modreader); - - if (!(okttrk = (OKTNOTE *) _mm_calloc(rows, sizeof(OKTNOTE))) || - !(patbuf = (char *)_mm_calloc(rows * of.numchn, sizeof(OKTNOTE)))) - return 0; - _mm_read_UBYTES(patbuf, rows * of.numchn * sizeof(OKTNOTE), modreader); - if (_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - - for (i = 0; i < of.numchn; i++) { - for (u = 0; u < rows; u++) { - okttrk[u].note = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE)]; - okttrk[u].ins = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 1]; - okttrk[u].eff = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 2]; - okttrk[u].dat = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 3]; - } - - if (!(of.tracks[patnum * of.numchn + i] = OKT_ConvertTrack(rows))) - return 0; - } - _mm_free(patbuf); - _mm_free(okttrk); - return 1; -} - -static void OKT_doSBOD(int insnum) -{ - of.samples[insnum].seekpos = _mm_ftell(modreader); -} - -BOOL OKT_Load(BOOL curious) -{ - UBYTE id[4]; - ULONG len; - ULONG fp; - BOOL seen_cmod = 0, seen_samp = 0, seen_slen = 0, seen_plen = 0, seen_patt - = 0, seen_spee = 0; - int patnum = 0, insnum = 0; - - /* skip OKTALYZER header */ - _mm_fseek(modreader, 8, SEEK_SET); - of.songname = strdup(""); - - of.modtype = strdup("Amiga Oktalyzer"); - of.numpos = of.reppos = 0; - - /* default values */ - of.initspeed = 6; - of.inittempo = 125; - - while (1) { - /* read block header */ - _mm_read_UBYTES(id, 4, modreader); - len = _mm_read_M_ULONG(modreader); - - if (_mm_eof(modreader)) - break; - fp = _mm_ftell(modreader); - - if (!memcmp(id, "CMOD", 4)) { - if (!seen_cmod) { - OKT_doCMOD(); - seen_cmod = 1; - } else { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - } else if (!memcmp(id, "SAMP", 4)) { - if (!seen_samp && OKT_doSAMP(len)) - seen_samp = 1; - else { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - } else if (!memcmp(id, "SPEE", 4)) { - if (!seen_spee) { - OKT_doSPEE(); - seen_spee = 1; - } else { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - } else if (!memcmp(id, "SLEN", 4)) { - if (!seen_slen) { - OKT_doSLEN(); - seen_slen = 1; - } else { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - } else if (!memcmp(id, "PLEN", 4)) { - if (!seen_plen) { - OKT_doPLEN(); - seen_plen = 1; - } else { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - } else if (!memcmp(id, "PATT", 4)) { - if (!seen_plen) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - if (!seen_patt && OKT_doPATT()) - seen_patt = 1; - else { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - } else if (!memcmp(id,"PBOD", 4)) { - /* need to know numpat and numchn */ - if (!seen_slen || !seen_cmod || (patnum >= of.numpat)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - if (!OKT_doPBOD(patnum++)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - } else if (!memcmp(id,"SBOD",4)) { - /* need to know numsmp */ - if (!seen_samp) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - while ((insnum < of.numins) && !of.samples[insnum].length) - insnum++; - if (insnum >= of.numins) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - OKT_doSBOD(insnum++); - } - - /* goto next block start position */ - _mm_fseek(modreader, fp + len, SEEK_SET); - } - - if (!seen_cmod || !seen_samp || !seen_patt || - !seen_slen || !seen_plen || (patnum != of.numpat)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - return 1; -} - -CHAR *OKT_LoadTitle(void) -{ - return strdup(""); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_okt = { - NULL, - "OKT", - "OKT (Amiga Oktalyzer)", - NULL, - OKT_Test, - OKT_Load, - NULL, - OKT_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/load_s3m.c b/mikmod/load_s3m.c deleted file mode 100644 index 66f53b71..00000000 --- a/mikmod/load_s3m.c +++ /dev/null @@ -1,470 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Screamtracker (S3M) module loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -/* header */ -typedef struct S3MHEADER { - CHAR songname[28]; - UBYTE t1a; - UBYTE type; - UBYTE unused1[2]; - UWORD ordnum; - UWORD insnum; - UWORD patnum; - UWORD flags; - UWORD tracker; - UWORD fileformat; - CHAR scrm[4]; - UBYTE mastervol; - UBYTE initspeed; - UBYTE inittempo; - UBYTE mastermult; - UBYTE ultraclick; - UBYTE pantable; - UBYTE unused2[8]; - UWORD special; - UBYTE channels[32]; -} S3MHEADER; - -/* sample information */ -typedef struct S3MSAMPLE { - UBYTE type; - CHAR filename[12]; - UBYTE memsegh; - UWORD memsegl; - ULONG length; - ULONG loopbeg; - ULONG loopend; - UBYTE volume; - UBYTE dsk; - UBYTE pack; - UBYTE flags; - ULONG c2spd; - UBYTE unused[12]; - CHAR sampname[28]; - CHAR scrs[4]; -} S3MSAMPLE; - -typedef struct S3MNOTE { - UBYTE note,ins,vol,cmd,inf; -} S3MNOTE; - -/*========== Loader variables */ - -static S3MNOTE *s3mbuf = NULL; /* pointer to a complete S3M pattern */ -static S3MHEADER *mh = NULL; -static UWORD *paraptr = NULL; /* parapointer array (see S3M docs) */ -static unsigned int tracker; /* tracker id */ - -/* tracker identifiers */ -#define NUMTRACKERS 4 -static CHAR* S3M_Version[] = { - "Screamtracker x.xx", - "Imago Orpheus x.xx (S3M format)", - "Impulse Tracker x.xx (S3M format)", - "Unknown tracker x.xx (S3M format)", - "Impulse Tracker 2.14p3 (S3M format)", - "Impulse Tracker 2.14p4 (S3M format)" -}; -/* version number position in above array */ -static int numeric[NUMTRACKERS]={14,14,16,16}; - -/*========== Loader code */ - -BOOL S3M_Test(void) -{ - UBYTE id[4]; - - _mm_fseek(modreader,0x2c,SEEK_SET); - if(!_mm_read_UBYTES(id,4,modreader)) return 0; - if(!memcmp(id,"SCRM",4)) return 1; - return 0; -} - -BOOL S3M_Init(void) -{ - if(!(s3mbuf=(S3MNOTE*)_mm_malloc(32*64*sizeof(S3MNOTE)))) return 0; - if(!(mh=(S3MHEADER*)_mm_malloc(sizeof(S3MHEADER)))) return 0; - if(!(poslookup=(UBYTE*)_mm_malloc(sizeof(UBYTE)*256))) return 0; - memset(poslookup,-1,256); - - return 1; -} - -void S3M_Cleanup(void) -{ - _mm_free(s3mbuf); - _mm_free(paraptr); - _mm_free(poslookup); - _mm_free(mh); - _mm_free(origpositions); -} - -/* Because so many s3m files have 16 channels as the set number used, but really - only use far less (usually 8 to 12 still), I had to make this function, which - determines the number of channels that are actually USED by a pattern. - - For every channel that's used, it sets the appropriate array entry of the - global variable 'remap' - - NOTE: You must first seek to the file location of the pattern before calling - this procedure. - - Returns 1 on fail. */ -static BOOL S3M_GetNumChannels(void) -{ - int row=0,flag,ch; - - while(row<64) { - flag=_mm_read_UBYTE(modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 1; - } - - if(flag) { - ch=flag&31; - if(mh->channels[ch]<32) remap[ch] = 0; - if(flag&32) {_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);} - if(flag&64) _mm_read_UBYTE(modreader); - if(flag&128){_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);} - } else row++; - } - return 0; -} - -static BOOL S3M_ReadPattern(void) -{ - int row=0,flag,ch; - S3MNOTE *n,dummy; - - /* clear pattern data */ - memset(s3mbuf,255,32*64*sizeof(S3MNOTE)); - - while(row<64) { - flag=_mm_read_UBYTE(modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_PATTERN; - return 0; - } - - if(flag) { - ch=remap[flag&31]; - - if(ch!=-1) - n=&s3mbuf[(64U*ch)+row]; - else - n=&dummy; - - if(flag&32) { - n->note=_mm_read_UBYTE(modreader); - n->ins=_mm_read_UBYTE(modreader); - } - if(flag&64) { - n->vol=_mm_read_UBYTE(modreader); - if (n->vol>64) n->vol=64; - } - if(flag&128) { - n->cmd=_mm_read_UBYTE(modreader); - n->inf=_mm_read_UBYTE(modreader); - } - } else row++; - } - return 1; -} - -static UBYTE* S3M_ConvertTrack(S3MNOTE* tr) -{ - int t; - - UniReset(); - for(t=0;t<64;t++) { - UBYTE note,ins,vol; - - note=tr[t].note; - ins=tr[t].ins; - vol=tr[t].vol; - - if((ins)&&(ins!=255)) UniInstrument(ins-1); - if(note!=255) { - if(note==254) { - UniPTEffect(0xc,0); /* note cut command */ - vol=255; - } else - UniNote(((note>>4)*OCTAVE)+(note&0xf)); /* normal note */ - } - if(vol<255) UniPTEffect(0xc,vol); - - S3MIT_ProcessCmd(tr[t].cmd,tr[t].inf, - tracker == 1 ? S3MIT_OLDSTYLE | S3MIT_SCREAM : S3MIT_OLDSTYLE); - UniNewline(); - } - return UniDup(); -} - -BOOL S3M_Load(BOOL curious) -{ - int t,u,track = 0; - SAMPLE *q; - UBYTE pan[32]; - - /* try to read module header */ - _mm_read_string(mh->songname,28,modreader); - mh->t1a =_mm_read_UBYTE(modreader); - mh->type =_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->unused1,2,modreader); - mh->ordnum =_mm_read_I_UWORD(modreader); - mh->insnum =_mm_read_I_UWORD(modreader); - mh->patnum =_mm_read_I_UWORD(modreader); - mh->flags =_mm_read_I_UWORD(modreader); - mh->tracker =_mm_read_I_UWORD(modreader); - mh->fileformat =_mm_read_I_UWORD(modreader); - _mm_read_string(mh->scrm,4,modreader); - mh->mastervol =_mm_read_UBYTE(modreader); - mh->initspeed =_mm_read_UBYTE(modreader); - mh->inittempo =_mm_read_UBYTE(modreader); - mh->mastermult =_mm_read_UBYTE(modreader); - mh->ultraclick =_mm_read_UBYTE(modreader); - mh->pantable =_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->unused2,8,modreader); - mh->special =_mm_read_I_UWORD(modreader); - _mm_read_UBYTES(mh->channels,32,modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* then we can decide the module type */ - tracker=mh->tracker>>12; - if((!tracker)||(tracker>=NUMTRACKERS)) - tracker=NUMTRACKERS-1; /* unknown tracker */ - else { - if(mh->tracker>=0x3217) - tracker=NUMTRACKERS+1; /* IT 2.14p4 */ - else if(mh->tracker>=0x3216) - tracker=NUMTRACKERS; /* IT 2.14p3 */ - else tracker--; - } - of.modtype = strdup(S3M_Version[tracker]); - if(trackertracker>>8) &0xf)+'0'; - of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0'; - of.modtype[numeric[tracker]+3] = ((mh->tracker)&0xf)+'0'; - } - /* set module variables */ - of.songname = DupStr(mh->songname,28,0); - of.numpat = mh->patnum; - of.reppos = 0; - of.numins = of.numsmp = mh->insnum; - of.initspeed = mh->initspeed; - of.inittempo = mh->inittempo; - of.initvolume = mh->mastervol<<1; - of.flags |= UF_ARPMEM | UF_PANNING; - if((mh->tracker==0x1300)||(mh->flags&64)) - of.flags|=UF_S3MSLIDES; - of.bpmlimit = 32; - - /* read the order data */ - if(!AllocPositions(mh->ordnum)) return 0; - if(!(origpositions=_mm_calloc(mh->ordnum,sizeof(UWORD)))) return 0; - - for(t=0;tordnum;t++) { - origpositions[t]=_mm_read_UBYTE(modreader); - if((origpositions[t]>=mh->patnum)&&(origpositions[t]<254)) - origpositions[t]=255/*mh->patnum-1*/; - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - poslookupcnt=mh->ordnum; - S3MIT_CreateOrders(curious); - - if(!(paraptr=(UWORD*)_mm_malloc((of.numins+of.numpat)*sizeof(UWORD)))) - return 0; - - /* read the instrument+pattern parapointers */ - _mm_read_I_UWORDS(paraptr,of.numins+of.numpat,modreader); - - if(mh->pantable==252) { - /* read the panning table (ST 3.2 addition. See below for further - portions of channel panning [past reampper]). */ - _mm_read_UBYTES(pan,32,modreader); - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* load samples */ - if(!AllocSamples()) return 0; - q = of.samples; - for(t=0;t 64000) - s.length = 64000; - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - q->samplename = DupStr(s.sampname,28,0); - q->speed = s.c2spd; - q->length = s.length; - q->loopstart = s.loopbeg; - q->loopend = s.loopend; - q->volume = s.volume; - q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4; - - if(s.flags&1) q->flags |= SF_LOOP; - if(s.flags&4) q->flags |= SF_16BITS; - if(mh->fileformat==1) q->flags |= SF_SIGNED; - - /* don't load sample if it doesn't have the SCRS tag */ - if(memcmp(s.scrs,"SCRS",4)) q->length = 0; - - q++; - } - - /* determine the number of channels actually used. */ - of.numchn = 0; - memset(remap,-1,32*sizeof(UBYTE)); - for(t=0;tchannels[t]<32)&&(remap[t]!=-1)) { - if(mh->channels[t]<8) - of.panning[remap[t]]=0x30; - else - of.panning[remap[t]]=0xc0; - } - if(mh->pantable==252) - /* set panning positions according to panning table (new for st3.2) */ - for(t=0;t<32;t++) - if((pan[t]&0x20)&&(mh->channels[t]<32)&&(remap[t]!=-1)) - of.panning[remap[t]]=(pan[t]&0xf)<<4; - - /* load pattern info */ - of.numtrk=of.numpat*of.numchn; - if(!AllocTracks()) return 0; - if(!AllocPatterns()) return 0; - - for(t=0;t -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -/* sample information */ -typedef struct STMSAMPLE { - CHAR filename[12]; - UBYTE unused; /* 0x00 */ - UBYTE instdisk; /* Instrument disk */ - UWORD reserved; - UWORD length; /* Sample length */ - UWORD loopbeg; /* Loop start point */ - UWORD loopend; /* Loop end point */ - UBYTE volume; /* Volume */ - UBYTE reserved2; - UWORD c2spd; /* Good old c2spd */ - ULONG reserved3; - UWORD isa; -} STMSAMPLE; - -/* header */ -typedef struct STMHEADER { - CHAR songname[20]; - CHAR trackername[8]; /* !Scream! for ST 2.xx */ - UBYTE unused; /* 0x1A */ - UBYTE filetype; /* 1=song, 2=module */ - UBYTE ver_major; - UBYTE ver_minor; - UBYTE inittempo; /* initspeed= stm inittempo>>4 */ - UBYTE numpat; /* number of patterns */ - UBYTE globalvol; - UBYTE reserved[13]; - STMSAMPLE sample[31]; /* STM sample data */ - UBYTE patorder[128]; /* Docs say 64 - actually 128 */ -} STMHEADER; - -typedef struct STMNOTE { - UBYTE note,insvol,volcmd,cmdinf; -} STMNOTE; - -/*========== Loader variables */ - -static STMNOTE *stmbuf = NULL; -static STMHEADER *mh = NULL; - -/* tracker identifiers */ -static CHAR* STM_Version[STM_NTRACKERS] = { - "Screamtracker 2", - "Converted by MOD2STM (STM format)", - "Wuzamod (STM format)" -}; - -/*========== Loader code */ - -BOOL STM_Test(void) -{ - UBYTE str[44]; - int t; - - _mm_fseek(modreader,20,SEEK_SET); - _mm_read_UBYTES(str,44,modreader); - if(str[9]!=2) return 0; /* STM Module = filetype 2 */ - - /* Prevent false positives for S3M files */ - if(!memcmp(str+40,"SCRM",4)) - return 0; - - for (t=0;tnote; - ins = n->insvol>>3; - vol = (n->insvol&7)+((n->volcmd&0x70)>>1); - cmd = n->volcmd&15; - inf = n->cmdinf; - - if((ins)&&(ins<32)) UniInstrument(ins-1); - - /* special values of [SBYTE0] are handled here - we have no idea if these strange values will ever be encountered. - but it appears as those stms sound correct. */ - if((note==254)||(note==252)) { - UniPTEffect(0xc,0); /* note cut */ - n->volcmd|=0x80; - } else - /* if note < 251, then all three bytes are stored in the file */ - if(note<251) UniNote((((note>>4)+2)*OCTAVE)+(note&0xf)); - - if((!(n->volcmd&0x80))&&(vol<65)) UniPTEffect(0xc,vol); - if(cmd!=255) - switch(cmd) { - case 1: /* Axx set speed to xx */ - UniPTEffect(0xf,inf>>4); - break; - case 2: /* Bxx position jump */ - UniPTEffect(0xb,inf); - break; - case 3: /* Cxx patternbreak to row xx */ - UniPTEffect(0xd,(((inf&0xf0)>>4)*10)+(inf&0xf)); - break; - case 4: /* Dxy volumeslide */ - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 5: /* Exy toneslide down */ - UniEffect(UNI_S3MEFFECTE,inf); - break; - case 6: /* Fxy toneslide up */ - UniEffect(UNI_S3MEFFECTF,inf); - break; - case 7: /* Gxx Tone portamento,speed xx */ - UniPTEffect(0x3,inf); - break; - case 8: /* Hxy vibrato */ - UniPTEffect(0x4,inf); - break; - case 9: /* Ixy tremor, ontime x, offtime y */ - UniEffect(UNI_S3MEFFECTI,inf); - break; - case 0: /* protracker arpeggio */ - if(!inf) break; - /* fall through */ - case 0xa: /* Jxy arpeggio */ - UniPTEffect(0x0,inf); - break; - case 0xb: /* Kxy Dual command H00 & Dxy */ - UniPTEffect(0x4,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 0xc: /* Lxy Dual command G00 & Dxy */ - UniPTEffect(0x3,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - /* Support all these above, since ST2 can LOAD these values but can - actually only play up to J - and J is only half-way implemented - in ST2 */ - case 0x18: /* Xxx amiga panning command 8xx */ - UniPTEffect(0x8,inf); - of.flags |= UF_PANNING; - break; - } -} - -static UBYTE *STM_ConvertTrack(STMNOTE *n) -{ - int t; - - UniReset(); - for(t=0;t<64;t++) { - STM_ConvertNote(n); - UniNewline(); - n+=of.numchn; - } - return UniDup(); -} - -static BOOL STM_LoadPatterns(void) -{ - int t,s,tracks=0; - - if(!AllocPatterns()) return 0; - if(!AllocTracks()) return 0; - - /* Allocate temporary buffer for loading and converting the patterns */ - for(t=0;tsongname,20,modreader); - _mm_read_string(mh->trackername,8,modreader); - mh->unused =_mm_read_UBYTE(modreader); - mh->filetype =_mm_read_UBYTE(modreader); - mh->ver_major =_mm_read_UBYTE(modreader); - mh->ver_minor =_mm_read_UBYTE(modreader); - mh->inittempo =_mm_read_UBYTE(modreader); - if(!mh->inittempo) { - _mm_errno=MMERR_NOT_A_MODULE; - return 0; - } - mh->numpat =_mm_read_UBYTE(modreader); - mh->globalvol =_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh->reserved,13,modreader); - - for(t=0;t<31;t++) { - STMSAMPLE *s=&mh->sample[t]; /* STM sample data */ - - _mm_read_string(s->filename,12,modreader); - s->unused =_mm_read_UBYTE(modreader); - s->instdisk =_mm_read_UBYTE(modreader); - s->reserved =_mm_read_I_UWORD(modreader); - s->length =_mm_read_I_UWORD(modreader); - s->loopbeg =_mm_read_I_UWORD(modreader); - s->loopend =_mm_read_I_UWORD(modreader); - s->volume =_mm_read_UBYTE(modreader); - s->reserved2=_mm_read_UBYTE(modreader); - s->c2spd =_mm_read_I_UWORD(modreader); - s->reserved3=_mm_read_I_ULONG(modreader); - s->isa =_mm_read_I_UWORD(modreader); - } - _mm_read_UBYTES(mh->patorder,128,modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - for(t=0;ttrackername,STM_Signatures[t],8)) break; - of.modtype = strdup(STM_Version[t]); - of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */ - of.numpat = mh->numpat; - of.inittempo = 125; /* mh->inittempo+0x1c; */ - of.initspeed = mh->inittempo>>4; - of.numchn = 4; /* get number of channels */ - of.reppos = 0; - of.flags |= UF_S3MSLIDES; - of.bpmlimit = 32; - - t=0; - if(!AllocPositions(0x80)) return 0; - /* 99 terminates the patorder list */ - while((mh->patorder[t]<=99)&&(mh->patorder[t]numpat)) { - of.positions[t]=mh->patorder[t]; - t++; - } - if(mh->patorder[t]<=99) t++; - of.numpos=t; - of.numtrk=of.numpat*of.numchn; - of.numins=of.numsmp=31; - - if(!AllocSamples()) return 0; - if(!STM_LoadPatterns()) return 0; - MikMod_ISA=_mm_ftell(modreader); - MikMod_ISA=(MikMod_ISA+15)&0xfffffff0; /* normalize */ - - for(q=of.samples,t=0;tsamplename = DupStr(mh->sample[t].filename,12,1); - q->speed = (mh->sample[t].c2spd * 8363) / 8448; - q->volume = mh->sample[t].volume; - q->length = mh->sample[t].length; - if (/*(!mh->sample[t].volume)||*/(q->length==1)) q->length=0; - q->loopstart = mh->sample[t].loopbeg; - q->loopend = mh->sample[t].loopend; - q->seekpos = MikMod_ISA; - - MikMod_ISA+=q->length; - MikMod_ISA=(MikMod_ISA+15)&0xfffffff0; /* normalize */ - - /* contrary to the STM specs, sample data is signed */ - q->flags = SF_SIGNED; - - if(q->loopend && q->loopend != 0xffff) - q->flags|=SF_LOOP; - } - return 1; -} - -CHAR *STM_LoadTitle(void) -{ - CHAR s[20]; - - _mm_fseek(modreader,0,SEEK_SET); - if(!_mm_read_UBYTES(s,20,modreader)) return NULL; - - return(DupStr(s,20,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_stm={ - NULL, - "STM", - "STM (Scream Tracker)", - STM_Init, - STM_Test, - STM_Load, - STM_Cleanup, - STM_LoadTitle -}; - - -/* ex:set ts=4: */ diff --git a/mikmod/load_stx.c b/mikmod/load_stx.c deleted file mode 100644 index ff978215..00000000 --- a/mikmod/load_stx.c +++ /dev/null @@ -1,439 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_stx.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - STMIK 0.2 (STX) module loader - -==============================================================================*/ - -/* - - Written by Claudio Matsuoka - -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -/* header */ -typedef struct STXHEADER { - CHAR songname[20]; - CHAR trackername[8]; - UWORD patsize; - UWORD unknown1; - UWORD patptr; - UWORD insptr; - UWORD chnptr; /* not sure */ - UWORD unknown2; - UWORD unknown3; - UBYTE mastermult; - UBYTE initspeed; - UWORD unknown4; - UWORD unknown5; - UWORD patnum; - UWORD insnum; - UWORD ordnum; - UWORD unknown6; - UWORD unknown7; - UWORD unknown8; - CHAR scrm[4]; -} STXHEADER; - -/* sample information */ -typedef struct STXSAMPLE { - UBYTE type; - CHAR filename[12]; - UBYTE memsegh; - UWORD memsegl; - ULONG length; - ULONG loopbeg; - ULONG loopend; - UBYTE volume; - UBYTE dsk; - UBYTE pack; - UBYTE flags; - ULONG c2spd; - UBYTE unused[12]; - CHAR sampname[28]; - CHAR scrs[4]; -} STXSAMPLE; - -typedef struct STXNOTE { - UBYTE note,ins,vol,cmd,inf; -} STXNOTE; - -/*========== Loader variables */ - -static STXNOTE *stxbuf = NULL; /* pointer to a complete STX pattern */ -static STXHEADER *mh = NULL; -static UWORD *paraptr = NULL; /* parapointer array (see STX docs) */ - -/*========== Loader code */ - -static BOOL STX_Test(void) -{ - UBYTE id[8]; - int t; - - _mm_fseek(modreader,0x3C,SEEK_SET); - if(!_mm_read_UBYTES(id,4,modreader)) return 0; - if(memcmp(id,"SCRM",4)) return 0; - - _mm_fseek(modreader,0x14,SEEK_SET); - if(!_mm_read_UBYTES(id,8,modreader)) return 0; - - for(t=0;t=0)&&(ch<4)) - n=&stxbuf[(64U*ch)+row]; - else - n=&dummy; - - if(flag&32) { - n->note=_mm_read_UBYTE(modreader); - n->ins=_mm_read_UBYTE(modreader); - } - if(flag&64) { - n->vol=_mm_read_UBYTE(modreader); - if(n->vol>64) n->vol=64; - } - if(flag&128) { - n->cmd=_mm_read_UBYTE(modreader); - n->inf=_mm_read_UBYTE(modreader); - } - } else row++; - } - return 1; -} - -static UBYTE* STX_ConvertTrack(STXNOTE* tr) -{ - int t; - - UniReset(); - for(t=0;t<64;t++) { - UBYTE note,ins,vol,cmd,inf; - - note=tr[t].note; - ins=tr[t].ins; - vol=tr[t].vol; - cmd=tr[t].cmd; - inf=tr[t].inf; - - if((ins)&&(ins!=255)) UniInstrument(ins-1); - if((note)&&(note!=255)) { - if(note==254) { - UniPTEffect(0xc,0); /* note cut command */ - vol=255; - } else UniNote(24+((note>>4)*OCTAVE)+(note&0xf)); /* normal note */ - } - - if(vol<255) UniPTEffect(0xc,vol); - - if(cmd<255) switch(cmd) { - case 1: /* Axx set speed to xx */ - UniPTEffect(0xf,inf>>4); - break; - case 2: /* Bxx position jump */ - UniPTEffect(0xb,inf); - break; - case 3: /* Cxx patternbreak to row xx */ - UniPTEffect(0xd,(((inf&0xf0)>>4)*10)+(inf&0xf)); - break; - case 4: /* Dxy volumeslide */ - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 5: /* Exy toneslide down */ - UniEffect(UNI_S3MEFFECTE,inf); - break; - case 6: /* Fxy toneslide up */ - UniEffect(UNI_S3MEFFECTF,inf); - break; - case 7: /* Gxx Tone portamento,speed xx */ - UniPTEffect(0x3,inf); - break; - case 8: /* Hxy vibrato */ - UniPTEffect(0x4,inf); - break; - case 9: /* Ixy tremor, ontime x, offtime y */ - UniEffect(UNI_S3MEFFECTI,inf); - break; - case 0: /* protracker arpeggio */ - if(!inf) break; - /* fall through */ - case 0xa: /* Jxy arpeggio */ - UniPTEffect(0x0,inf); - break; - case 0xb: /* Kxy Dual command H00 & Dxy */ - UniPTEffect(0x4,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 0xc: /* Lxy Dual command G00 & Dxy */ - UniPTEffect(0x3,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - /* Support all these above, since ST2 can LOAD these values but can - actually only play up to J - and J is only half-way implemented - in ST2 */ - case 0x18: /* Xxx amiga panning command 8xx */ - UniPTEffect(0x8,inf); - of.flags |= UF_PANNING; - break; - } - UniNewline(); - } - return UniDup(); -} - -static BOOL STX_Load(BOOL curious) -{ - int t,u,track = 0; - int version = 0; - SAMPLE *q; - - /* try to read module header */ - _mm_read_string(mh->songname,20,modreader); - _mm_read_string(mh->trackername,8,modreader); - mh->patsize =_mm_read_I_UWORD(modreader); - mh->unknown1 =_mm_read_I_UWORD(modreader); - mh->patptr =_mm_read_I_UWORD(modreader); - mh->insptr =_mm_read_I_UWORD(modreader); - mh->chnptr =_mm_read_I_UWORD(modreader); - mh->unknown2 =_mm_read_I_UWORD(modreader); - mh->unknown3 =_mm_read_I_UWORD(modreader); - mh->mastermult =_mm_read_UBYTE(modreader); - mh->initspeed =_mm_read_UBYTE(modreader)>>4; - mh->unknown4 =_mm_read_I_UWORD(modreader); - mh->unknown5 =_mm_read_I_UWORD(modreader); - mh->patnum =_mm_read_I_UWORD(modreader); - mh->insnum =_mm_read_I_UWORD(modreader); - mh->ordnum =_mm_read_I_UWORD(modreader); - mh->unknown6 =_mm_read_I_UWORD(modreader); - mh->unknown7 =_mm_read_I_UWORD(modreader); - mh->unknown8 =_mm_read_I_UWORD(modreader); - _mm_read_string(mh->scrm,4,modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - of.songname = DupStr(mh->songname,20,1); - of.numpat = mh->patnum; - of.reppos = 0; - of.numins = of.numsmp = mh->insnum; - of.initspeed = mh->initspeed; - of.inittempo = 125; - of.numchn = 4; - of.flags |= UF_S3MSLIDES; - of.bpmlimit = 32; - - if(!(paraptr=(UWORD*)_mm_malloc((of.numins+of.numpat)*sizeof(UWORD)))) - return 0; - - /* read the instrument+pattern parapointers */ - _mm_fseek(modreader,mh->insptr<<4,SEEK_SET); - _mm_read_I_UWORDS(paraptr,of.numins,modreader); - _mm_fseek(modreader,mh->patptr<<4,SEEK_SET); - _mm_read_I_UWORDS(paraptr+of.numins,of.numpat,modreader); - - /* check module version */ - _mm_fseek(modreader,paraptr[of.numins]<<4,SEEK_SET); - version=_mm_read_I_UWORD(modreader); - if(version==mh->patsize) { - version = 0x10; - of.modtype = strdup("STMIK 0.2 (STM2STX 1.0)"); - } else { - version = 0x11; - of.modtype = strdup("STMIK 0.2 (STM2STX 1.1)"); - } - - /* read the order data */ - _mm_fseek(modreader,(mh->chnptr<<4)+32,SEEK_SET); - if(!AllocPositions(mh->ordnum)) return 0; - for(t=0;tordnum;t++) { - of.positions[t]=_mm_read_UBYTE(modreader); - _mm_fseek(modreader,4,SEEK_CUR); - } - - of.numpos=0;poslookupcnt=mh->ordnum; - for(t=0;tordnum;t++) { - int order=of.positions[t]; - if(order==255) order=LAST_PATTERN; - of.positions[of.numpos]=order; - poslookup[t]=of.numpos; /* bug fix for freaky S3Ms */ - if(of.positions[t]<254) of.numpos++; - else - /* special end of song pattern */ - if((order==LAST_PATTERN)&&(!curious)) break; - } - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* load samples */ - if(!AllocSamples()) return 0; - for(q=of.samples,t=0;tsamplename = DupStr(s.sampname,28,1); - q->speed = (s.c2spd * 8363) / 8448; - q->length = s.length; - q->loopstart = s.loopbeg; - q->loopend = s.loopend; - q->volume = s.volume; - q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4; - q->flags |= SF_SIGNED; - - if(s.flags&1) q->flags |= SF_LOOP; - if(s.flags&4) q->flags |= SF_16BITS; - } - - /* load pattern info */ - of.numtrk=of.numpat*of.numchn; - if(!AllocTracks()) return 0; - if(!AllocPatterns()) return 0; - - for(t=0;t -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -/* header */ -typedef struct ULTHEADER { - CHAR id[16]; - CHAR songtitle[32]; - UBYTE reserved; -} ULTHEADER; - -/* sample information */ -typedef struct ULTSAMPLE { - CHAR samplename[32]; - CHAR dosname[12]; - SLONG loopstart; - SLONG loopend; - SLONG sizestart; - SLONG sizeend; - UBYTE volume; - UBYTE flags; - UWORD speed; - SWORD finetune; -} ULTSAMPLE; - -typedef struct ULTEVENT { - UBYTE note,sample,eff,dat1,dat2; -} ULTEVENT; - -/*========== Loader variables */ - -#define ULTS_16BITS 4 -#define ULTS_LOOP 8 -#define ULTS_REVERSE 16 - -#define ULT_VERSION_LEN 18 -static CHAR ULT_Version[ULT_VERSION_LEN]="Ultra Tracker v1.x"; - -static ULTEVENT ev; - -/*========== Loader code */ - -BOOL ULT_Test(void) -{ - CHAR id[16]; - - if(!_mm_read_string(id,15,modreader)) return 0; - if(strncmp(id,"MAS_UTrack_V00",14)) return 0; - if((id[14]<'1')||(id[14]>'4')) return 0; - return 1; -} - -BOOL ULT_Init(void) -{ - return 1; -} - -void ULT_Cleanup(void) -{ -} - -static UBYTE ReadUltEvent(ULTEVENT* event) -{ - UBYTE flag,rep=1; - - flag = _mm_read_UBYTE(modreader); - if(flag==0xfc) { - rep = _mm_read_UBYTE(modreader); - event->note =_mm_read_UBYTE(modreader); - } else - event->note = flag; - - event->sample =_mm_read_UBYTE(modreader); - event->eff =_mm_read_UBYTE(modreader); - event->dat1 =_mm_read_UBYTE(modreader); - event->dat2 =_mm_read_UBYTE(modreader); - - return rep; -} - -BOOL ULT_Load(BOOL curious) -{ - int t,u,tracks=0; - SAMPLE *q; - ULTSAMPLE s; - ULTHEADER mh; - UBYTE nos,noc,nop; - - /* try to read module header */ - _mm_read_string(mh.id,15,modreader); - _mm_read_string(mh.songtitle,32,modreader); - mh.reserved=_mm_read_UBYTE(modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - ULT_Version[ULT_VERSION_LEN-1]='3'+(mh.id[14]-'1'); - of.modtype = DupStr(ULT_Version,ULT_VERSION_LEN,1); - of.initspeed = 6; - of.inittempo = 125; - of.reppos = 0; - - /* read songtext */ - if ((mh.id[14]>'1')&&(mh.reserved)) - if(!ReadLinedComment(mh.reserved * 32, 32)) return 0; - - nos=_mm_read_UBYTE(modreader); - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - of.songname=DupStr(mh.songtitle,32,1); - of.numins=of.numsmp=nos; - - if(!AllocSamples()) return 0; - q = of.samples; - for(t=0;t='4')?_mm_read_I_UWORD(modreader):8363; - s.finetune =_mm_read_I_SWORD(modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - q->samplename=DupStr(s.samplename,32,1); - /* The correct formula for the coefficient would be - pow(2,(double)s.finetume/OCTAVE/32768), but to avoid floating point - here, we'll use a first order approximation here. - 1/567290 == Ln(2)/OCTAVE/32768 */ - q->speed=s.speed+s.speed*(((SLONG)s.speed*(SLONG)s.finetune)/567290); - q->length = s.sizeend-s.sizestart; - q->volume = s.volume>>2; - q->loopstart = s.loopstart; - q->loopend = s.loopend; - q->flags = SF_SIGNED; - if(s.flags&ULTS_LOOP) q->flags|=SF_LOOP; - if(s.flags&ULTS_16BITS) { - s.sizeend+=(s.sizeend-s.sizestart); - s.sizestart<<=1; - q->flags|=SF_16BITS; - q->loopstart>>=1; - q->loopend>>=1; - } - q++; - } - - if(!AllocPositions(256)) return 0; - for(t=0;t<256;t++) - of.positions[t]=_mm_read_UBYTE(modreader); - for(t=0;t<256;t++) - if(of.positions[t]==255) { - of.positions[t]=LAST_PATTERN; - break; - } - of.numpos=t; - - noc=_mm_read_UBYTE(modreader); - nop=_mm_read_UBYTE(modreader); - - of.numchn=++noc; - of.numpat=++nop; - of.numtrk=of.numchn*of.numpat; - if(!AllocTracks()) return 0; - if(!AllocPatterns()) return 0; - for(u=0;u='3') { - for(t=0;t>4; - switch(eff) { - case 0x3: /* tone portamento */ - UniEffect(UNI_ITEFFECTG,ev.dat2); - break; - case 0x5: - break; - case 0x9: /* sample offset */ - offset=(ev.dat2<<8)|((ev.eff&0xf)==9?ev.dat1:0); - UniEffect(UNI_ULTEFFECT9,offset); - break; - case 0xb: /* panning */ - UniPTEffect(8,ev.dat2*0xf); - of.flags |= UF_PANNING; - break; - case 0xc: /* volume */ - UniPTEffect(eff,ev.dat2>>2); - break; - default: - UniPTEffect(eff,ev.dat2); - break; - } - - /* second effect */ - eff=ev.eff&0xf; - switch(eff) { - case 0x3: /* tone portamento */ - UniEffect(UNI_ITEFFECTG,ev.dat1); - break; - case 0x5: - break; - case 0x9: /* sample offset */ - if((ev.eff>>4)!=9) - UniEffect(UNI_ULTEFFECT9,((UWORD)ev.dat1)<<8); - break; - case 0xb: /* panning */ - UniPTEffect(8,ev.dat1*0xf); - of.flags |= UF_PANNING; - break; - case 0xc: /* volume */ - UniPTEffect(eff,ev.dat1>>2); - break; - default: - UniPTEffect(eff,ev.dat1); - break; - } - - UniNewline(); - row++; - } - } - if(!(of.tracks[t]=UniDup())) return 0; - } - return 1; -} - -CHAR *ULT_LoadTitle(void) -{ - CHAR s[32]; - - _mm_fseek(modreader,15,SEEK_SET); - if(!_mm_read_UBYTES(s,32,modreader)) return NULL; - - return(DupStr(s,32,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_ult={ - NULL, - "ULT", - "ULT (UltraTracker)", - ULT_Init, - ULT_Test, - ULT_Load, - ULT_Cleanup, - ULT_LoadTitle -}; - - -/* ex:set ts=4: */ diff --git a/mikmod/load_uni.c b/mikmod/load_uni.c deleted file mode 100644 index 2f7cf153..00000000 --- a/mikmod/load_uni.c +++ /dev/null @@ -1,717 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id: load_uni.c,v 1.1.1.1 2004/06/01 12:16:17 raph Exp $ - - UNIMOD (libmikmod's and APlayer's internal module format) loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -typedef struct UNIHEADER { - CHAR id[4]; - UBYTE numchn; - UWORD numpos; - UWORD reppos; - UWORD numpat; - UWORD numtrk; - UWORD numins; - UWORD numsmp; - UBYTE initspeed; - UBYTE inittempo; - UBYTE initvolume; - UWORD flags; - UBYTE numvoices; - UWORD bpmlimit; - - UBYTE positions[256]; - UBYTE panning[32]; -} UNIHEADER; - -typedef struct UNISMP05 { - UWORD c2spd; - UWORD transpose; - UBYTE volume; - UBYTE panning; - ULONG length; - ULONG loopstart; - ULONG loopend; - UWORD flags; - CHAR* samplename; - UBYTE vibtype; - UBYTE vibsweep; - UBYTE vibdepth; - UBYTE vibrate; -} UNISMP05; - -/*========== Loader variables */ - -static UWORD universion; -static UNIHEADER mh; - -#define UNI_SMPINCR 64 -static UNISMP05 *wh=NULL,*s=NULL; - -/*========== Loader code */ - -static char* readstring(void) -{ - char *s=NULL; - UWORD len; - - len=_mm_read_I_UWORD(modreader); - if(len) { - s=_mm_malloc(len+1); - _mm_read_UBYTES(s,len,modreader); - s[len]=0; - } - return s; -} - -BOOL UNI_Test(void) -{ - char id[6]; - - if(!_mm_read_UBYTES(id,6,modreader)) return 0; - - /* UNIMod created by MikCvt */ - if(!(memcmp(id,"UN0",3))) { - if((id[3]>='4')&&(id[3]<='6')) return 1; - } - /* UNIMod created by APlayer */ - if(!(memcmp(id,"APUN\01",5))) { - if((id[5]>=1)&&(id[5]<=6)) return 1; - } - return 0; -} - -BOOL UNI_Init(void) -{ - return 1; -} - -void UNI_Cleanup(void) -{ - _mm_free(wh); - s=NULL; -} - -static UBYTE* readtrack(void) -{ - UBYTE *t; - UWORD len; - int cur=0,chunk; - - if(universion>=6) - len=_mm_read_M_UWORD(modreader); - else - len=_mm_read_I_UWORD(modreader); - - if(!len) return NULL; - if(!(t=_mm_malloc(len))) return NULL; - _mm_read_UBYTES(t,len,modreader); - - /* Check if the track is correct */ - while(1) { - chunk=t[cur++]; - if(!chunk) break; - chunk=(chunk&0x1f)-1; - while(chunk>0) { - int opcode,oplen; - - if(cur>=len) { - free(t); - return NULL; - } - opcode=t[cur]; - - /* Remap opcodes */ - if (universion <= 5) { - if (opcode > 29) { - free(t); - return NULL; - } - switch (opcode) { - /* UNI_NOTE .. UNI_S3MEFFECTQ are the same */ - case 25: - opcode = UNI_S3MEFFECTT; - break; - case 26: - opcode = UNI_XMEFFECTA; - break; - case 27: - opcode = UNI_XMEFFECTG; - break; - case 28: - opcode = UNI_XMEFFECTH; - break; - case 29: - opcode = UNI_XMEFFECTP; - break; - } - } else { - /* APlayer < 1.05 does not have XMEFFECT6 */ - if (opcode >= UNI_XMEFFECT6 && universion < 0x105) - opcode++; - /* APlayer < 1.03 does not have ITEFFECTT */ - if (opcode >= UNI_ITEFFECTT && universion < 0x103) - opcode++; - /* APlayer < 1.02 does not have ITEFFECTZ */ - if (opcode >= UNI_ITEFFECTZ && universion < 0x102) - opcode++; - } - - if((!opcode)||(opcode>=UNI_LAST)) { - free(t); - return NULL; - } - t[cur]=opcode; - oplen=unioperands[opcode]+1; - cur+=oplen; - chunk-=oplen; - } - if((chunk<0)||(cur>=len)) { - free(t); - return NULL; - } - } - return t; -} - -static BOOL loadsmp6(void) -{ - int t; - SAMPLE *s; - - s=of.samples; - for(t=0;tflags=0; - if(flags&0x0004) s->flags|=SF_STEREO; - if(flags&0x0002) s->flags|=SF_SIGNED; - if(flags&0x0001) s->flags|=SF_16BITS; - /* convert flags */ - if(universion>=0x104) { - if(flags&0x2000) s->flags|=SF_UST_LOOP; - if(flags&0x1000) s->flags|=SF_OWNPAN; - if(flags&0x0800) s->flags|=SF_SUSTAIN; - if(flags&0x0400) s->flags|=SF_REVERSE; - if(flags&0x0200) s->flags|=SF_BIDI; - if(flags&0x0100) s->flags|=SF_LOOP; - if(flags&0x0020) s->flags|=SF_ITPACKED; - if(flags&0x0010) s->flags|=SF_DELTA; - if(flags&0x0008) s->flags|=SF_BIG_ENDIAN; - } else if(universion>=0x102) { - if(flags&0x0800) s->flags|=SF_UST_LOOP; - if(flags&0x0400) s->flags|=SF_OWNPAN; - if(flags&0x0200) s->flags|=SF_SUSTAIN; - if(flags&0x0100) s->flags|=SF_REVERSE; - if(flags&0x0080) s->flags|=SF_BIDI; - if(flags&0x0040) s->flags|=SF_LOOP; - if(flags&0x0020) s->flags|=SF_ITPACKED; - if(flags&0x0010) s->flags|=SF_DELTA; - if(flags&0x0008) s->flags|=SF_BIG_ENDIAN; - } else { - if(flags&0x400) s->flags|=SF_UST_LOOP; - if(flags&0x200) s->flags|=SF_OWNPAN; - if(flags&0x100) s->flags|=SF_REVERSE; - if(flags&0x080) s->flags|=SF_SUSTAIN; - if(flags&0x040) s->flags|=SF_BIDI; - if(flags&0x020) s->flags|=SF_LOOP; - if(flags&0x010) s->flags|=SF_BIG_ENDIAN; - if(flags&0x008) s->flags|=SF_DELTA; - } - - s->speed = _mm_read_M_ULONG(modreader); - s->volume = _mm_read_UBYTE(modreader); - s->panning = _mm_read_M_UWORD(modreader); - s->length = _mm_read_M_ULONG(modreader); - s->loopstart = _mm_read_M_ULONG(modreader); - s->loopend = _mm_read_M_ULONG(modreader); - s->susbegin = _mm_read_M_ULONG(modreader); - s->susend = _mm_read_M_ULONG(modreader); - s->globvol = _mm_read_UBYTE(modreader); - s->vibflags = _mm_read_UBYTE(modreader); - s->vibtype = _mm_read_UBYTE(modreader); - s->vibsweep = _mm_read_UBYTE(modreader); - s->vibdepth = _mm_read_UBYTE(modreader); - s->vibrate = _mm_read_UBYTE(modreader); - - s->samplename=readstring(); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - } - return 1; -} - -static BOOL loadinstr6(void) -{ - int t,w; - INSTRUMENT *i; - - i=of.instruments; - for(t=0;tflags = _mm_read_UBYTE(modreader); - i->nnatype = _mm_read_UBYTE(modreader); - i->dca = _mm_read_UBYTE(modreader); - i->dct = _mm_read_UBYTE(modreader); - i->globvol = _mm_read_UBYTE(modreader); - i->panning = _mm_read_M_UWORD(modreader); - i->pitpansep = _mm_read_UBYTE(modreader); - i->pitpancenter = _mm_read_UBYTE(modreader); - i->rvolvar = _mm_read_UBYTE(modreader); - i->rpanvar = _mm_read_UBYTE(modreader); - i->volfade = _mm_read_M_UWORD(modreader); - -#if defined __STDC__ || defined _MSC_VER -#define UNI_LoadEnvelope6(name) \ - i-> name##flg=_mm_read_UBYTE(modreader); \ - i-> name##pts=_mm_read_UBYTE(modreader); \ - i-> name##susbeg=_mm_read_UBYTE(modreader); \ - i-> name##susend=_mm_read_UBYTE(modreader); \ - i-> name##beg=_mm_read_UBYTE(modreader); \ - i-> name##end=_mm_read_UBYTE(modreader); \ - for(w=0;w<(universion>=0x100?32:i-> name##pts);w++) { \ - i-> name##env[w].pos=_mm_read_M_SWORD(modreader); \ - i-> name##env[w].val=_mm_read_M_SWORD(modreader); \ - } -#else -#define UNI_LoadEnvelope6(name) \ - i-> name/**/flg=_mm_read_UBYTE(modreader); \ - i-> name/**/pts=_mm_read_UBYTE(modreader); \ - i-> name/**/susbeg=_mm_read_UBYTE(modreader); \ - i-> name/**/susend=_mm_read_UBYTE(modreader); \ - i-> name/**/beg=_mm_read_UBYTE(modreader); \ - i-> name/**/end=_mm_read_UBYTE(modreader); \ - for (w=0;w<(universion>=0x100?32:i-> name/**/pts);w++) { \ - i-> name/**/env[w].pos=_mm_read_M_SWORD(modreader); \ - i-> name/**/env[w].val=_mm_read_M_SWORD(modreader); \ - } -#endif - - UNI_LoadEnvelope6(vol); - UNI_LoadEnvelope6(pan); - UNI_LoadEnvelope6(pit); -#undef UNI_LoadEnvelope6 - - if(universion>=0x103) - _mm_read_M_UWORDS(i->samplenumber,120,modreader); - else - for(w=0;w<120;w++) - i->samplenumber[w]=_mm_read_UBYTE(modreader); - _mm_read_UBYTES(i->samplenote,120,modreader); - - i->insname=readstring(); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - } - return 1; -} - -static BOOL loadinstr5(void) -{ - INSTRUMENT *i; - int t; - UWORD wavcnt=0; - UBYTE vibtype,vibsweep,vibdepth,vibrate; - - i=of.instruments; - for(of.numsmp=t=0;tsamplenumber,0xff,INSTNOTES*sizeof(UWORD)); - for(u=0;u<96;u++) - i->samplenumber[u]=of.numsmp+_mm_read_UBYTE(modreader); - -#if defined __STDC__ || defined _MSC_VER -#define UNI_LoadEnvelope5(name) \ - i-> name##flg=_mm_read_UBYTE(modreader); \ - i-> name##pts=_mm_read_UBYTE(modreader); \ - i-> name##susbeg=_mm_read_UBYTE(modreader); \ - i-> name##susend=i-> name##susbeg; \ - i-> name##beg=_mm_read_UBYTE(modreader); \ - i-> name##end=_mm_read_UBYTE(modreader); \ - for(u=0;u<12;u++) { \ - i-> name##env[u].pos=_mm_read_I_SWORD(modreader); \ - i-> name##env[u].val=_mm_read_I_SWORD(modreader); \ - } -#else -#define UNI_LoadEnvelope5(name) \ - i-> name/**/flg=_mm_read_UBYTE(modreader); \ - i-> name/**/pts=_mm_read_UBYTE(modreader); \ - i-> name/**/susbeg=_mm_read_UBYTE(modreader); \ - i-> name/**/susend=i-> name/**/susbeg; \ - i-> name/**/beg=_mm_read_UBYTE(modreader); \ - i-> name/**/end=_mm_read_UBYTE(modreader); \ - for(u=0;u<12;u++) { \ - i-> name/**/env[u].pos=_mm_read_I_SWORD(modreader); \ - i-> name/**/env[u].val=_mm_read_I_SWORD(modreader); \ - } -#endif - - UNI_LoadEnvelope5(vol); - UNI_LoadEnvelope5(pan); -#undef UNI_LoadEnvelope5 - - vibtype =_mm_read_UBYTE(modreader); - vibsweep =_mm_read_UBYTE(modreader); - vibdepth =_mm_read_UBYTE(modreader); - vibrate =_mm_read_UBYTE(modreader); - - i->volfade=_mm_read_I_UWORD(modreader); - i->insname=readstring(); - - for(u=0;uc2spd =_mm_read_I_UWORD(modreader); - s->transpose=_mm_read_SBYTE(modreader); - s->volume =_mm_read_UBYTE(modreader); - s->panning =_mm_read_UBYTE(modreader); - s->length =_mm_read_I_ULONG(modreader); - s->loopstart=_mm_read_I_ULONG(modreader); - s->loopend =_mm_read_I_ULONG(modreader); - s->flags =_mm_read_I_UWORD(modreader); - s->samplename=readstring(); - - s->vibtype =vibtype; - s->vibsweep=vibsweep; - s->vibdepth=vibdepth; - s->vibrate =vibrate; - - if(_mm_eof(modreader)) { - free(wh);wh=NULL; - _mm_errno=MMERR_LOADING_SAMPLEINFO; - return 0; - } - } - } - - /* sanity check */ - if(!of.numsmp) { - if(wh) { free(wh);wh=NULL; } - _mm_errno=MMERR_LOADING_SAMPLEINFO; - return 0; - } - return 1; -} - -static BOOL loadsmp5(void) -{ - int t,u; - SAMPLE *q; - INSTRUMENT *d; - - q=of.samples;s=wh; - for(u=0;usamplename=s->samplename; - - q->length =s->length; - q->loopstart=s->loopstart; - q->loopend =s->loopend; - q->volume =s->volume; - q->speed =s->c2spd; - q->panning =s->panning; - q->vibtype =s->vibtype; - q->vibsweep =s->vibsweep; - q->vibdepth =s->vibdepth; - q->vibrate =s->vibrate; - - /* convert flags */ - q->flags=0; - if(s->flags&128) q->flags|=SF_REVERSE; - if(s->flags& 64) q->flags|=SF_SUSTAIN; - if(s->flags& 32) q->flags|=SF_BIDI; - if(s->flags& 16) q->flags|=SF_LOOP; - if(s->flags& 8) q->flags|=SF_BIG_ENDIAN; - if(s->flags& 4) q->flags|=SF_DELTA; - if(s->flags& 2) q->flags|=SF_SIGNED; - if(s->flags& 1) q->flags|=SF_16BITS; - } - - d=of.instruments;s=wh; - for(u=0;usamplenote[t]=(d->samplenumber[t]>=of.numsmp)? - 255:(t+s[d->samplenumber[t]].transpose); - - free(wh);wh=NULL; - - return 1; -} - -BOOL UNI_Load(BOOL curious) -{ - int t; - char *modtype,*oldtype=NULL; - INSTRUMENT *d; - SAMPLE *q; - - /* read module header */ - _mm_read_UBYTES(mh.id,4,modreader); - if(mh.id[3]!='N') - universion=mh.id[3]-'0'; - else - universion=0x100; - - if(universion>=6) { - if (universion==6) - _mm_read_UBYTE(modreader); - else - universion=_mm_read_M_UWORD(modreader); - - mh.flags =_mm_read_M_UWORD(modreader); - mh.numchn =_mm_read_UBYTE(modreader); - mh.numvoices =_mm_read_UBYTE(modreader); - mh.numpos =_mm_read_M_UWORD(modreader); - mh.numpat =_mm_read_M_UWORD(modreader); - mh.numtrk =_mm_read_M_UWORD(modreader); - mh.numins =_mm_read_M_UWORD(modreader); - mh.numsmp =_mm_read_M_UWORD(modreader); - mh.reppos =_mm_read_M_UWORD(modreader); - mh.initspeed =_mm_read_UBYTE(modreader); - mh.inittempo =_mm_read_UBYTE(modreader); - mh.initvolume=_mm_read_UBYTE(modreader); - /* I expect this to show up soon in APlayer 1.06 format */ - if (universion >= 0x106) - mh.bpmlimit=_mm_read_M_UWORD(modreader); - else - mh.bpmlimit=32; - - mh.flags &= UF_XMPERIODS | UF_LINEAR | UF_INST | UF_NNA; - mh.flags |= UF_PANNING; - } else { - mh.numchn =_mm_read_UBYTE(modreader); - mh.numpos =_mm_read_I_UWORD(modreader); - mh.reppos =(universion==5)?_mm_read_I_UWORD(modreader):0; - mh.numpat =_mm_read_I_UWORD(modreader); - mh.numtrk =_mm_read_I_UWORD(modreader); - mh.numins =_mm_read_I_UWORD(modreader); - mh.initspeed =_mm_read_UBYTE(modreader); - mh.inittempo =_mm_read_UBYTE(modreader); - _mm_read_UBYTES(mh.positions,256,modreader); - _mm_read_UBYTES(mh.panning,32,modreader); - mh.flags =_mm_read_UBYTE(modreader); - mh.bpmlimit =32; - - mh.flags &= UF_XMPERIODS | UF_LINEAR; - mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING; - } - - /* set module parameters */ - of.flags =mh.flags; - of.numchn =mh.numchn; - of.numpos =mh.numpos; - of.numpat =mh.numpat; - of.numtrk =mh.numtrk; - of.numins =mh.numins; - of.reppos =mh.reppos; - of.initspeed =mh.initspeed; - of.inittempo =mh.inittempo; - if(mh.bpmlimit) - of.bpmlimit=mh.bpmlimit; - else - /* be bug-compatible with older releases */ - of.bpmlimit=32; - - of.songname=readstring(); - if(universion<0x102) - oldtype=readstring(); - if(oldtype) { - int len=strlen(oldtype)+20; - if(!(modtype=_mm_malloc(len))) return 0; -#ifdef HAVE_SNPRINTF - snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); -#else - sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); -#endif - } else { - if(!(modtype=_mm_malloc(10))) return 0; -#ifdef HAVE_SNPRINTF - snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); -#else - sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); -#endif - } - of.modtype=strdup(modtype); - free(modtype);free(oldtype); - of.comment=readstring(); - - if(universion>=6) { - of.numvoices=mh.numvoices; - of.initvolume=mh.initvolume; - } - - if(_mm_eof(modreader)) { - _mm_errno=MMERR_LOADING_HEADER; - return 0; - } - - /* positions */ - if(!AllocPositions(of.numpos)) return 0; - if(universion>=6) { - if(universion>=0x100) - _mm_read_M_UWORDS(of.positions,of.numpos,modreader); - else - for(t=0;t256)||(mh.numchn>32)) { - _mm_errno=MMERR_LOADING_HEADER; - return 0; - } - for(t=0;t=6) { - of.numsmp=mh.numsmp; - if(!AllocSamples()) return 0; - if(!loadsmp6()) return 0; - - if(of.flags&UF_INST) { - if(!AllocInstruments()) return 0; - if(!loadinstr6()) return 0; - } - } else { - if(!AllocInstruments()) return 0; - if(!loadinstr5()) return 0; - if(!AllocSamples()) { - if(wh) { free(wh);wh=NULL; } - return 0; - } - if(!loadsmp5()) return 0; - - /* check if the original file had no instruments */ - if(of.numsmp==of.numins) { - for(t=0,d=of.instruments;tvolpts)||(d->panpts)||(d->globvol!=64)) break; - for(u=0;u<96;u++) - if((d->samplenumber[u]!=t)||(d->samplenote[u]!=u)) break; - if(u!=96) break; - } - if(t==of.numins) { - of.flags&=~UF_INST; - of.flags&=~UF_NOWRAP; - for(t=0,d=of.instruments,q=of.samples;tsamplename=d->insname; - d->insname=NULL; - } - } - } - } - - /* patterns */ - if(!AllocPatterns()) return 0; - if(universion>=6) { - _mm_read_M_UWORDS(of.pattrows,of.numpat,modreader); - _mm_read_M_UWORDS(of.patterns,of.numpat*of.numchn,modreader); - } else { - _mm_read_I_UWORDS(of.pattrows,of.numpat,modreader); - _mm_read_I_UWORDS(of.patterns,of.numpat*of.numchn,modreader); - } - - /* tracks */ - if(!AllocTracks()) return 0; - for(t=0;t -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Module structure */ - -typedef struct XMHEADER { - CHAR id[17]; /* ID text: 'Extended module: ' */ - CHAR songname[21]; /* Module name */ - CHAR trackername[20]; /* Tracker name */ - UWORD version; /* Version number */ - ULONG headersize; /* Header size */ - UWORD songlength; /* Song length (in patten order table) */ - UWORD restart; /* Restart position */ - UWORD numchn; /* Number of channels (2,4,6,8,10,...,32) */ - UWORD numpat; /* Number of patterns (max 256) */ - UWORD numins; /* Number of instruments (max 128) */ - UWORD flags; - UWORD tempo; /* Default tempo */ - UWORD bpm; /* Default BPM */ - UBYTE orders[256]; /* Pattern order table */ -} XMHEADER; - -typedef struct XMINSTHEADER { - ULONG size; /* Instrument size */ - CHAR name[22]; /* Instrument name */ - UBYTE type; /* Instrument type (always 0) */ - UWORD numsmp; /* Number of samples in instrument */ - ULONG ssize; -} XMINSTHEADER; - -#define XMENVCNT (12*2) -#define XMNOTECNT (8*OCTAVE) -typedef struct XMPATCHHEADER { - UBYTE what[XMNOTECNT]; /* Sample number for all notes */ - UWORD volenv[XMENVCNT]; /* Points for volume envelope */ - UWORD panenv[XMENVCNT]; /* Points for panning envelope */ - UBYTE volpts; /* Number of volume points */ - UBYTE panpts; /* Number of panning points */ - UBYTE volsus; /* Volume sustain point */ - UBYTE volbeg; /* Volume loop start point */ - UBYTE volend; /* Volume loop end point */ - UBYTE pansus; /* Panning sustain point */ - UBYTE panbeg; /* Panning loop start point */ - UBYTE panend; /* Panning loop end point */ - UBYTE volflg; /* Volume type: bit 0: On; 1: Sustain; 2: Loop */ - UBYTE panflg; /* Panning type: bit 0: On; 1: Sustain; 2: Loop */ - UBYTE vibflg; /* Vibrato type */ - UBYTE vibsweep; /* Vibrato sweep */ - UBYTE vibdepth; /* Vibrato depth */ - UBYTE vibrate; /* Vibrato rate */ - UWORD volfade; /* Volume fadeout */ -} XMPATCHHEADER; - -typedef struct XMWAVHEADER { - ULONG length; /* Sample length */ - ULONG loopstart; /* Sample loop start */ - ULONG looplength; /* Sample loop length */ - UBYTE volume; /* Volume */ - SBYTE finetune; /* Finetune (signed byte -128..+127) */ - UBYTE type; /* Loop type */ - UBYTE panning; /* Panning (0-255) */ - SBYTE relnote; /* Relative note number (signed byte) */ - UBYTE reserved; - CHAR samplename[22]; /* Sample name */ - UBYTE vibtype; /* Vibrato type */ - UBYTE vibsweep; /* Vibrato sweep */ - UBYTE vibdepth; /* Vibrato depth */ - UBYTE vibrate; /* Vibrato rate */ -} XMWAVHEADER; - -typedef struct XMPATHEADER { - ULONG size; /* Pattern header length */ - UBYTE packing; /* Packing type (always 0) */ - UWORD numrows; /* Number of rows in pattern (1..256) */ - SWORD packsize; /* Packed patterndata size */ -} XMPATHEADER; - -typedef struct XMNOTE { - UBYTE note,ins,vol,eff,dat; -} XMNOTE; - -/*========== Loader variables */ - -static XMNOTE *xmpat=NULL; -static XMHEADER *mh=NULL; - -/* increment unit for sample array reallocation */ -#define XM_SMPINCR 64 -static ULONG *nextwav=NULL; -static XMWAVHEADER *wh=NULL,*s=NULL; - -/*========== Loader code */ - -BOOL XM_Test(void) -{ - UBYTE id[38]; - - if(!_mm_read_UBYTES(id,38,modreader)) return 0; - if(memcmp(id,"Extended Module: ",17)) return 0; - if(id[37]==0x1a) return 1; - return 0; -} - -BOOL XM_Init(void) -{ - if(!(mh=(XMHEADER *)_mm_malloc(sizeof(XMHEADER)))) return 0; - return 1; -} - -void XM_Cleanup(void) -{ - _mm_free(mh); -} - -static int XM_ReadNote(XMNOTE* n) -{ - UBYTE cmp,result=1; - - memset(n,0,sizeof(XMNOTE)); - cmp=_mm_read_UBYTE(modreader); - - if(cmp&0x80) { - if(cmp&1) { result++;n->note = _mm_read_UBYTE(modreader); } - if(cmp&2) { result++;n->ins = _mm_read_UBYTE(modreader); } - if(cmp&4) { result++;n->vol = _mm_read_UBYTE(modreader); } - if(cmp&8) { result++;n->eff = _mm_read_UBYTE(modreader); } - if(cmp&16) { result++;n->dat = _mm_read_UBYTE(modreader); } - } else { - n->note = cmp; - n->ins = _mm_read_UBYTE(modreader); - n->vol = _mm_read_UBYTE(modreader); - n->eff = _mm_read_UBYTE(modreader); - n->dat = _mm_read_UBYTE(modreader); - result += 4; - } - return result; -} - -static UBYTE* XM_Convert(XMNOTE* xmtrack,UWORD rows) -{ - int t; - UBYTE note,ins,vol,eff,dat; - - UniReset(); - for(t=0;tnote; - ins = xmtrack->ins; - vol = xmtrack->vol; - eff = xmtrack->eff; - dat = xmtrack->dat; - - if(note) { - if(note>XMNOTECNT) - UniEffect(UNI_KEYFADE,0); - else - UniNote(note-1); - } - if(ins) UniInstrument(ins-1); - - switch(vol>>4) { - case 0x6: /* volslide down */ - if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol&0xf); - break; - case 0x7: /* volslide up */ - if(vol&0xf) UniEffect(UNI_XMEFFECTA,vol<<4); - break; - - /* volume-row fine volume slide is compatible with protracker - EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as - opposed to 'take the last sliding value'. */ - case 0x8: /* finevol down */ - UniPTEffect(0xe,0xb0|(vol&0xf)); - break; - case 0x9: /* finevol up */ - UniPTEffect(0xe,0xa0|(vol&0xf)); - break; - case 0xa: /* set vibrato speed */ - UniEffect(UNI_XMEFFECT4,vol<<4); - break; - case 0xb: /* vibrato */ - UniEffect(UNI_XMEFFECT4,vol&0xf); - break; - case 0xc: /* set panning */ - UniPTEffect(0x8,vol<<4); - break; - case 0xd: /* panning slide left (only slide when data not zero) */ - if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol&0xf); - break; - case 0xe: /* panning slide right (only slide when data not zero) */ - if(vol&0xf) UniEffect(UNI_XMEFFECTP,vol<<4); - break; - case 0xf: /* tone porta */ - UniPTEffect(0x3,vol<<4); - break; - default: - if((vol>=0x10)&&(vol<=0x50)) - UniPTEffect(0xc,vol-0x10); - } - - switch(eff) { - case 0x4: - UniEffect(UNI_XMEFFECT4,dat); - break; - case 0x6: - UniEffect(UNI_XMEFFECT6,dat); - break; - case 0xa: - UniEffect(UNI_XMEFFECTA,dat); - break; - case 0xe: /* Extended effects */ - switch(dat>>4) { - case 0x1: /* XM fine porta up */ - UniEffect(UNI_XMEFFECTE1,dat&0xf); - break; - case 0x2: /* XM fine porta down */ - UniEffect(UNI_XMEFFECTE2,dat&0xf); - break; - case 0xa: /* XM fine volume up */ - UniEffect(UNI_XMEFFECTEA,dat&0xf); - break; - case 0xb: /* XM fine volume down */ - UniEffect(UNI_XMEFFECTEB,dat&0xf); - break; - default: - UniPTEffect(eff,dat); - } - break; - case 'G'-55: /* G - set global volume */ - UniEffect(UNI_XMEFFECTG,dat>64?128:dat<<1); - break; - case 'H'-55: /* H - global volume slide */ - UniEffect(UNI_XMEFFECTH,dat); - break; - case 'K'-55: /* K - keyOff and KeyFade */ - UniEffect(UNI_KEYFADE,dat); - break; - case 'L'-55: /* L - set envelope position */ - UniEffect(UNI_XMEFFECTL,dat); - break; - case 'P'-55: /* P - panning slide */ - UniEffect(UNI_XMEFFECTP,dat); - break; - case 'R'-55: /* R - multi retrig note */ - UniEffect(UNI_S3MEFFECTQ,dat); - break; - case 'T'-55: /* T - Tremor */ - UniEffect(UNI_S3MEFFECTI,dat); - break; - case 'X'-55: - switch(dat>>4) { - case 1: /* X1 - Extra Fine Porta up */ - UniEffect(UNI_XMEFFECTX1,dat&0xf); - break; - case 2: /* X2 - Extra Fine Porta down */ - UniEffect(UNI_XMEFFECTX2,dat&0xf); - break; - } - break; - case 'Z'-55: /* Z - synchro */ - UniEffect(UNI_XMEFFECTZ,dat); - break; - default: - if(eff<=0xf) { - /* the pattern jump destination is written in decimal, - but it seems some poor tracker software writes them - in hexadecimal... (sigh) */ - if (eff==0xd) - /* don't change anything if we're sure it's in hexa */ - if ((((dat&0xf0)>>4)<=9)&&((dat&0xf)<=9)) - /* otherwise, convert from dec to hex */ - dat=(((dat&0xf0)>>4)*10)+(dat&0xf); - UniPTEffect(eff,dat); - } - break; - } - UniNewline(); - xmtrack++; - } - return UniDup(); -} - -static BOOL LoadPatterns(BOOL dummypat) -{ - int t,u,v,numtrk; - - if(!AllocTracks()) return 0; - if(!AllocPatterns()) return 0; - - numtrk=0; - for(t=0;tnumpat;t++) { - XMPATHEADER ph; - - ph.size =_mm_read_I_ULONG(modreader); - if (ph.size<(mh->version==0x0102?8:9)) { - _mm_errno=MMERR_LOADING_PATTERN; - return 0; - } - ph.packing =_mm_read_UBYTE(modreader); - if(ph.packing) { - _mm_errno=MMERR_LOADING_PATTERN; - return 0; - } - if(mh->version==0x0102) - ph.numrows =_mm_read_UBYTE(modreader)+1; - else - ph.numrows =_mm_read_I_UWORD(modreader); - ph.packsize =_mm_read_I_UWORD(modreader); - - ph.size-=(mh->version==0x0102?8:9); - if(ph.size) - _mm_fseek(modreader,ph.size,SEEK_CUR); - - of.pattrows[t]=ph.numrows; - - if(ph.numrows) { - if(!(xmpat=(XMNOTE*)_mm_calloc(ph.numrows*of.numchn,sizeof(XMNOTE)))) - return 0; - - /* when packsize is 0, don't try to load a pattern.. it's empty. */ - if(ph.packsize) - for(u=0;upos; - - for (u = 1; u < pts; u++, prev++, cur++) { - if (cur->pos < prev->pos) { - if (cur->pos < 0x100) { - if (cur->pos > old) /* same hex century */ - tmp = cur->pos + (prev->pos - old); - else - tmp = cur->pos | ((prev->pos + 0x100) & 0xff00); - old = cur->pos; - cur->pos = tmp; -#ifdef MIKMOD_DEBUG - fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d -> %d\n", - u, pts, prev->pos, old, cur->pos); -#endif - } else { -#ifdef MIKMOD_DEBUG - /* different brokenness style... fix unknown */ - fprintf(stderr, "\rbroken envelope position(%d/%d), %d %d\n", - u, pts, old, cur->pos); -#endif - old = cur->pos; - } - } else - old = cur->pos; - } -} - -static BOOL LoadInstruments(void) -{ - int t,u, ck; - INSTRUMENT *d; - ULONG next=0; - UWORD wavcnt=0; - - if(!AllocInstruments()) return 0; - d=of.instruments; - for(t=0;tsamplenumber,0xff,INSTNOTES*sizeof(UWORD)); - - /* read instrument header */ - headend = _mm_ftell(modreader); - ih.size = _mm_read_I_ULONG(modreader); - headend += ih.size; - ck = _mm_ftell(modreader); - _mm_fseek(modreader,0,SEEK_END); - if ((headend<0) || (_mm_ftell(modreader)insname = DupStr(ih.name,22,1); - - if((SWORD)ih.size>29) { - ih.ssize = _mm_read_I_ULONG(modreader); - if(((SWORD)ih.numsmp>0)&&(ih.numsmp<=XMNOTECNT)) { - XMPATCHHEADER pth; - int p; - - _mm_read_UBYTES (pth.what,XMNOTECNT,modreader); - _mm_read_I_UWORDS (pth.volenv, XMENVCNT, modreader); - _mm_read_I_UWORDS (pth.panenv, XMENVCNT, modreader); - pth.volpts = _mm_read_UBYTE(modreader); - pth.panpts = _mm_read_UBYTE(modreader); - pth.volsus = _mm_read_UBYTE(modreader); - pth.volbeg = _mm_read_UBYTE(modreader); - pth.volend = _mm_read_UBYTE(modreader); - pth.pansus = _mm_read_UBYTE(modreader); - pth.panbeg = _mm_read_UBYTE(modreader); - pth.panend = _mm_read_UBYTE(modreader); - pth.volflg = _mm_read_UBYTE(modreader); - pth.panflg = _mm_read_UBYTE(modreader); - pth.vibflg = _mm_read_UBYTE(modreader); - pth.vibsweep = _mm_read_UBYTE(modreader); - pth.vibdepth = _mm_read_UBYTE(modreader); - pth.vibrate = _mm_read_UBYTE(modreader); - pth.volfade = _mm_read_I_UWORD(modreader); - - /* read the remainder of the header - (2 bytes for 1.03, 22 for 1.04) */ - if (headend>=_mm_ftell(modreader)) for(u=headend-_mm_ftell(modreader);u;u--) _mm_read_UBYTE(modreader); - - /* we can't trust the envelope point count here, as some - modules have incorrect values (K_OSPACE.XM reports 32 volume - points, for example). */ - if(pth.volpts>XMENVCNT/2) pth.volpts=XMENVCNT/2; - if(pth.panpts>XMENVCNT/2) pth.panpts=XMENVCNT/2; - - if((_mm_eof(modreader))||(pth.volpts>XMENVCNT/2)||(pth.panpts>XMENVCNT/2)) { - if(nextwav) { free(nextwav);nextwav=NULL; } - if(wh) { free(wh);wh=NULL; } - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - - for(u=0;usamplenumber[u]=pth.what[u]+of.numsmp; - d->volfade = pth.volfade; - -#if defined __STDC__ || defined _MSC_VER -#define XM_ProcessEnvelope(name) \ - for (u = 0; u < (XMENVCNT >> 1); u++) { \ - d-> name##env[u].pos = pth. name##env[u << 1]; \ - d-> name##env[u].val = pth. name##env[(u << 1)+ 1]; \ - } \ - if (pth. name##flg&1) d-> name##flg|=EF_ON; \ - if (pth. name##flg&2) d-> name##flg|=EF_SUSTAIN; \ - if (pth. name##flg&4) d-> name##flg|=EF_LOOP; \ - d-> name##susbeg=d-> name##susend=pth. name##sus; \ - d-> name##beg=pth. name##beg; \ - d-> name##end=pth. name##end; \ - d-> name##pts=pth. name##pts; \ - \ - /* scale envelope */ \ - for (p=0;p name##env[p].val<<=2; \ - \ - if ((d-> name##flg&EF_ON)&&(d-> name##pts<2)) \ - d-> name##flg&=~EF_ON -#else -#define XM_ProcessEnvelope(name) \ - for (u = 0; u < (XMENVCNT >> 1); u++) { \ - d-> name/**/env[u].pos = pth. name/**/env[u << 1]; \ - d-> name/**/env[u].val = pth. name/**/env[(u << 1)+ 1]; \ - } \ - if (pth. name/**/flg&1) d-> name/**/flg|=EF_ON; \ - if (pth. name/**/flg&2) d-> name/**/flg|=EF_SUSTAIN; \ - if (pth. name/**/flg&4) d-> name/**/flg|=EF_LOOP; \ - d-> name/**/susbeg=d-> name/**/susend= \ - pth. name/**/sus; \ - d-> name/**/beg=pth. name/**/beg; \ - d-> name/**/end=pth. name/**/end; \ - d-> name/**/pts=pth. name/**/pts; \ - \ - /* scale envelope */ \ - for (p=0;p name/**/env[p].val<<=2; \ - \ - if ((d-> name/**/flg&EF_ON)&&(d-> name/**/pts<2)) \ - d-> name/**/flg&=~EF_ON -#endif - - XM_ProcessEnvelope(vol); - XM_ProcessEnvelope(pan); -#undef XM_ProcessEnvelope - - if (d->volflg & EF_ON) - FixEnvelope(d->volenv, d->volpts); - if (d->panflg & EF_ON) - FixEnvelope(d->panenv, d->panpts); - - /* Samples are stored outside the instrument struct now, so we - have to load them all into a temp area, count the of.numsmp - along the way and then do an AllocSamples() and move - everything over */ - if(mh->version>0x0103) next = 0; - for(u=0;ulength =_mm_read_I_ULONG (modreader); - s->loopstart =_mm_read_I_ULONG (modreader); - s->looplength =_mm_read_I_ULONG (modreader); - s->volume =_mm_read_UBYTE (modreader); - s->finetune =_mm_read_SBYTE (modreader); - s->type =_mm_read_UBYTE (modreader); - s->panning =_mm_read_UBYTE (modreader); - s->relnote =_mm_read_SBYTE (modreader); - s->vibtype = pth.vibflg; - s->vibsweep = pth.vibsweep; - s->vibdepth = pth.vibdepth*4; - s->vibrate = pth.vibrate; - s->reserved =_mm_read_UBYTE (modreader); - _mm_read_string(s->samplename, 22, modreader); - - nextwav[of.numsmp+u]=next; - next+=s->length; - - if(_mm_eof(modreader)) { - free(nextwav);free(wh); - nextwav=NULL;wh=NULL; - _mm_errno = MMERR_LOADING_SAMPLEINFO; - return 0; - } - } - - if(mh->version>0x0103) { - for(u=0;uid,17,modreader); - _mm_read_string(mh->songname,21,modreader); - _mm_read_string(mh->trackername,20,modreader); - mh->version =_mm_read_I_UWORD(modreader); - if((mh->version<0x102)||(mh->version>0x104)) { - _mm_errno=MMERR_NOT_A_MODULE; - return 0; - } - mh->headersize =_mm_read_I_ULONG(modreader); - mh->songlength =_mm_read_I_UWORD(modreader); - mh->restart =_mm_read_I_UWORD(modreader); - mh->numchn =_mm_read_I_UWORD(modreader); - mh->numpat =_mm_read_I_UWORD(modreader); - mh->numins =_mm_read_I_UWORD(modreader); - mh->flags =_mm_read_I_UWORD(modreader); - mh->tempo =_mm_read_I_UWORD(modreader); - mh->bpm =_mm_read_I_UWORD(modreader); - if(!mh->bpm) { - _mm_errno=MMERR_NOT_A_MODULE; - return 0; - } - _mm_read_UBYTES(mh->orders,256,modreader); - - if(_mm_eof(modreader)) { - _mm_errno = MMERR_LOADING_HEADER; - return 0; - } - - /* set module variables */ - of.initspeed = (UBYTE)mh->tempo; - of.inittempo = (UBYTE)mh->bpm; - strncpy(tracker,mh->trackername,20);tracker[20]=0; - for(t=20;(tracker[t]<=' ')&&(t>=0);t--) tracker[t]=0; - - /* some modules have the tracker name empty */ - if (!tracker[0]) - strcpy(tracker,"Unknown tracker"); - -#ifdef HAVE_SNPRINTF - snprintf(modtype,60,"%s (XM format %d.%02d)", - tracker,mh->version>>8,mh->version&0xff); -#else - sprintf(modtype,"%s (XM format %d.%02d)", - tracker,mh->version>>8,mh->version&0xff); -#endif - of.modtype = strdup(modtype); - of.numchn = mh->numchn; - of.numpat = mh->numpat; - of.numtrk = (UWORD)of.numpat*of.numchn; /* get number of channels */ - of.songname = DupStr(mh->songname,20,1); - of.numpos = mh->songlength; /* copy the songlength */ - of.reppos = mh->restartsonglength?mh->restart:0; - of.numins = mh->numins; - of.flags |= UF_XMPERIODS | UF_INST | UF_NOWRAP | UF_FT2QUIRKS | - UF_PANNING; - if(mh->flags&1) of.flags |= UF_LINEAR; - of.bpmlimit = 32; - - memset(of.chanvol,64,of.numchn); /* store channel volumes */ - - if(!AllocPositions(of.numpos+1)) return 0; - for(t=0;torders[t]; - - /* We have to check for any pattern numbers in the order list greater than - the number of patterns total. If one or more is found, we set it equal to - the pattern total and make a dummy pattern to workaround the problem */ - for(t=0;t=of.numpat) { - of.positions[t]=of.numpat; - dummypat=1; - } - } - if(dummypat) { - of.numpat++;of.numtrk+=of.numchn; - } - - if(mh->version<0x0104) { - if(!LoadInstruments()) return 0; - if(!LoadPatterns(dummypat)) return 0; - for(t=0;tsamplename = DupStr(s->samplename,22,1); - q->length = s->length; - q->loopstart = s->loopstart; - q->loopend = s->loopstart+s->looplength; - q->volume = s->volume; - q->speed = s->finetune+128; - q->panning = s->panning; - q->seekpos = nextwav[u]; - q->vibtype = s->vibtype; - q->vibsweep = s->vibsweep; - q->vibdepth = s->vibdepth; - q->vibrate = s->vibrate; - - if(s->type & 0x10) { - q->length >>= 1; - q->loopstart >>= 1; - q->loopend >>= 1; - } - - q->flags|=SF_OWNPAN|SF_DELTA|SF_SIGNED; - if(s->type&0x3) q->flags|=SF_LOOP; - if(s->type&0x2) q->flags|=SF_BIDI; - if(s->type&0x10) q->flags|=SF_16BITS; - } - - d=of.instruments; - s=wh; - for(u=0;usamplenumber[t]>=of.numsmp) - d->samplenote[t]=255; - else { - int note=t+s[d->samplenumber[t]].relnote; - d->samplenote[t]=(note<0)?0:note; - } - } - - free(wh);free(nextwav); - wh=NULL;nextwav=NULL; - return 1; -} - -CHAR *XM_LoadTitle(void) -{ - CHAR s[21]; - - _mm_fseek(modreader,17,SEEK_SET); - if(!_mm_read_UBYTES(s,21,modreader)) return NULL; - - return(DupStr(s,21,1)); -} - -/*========== Loader information */ - -MIKMODAPI MLOADER load_xm={ - NULL, - "XM", - "XM (FastTracker 2)", - XM_Init, - XM_Test, - XM_Load, - XM_Cleanup, - XM_LoadTitle -}; - -/* ex:set ts=4: */ diff --git a/mikmod/mdreg.c b/mikmod/mdreg.c deleted file mode 100644 index 45643a0d..00000000 --- a/mikmod/mdreg.c +++ /dev/null @@ -1,54 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Routine for registering all drivers in libmikmod for the current platform. - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mikmod_internals.h" - -void _mm_registeralldrivers(void) -{ - _mm_registerdriver(&drv_nos); -} - -void MikMod_RegisterAllDrivers(void) -{ - MUTEX_LOCK(lists); - _mm_registeralldrivers(); - MUTEX_UNLOCK(lists); -} - -void MikMod_UnregisterAllDrivers(void) -{ - MUTEX_LOCK(lists); - _mm_unregisterdrivers(); - MUTEX_UNLOCK(lists); -} - -/* ex:set ts=4: */ diff --git a/mikmod/mdriver.c b/mikmod/mdriver.c deleted file mode 100644 index 238996b2..00000000 --- a/mikmod/mdriver.c +++ /dev/null @@ -1,943 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - These routines are used to access the available soundcard drivers. - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#if defined unix || (defined __APPLE__ && defined __MACH__) -#include -#include -#endif - -#include -#ifdef HAVE_STRINGS_H -#include -#endif - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -static MDRIVER *firstdriver=NULL; -MIKMODAPI MDRIVER *md_driver=NULL; -extern MODULE *pf; /* modfile being played */ - -/* Initial global settings */ -MIKMODAPI UWORD md_device = 0; /* autodetect */ -MIKMODAPI UWORD md_mixfreq = 44100; -MIKMODAPI UWORD md_mode = DMODE_STEREO | DMODE_16BITS | - DMODE_SURROUND |DMODE_SOFT_MUSIC | - DMODE_SOFT_SNDFX; -MIKMODAPI UBYTE md_pansep = 128; /* 128 == 100% (full left/right) */ -MIKMODAPI UBYTE md_reverb = 0; /* no reverb */ -MIKMODAPI UBYTE md_volume = 128; /* global sound volume (0-128) */ -MIKMODAPI UBYTE md_musicvolume = 128; /* volume of song */ -MIKMODAPI UBYTE md_sndfxvolume = 128; /* volume of sound effects */ - UWORD md_bpm = 125; /* tempo */ - -/* Do not modify the numchn variables yourself! use MD_SetVoices() */ - UBYTE md_numchn=0,md_sngchn=0,md_sfxchn=0; - UBYTE md_hardchn=0,md_softchn=0; - - void (*md_player)(void) = Player_HandleTick; -static BOOL isplaying=0, initialized = 0; -static UBYTE *sfxinfo; -static int sfxpool; - -static SAMPLE **md_sample = NULL; - -/* Previous driver in use */ -static SWORD olddevice = -1; - -/* Limits the number of hardware voices to the specified amount. - This function should only be used by the low-level drivers. */ -static void LimitHardVoices(int limit) -{ - int t=0; - - if (!(md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn>limit)) md_sfxchn=limit; - if (!(md_mode & DMODE_SOFT_MUSIC) && (md_sngchn>limit)) md_sngchn=limit; - - if (!(md_mode & DMODE_SOFT_SNDFX)) - md_hardchn=md_sfxchn; - else - md_hardchn=0; - - if (!(md_mode & DMODE_SOFT_MUSIC)) md_hardchn += md_sngchn; - - while (md_hardchn>limit) { - if (++t & 1) { - if (!(md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn>4)) md_sfxchn--; - } else { - if (!(md_mode & DMODE_SOFT_MUSIC) && (md_sngchn>8)) md_sngchn--; - } - - if (!(md_mode & DMODE_SOFT_SNDFX)) - md_hardchn=md_sfxchn; - else - md_hardchn=0; - - if (!(md_mode & DMODE_SOFT_MUSIC)) - md_hardchn+=md_sngchn; - } - md_numchn=md_hardchn+md_softchn; -} - -/* Limits the number of hardware voices to the specified amount. - This function should only be used by the low-level drivers. */ -static void LimitSoftVoices(int limit) -{ - int t=0; - - if ((md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn>limit)) md_sfxchn=limit; - if ((md_mode & DMODE_SOFT_MUSIC) && (md_sngchn>limit)) md_sngchn=limit; - - if (md_mode & DMODE_SOFT_SNDFX) - md_softchn=md_sfxchn; - else - md_softchn=0; - - if (md_mode & DMODE_SOFT_MUSIC) md_softchn+=md_sngchn; - - while (md_softchn>limit) { - if (++t & 1) { - if ((md_mode & DMODE_SOFT_SNDFX) && (md_sfxchn>4)) md_sfxchn--; - } else { - if ((md_mode & DMODE_SOFT_MUSIC) && (md_sngchn>8)) md_sngchn--; - } - - if (!(md_mode & DMODE_SOFT_SNDFX)) - md_softchn=md_sfxchn; - else - md_softchn=0; - - if (!(md_mode & DMODE_SOFT_MUSIC)) - md_softchn+=md_sngchn; - } - md_numchn=md_hardchn+md_softchn; -} - -/* Note: 'type' indicates whether the returned value should be for music or for - sound effects. */ -ULONG MD_SampleSpace(int type) -{ - if(type==MD_MUSIC) - type=(md_mode & DMODE_SOFT_MUSIC)?MD_SOFTWARE:MD_HARDWARE; - else if(type==MD_SNDFX) - type=(md_mode & DMODE_SOFT_SNDFX)?MD_SOFTWARE:MD_HARDWARE; - - return md_driver->FreeSampleSpace(type); -} - -ULONG MD_SampleLength(int type,SAMPLE* s) -{ - if(type==MD_MUSIC) - type=(md_mode & DMODE_SOFT_MUSIC)?MD_SOFTWARE:MD_HARDWARE; - else - if(type==MD_SNDFX) - type=(md_mode & DMODE_SOFT_SNDFX)?MD_SOFTWARE:MD_HARDWARE; - - return md_driver->RealSampleLength(type,s); -} - -MIKMODAPI CHAR* MikMod_InfoDriver(void) -{ - int t,len=0; - MDRIVER *l; - CHAR *list=NULL; - - MUTEX_LOCK(lists); - /* compute size of buffer */ - for(l=firstdriver;l;l=l->next) - len+=4+(l->next?1:0)+strlen(l->Version); - - if(len) - if((list=_mm_malloc(len*sizeof(CHAR)))) { - list[0]=0; - /* list all registered device drivers : */ - for(t=1,l=firstdriver;l;l=l->next,t++) - sprintf(list,(l->next)?"%s%2d %s\n":"%s%2d %s", - list,t,l->Version); - } - MUTEX_UNLOCK(lists); - return list; -} - -void _mm_registerdriver(struct MDRIVER* drv) -{ - MDRIVER *cruise = firstdriver; - - /* don't register a MISSING() driver */ - if ((drv->Name) && (drv->Version)) { - if (cruise) { - while (cruise->next) cruise = cruise->next; - cruise->next = drv; - } else - firstdriver = drv; - } -} - -void _mm_unregisterdrivers(void) -{ - MDRIVER *cruise=firstdriver, *drv; - - while ( cruise ) { - drv = cruise; - cruise = cruise->next; - drv->next = NULL; - } - firstdriver = NULL; -} - -MIKMODAPI void MikMod_RegisterDriver(struct MDRIVER* drv) -{ - /* if we try to register an invalid driver, or an already registered driver, - ignore this attempt */ - if ((!drv)||(drv->next)||(!drv->Name)) - return; - - MUTEX_LOCK(lists); - _mm_registerdriver(drv); - MUTEX_UNLOCK(lists); -} - -MIKMODAPI int MikMod_DriverFromAlias(CHAR *alias) -{ - int rank=1; - MDRIVER *cruise; - - MUTEX_LOCK(lists); - cruise=firstdriver; - while(cruise) { - if (cruise->Alias) { - if (!(strcasecmp(alias,cruise->Alias))) break; - rank++; - } - cruise=cruise->next; - } - if(!cruise) rank=0; - MUTEX_UNLOCK(lists); - - return rank; -} - -SWORD MD_SampleLoad(SAMPLOAD* s, int type) -{ - SWORD result; - - if(type==MD_MUSIC) - type=(md_mode & DMODE_SOFT_MUSIC)?MD_SOFTWARE:MD_HARDWARE; - else if(type==MD_SNDFX) - type=(md_mode & DMODE_SOFT_SNDFX)?MD_SOFTWARE:MD_HARDWARE; - - SL_Init(s); - result=md_driver->SampleLoad(s,type); - SL_Exit(s); - - return result; -} - -void MD_SampleUnload(SWORD handle) -{ - md_driver->SampleUnload(handle); -} - -MIKMODAPI MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t player) -{ - MikMod_player_t result; - - MUTEX_LOCK(vars); - result=md_player; - md_player=player; - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI void MikMod_Update(void) -{ - MUTEX_LOCK(vars); - if(isplaying) { - if((!pf)||(!pf->forbid)) - md_driver->Update(); - else { - if (md_driver->Pause) - md_driver->Pause(); - } - } - MUTEX_UNLOCK(vars); -} - -void Voice_SetVolume_internal(SBYTE voice,UWORD vol) -{ - ULONG tmp; - - if((voice<0)||(voice>=md_numchn)) return; - - /* range checks */ - if(md_musicvolume>128) md_musicvolume=128; - if(md_sndfxvolume>128) md_sndfxvolume=128; - if(md_volume>128) md_volume=128; - - tmp=(ULONG)vol*(ULONG)md_volume* - ((voiceVoiceSetVolume(voice,tmp/16384UL); -} - -MIKMODAPI void Voice_SetVolume(SBYTE voice,UWORD vol) -{ - MUTEX_LOCK(vars); - Voice_SetVolume_internal(voice,vol); - MUTEX_UNLOCK(vars); -} - -MIKMODAPI UWORD Voice_GetVolume(SBYTE voice) -{ - UWORD result=0; - - MUTEX_LOCK(vars); - if((voice>=0)&&(voiceVoiceGetVolume(voice); - MUTEX_UNLOCK(vars); - - return result; -} - -void Voice_SetFrequency_internal(SBYTE voice,ULONG frq) -{ - if((voice<0)||(voice>=md_numchn)) return; - if((md_sample[voice])&&(md_sample[voice]->divfactor)) - frq/=md_sample[voice]->divfactor; - md_driver->VoiceSetFrequency(voice,frq); -} - -MIKMODAPI void Voice_SetFrequency(SBYTE voice,ULONG frq) -{ - MUTEX_LOCK(vars); - Voice_SetFrequency_internal(voice,frq); - MUTEX_UNLOCK(vars); -} - -MIKMODAPI ULONG Voice_GetFrequency(SBYTE voice) -{ - ULONG result=0; - - MUTEX_LOCK(vars); - if((voice>=0)&&(voiceVoiceGetFrequency(voice); - MUTEX_UNLOCK(vars); - - return result; -} - -void Voice_SetPanning_internal(SBYTE voice,ULONG pan) -{ - if((voice<0)||(voice>=md_numchn)) return; - if(pan!=PAN_SURROUND) { - if(md_pansep>128) md_pansep=128; - if(md_mode & DMODE_REVERSE) pan=255-pan; - pan = (((SWORD)(pan-128)*md_pansep)/128)+128; - } - md_driver->VoiceSetPanning(voice, pan); -} - -MIKMODAPI void Voice_SetPanning(SBYTE voice,ULONG pan) -{ -#ifdef MIKMOD_DEBUG - if((pan!=PAN_SURROUND)&&((pan<0)||(pan>255))) - fprintf(stderr,"\rVoice_SetPanning called with pan=%ld\n",(long)pan); -#endif - - MUTEX_LOCK(vars); - Voice_SetPanning_internal(voice,pan); - MUTEX_UNLOCK(vars); -} - -MIKMODAPI ULONG Voice_GetPanning(SBYTE voice) -{ - ULONG result=PAN_CENTER; - - MUTEX_LOCK(vars); - if((voice>=0)&&(voiceVoiceGetPanning(voice); - MUTEX_UNLOCK(vars); - - return result; -} - -void Voice_Play_internal(SBYTE voice,SAMPLE* s,ULONG start) -{ - ULONG repend; - - if((voice<0)||(voice>=md_numchn)) return; - - md_sample[voice]=s; - repend=s->loopend; - - if(s->flags&SF_LOOP) - /* repend can't be bigger than size */ - if(repend>s->length) repend=s->length; - - md_driver->VoicePlay(voice,s->handle,start,s->length,s->loopstart,repend,s->flags); -} - -MIKMODAPI void Voice_Play(SBYTE voice,SAMPLE* s,ULONG start) -{ - if(start>s->length) return; - - MUTEX_LOCK(vars); - Voice_Play_internal(voice,s,start); - MUTEX_UNLOCK(vars); -} - -void Voice_Stop_internal(SBYTE voice) -{ - if((voice<0)||(voice>=md_numchn)) return; - if(voice>=md_sngchn) - /* It is a sound effects channel, so flag the voice as non-critical! */ - sfxinfo[voice-md_sngchn]=0; - md_driver->VoiceStop(voice); -} - -MIKMODAPI void Voice_Stop(SBYTE voice) -{ - MUTEX_LOCK(vars); - Voice_Stop_internal(voice); - MUTEX_UNLOCK(vars); -} - -BOOL Voice_Stopped_internal(SBYTE voice) -{ - if((voice<0)||(voice>=md_numchn)) return 0; - return(md_driver->VoiceStopped(voice)); -} - -MIKMODAPI BOOL Voice_Stopped(SBYTE voice) -{ - BOOL result; - - MUTEX_LOCK(vars); - result=Voice_Stopped_internal(voice); - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI SLONG Voice_GetPosition(SBYTE voice) -{ - SLONG result=0; - - MUTEX_LOCK(vars); - if((voice>=0)&&(voiceVoiceGetPosition) - result=(md_driver->VoiceGetPosition(voice)); - else - result=-1; - } - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI ULONG Voice_RealVolume(SBYTE voice) -{ - ULONG result=0; - - MUTEX_LOCK(vars); - if((voice>=0)&&(voiceVoiceRealVolume) - result=(md_driver->VoiceRealVolume(voice)); - MUTEX_UNLOCK(vars); - - return result; -} - -static BOOL _mm_init(CHAR *cmdline) -{ - UWORD t; - - _mm_critical = 1; - - /* if md_device==0, try to find a device number */ - if(!md_device) { - cmdline=NULL; - - for(t=1,md_driver=firstdriver;md_driver;md_driver=md_driver->next,t++) - if(md_driver->IsPresent()) break; - - if(!md_driver) { - _mm_errno = MMERR_DETECTING_DEVICE; - if(_mm_errorhandler) _mm_errorhandler(); - md_driver = &drv_nos; - return 1; - } - - md_device = t; - } else { - /* if n>0, use that driver */ - for(t=1,md_driver=firstdriver;(md_driver)&&(t!=md_device);md_driver=md_driver->next) - t++; - - if(!md_driver) { - _mm_errno = MMERR_INVALID_DEVICE; - if(_mm_errorhandler) _mm_errorhandler(); - md_driver = &drv_nos; - return 1; - } - - /* arguments here might be necessary for the presence check to succeed */ - if(cmdline&&(md_driver->CommandLine)) - md_driver->CommandLine(cmdline); - - if(!md_driver->IsPresent()) { - _mm_errno = MMERR_DETECTING_DEVICE; - if(_mm_errorhandler) _mm_errorhandler(); - md_driver = &drv_nos; - return 1; - } - } - - olddevice = md_device; - if(md_driver->Init()) { - MikMod_Exit_internal(); - if(_mm_errorhandler) _mm_errorhandler(); - return 1; - } - - initialized=1; - _mm_critical=0; - - return 0; -} - -MIKMODAPI BOOL MikMod_Init(CHAR *cmdline) -{ - BOOL result; - - MUTEX_LOCK(vars); - MUTEX_LOCK(lists); - result=_mm_init(cmdline); - MUTEX_UNLOCK(lists); - MUTEX_UNLOCK(vars); - - return result; -} - -void MikMod_Exit_internal(void) -{ - MikMod_DisableOutput_internal(); - md_driver->Exit(); - md_numchn = md_sfxchn = md_sngchn = 0; - md_driver = &drv_nos; - - if(sfxinfo) free(sfxinfo); - if(md_sample) free(md_sample); - md_sample = NULL; - sfxinfo = NULL; - - initialized = 0; -} - -MIKMODAPI void MikMod_Exit(void) -{ - MUTEX_LOCK(vars); - MUTEX_LOCK(lists); - MikMod_Exit_internal(); - MUTEX_UNLOCK(lists); - MUTEX_UNLOCK(vars); -} - -/* Reset the driver using the new global variable settings. - If the driver has not been initialized, it will be now. */ -static BOOL _mm_reset(CHAR *cmdline) -{ - BOOL wasplaying = 0; - - if(!initialized) return _mm_init(cmdline); - - if (isplaying) { - wasplaying = 1; - md_driver->PlayStop(); - } - - if((!md_driver->Reset)||(md_device != olddevice)) { - /* md_driver->Reset was NULL, or md_device was changed, so do a full - reset of the driver. */ - md_driver->Exit(); - if(_mm_init(cmdline)) { - MikMod_Exit_internal(); - if(_mm_errno) - if(_mm_errorhandler) _mm_errorhandler(); - return 1; - } - } else { - if(md_driver->Reset()) { - MikMod_Exit_internal(); - if(_mm_errno) - if(_mm_errorhandler) _mm_errorhandler(); - return 1; - } - } - - if (wasplaying) md_driver->PlayStart(); - return 0; -} - -MIKMODAPI BOOL MikMod_Reset(CHAR *cmdline) -{ - BOOL result; - - MUTEX_LOCK(vars); - MUTEX_LOCK(lists); - result=_mm_reset(cmdline); - MUTEX_UNLOCK(lists); - MUTEX_UNLOCK(vars); - - return result; -} - -/* If either parameter is -1, the current set value will be retained. */ -BOOL MikMod_SetNumVoices_internal(int music, int sfx) -{ - BOOL resume = 0; - int t, oldchn = 0; - - if((!music)&&(!sfx)) return 1; - _mm_critical = 1; - if(isplaying) { - MikMod_DisableOutput_internal(); - oldchn = md_numchn; - resume = 1; - } - - if(sfxinfo) free(sfxinfo); - if(md_sample) free(md_sample); - md_sample = NULL; - sfxinfo = NULL; - - if(music!=-1) md_sngchn = music; - if(sfx!=-1) md_sfxchn = sfx; - md_numchn = md_sngchn + md_sfxchn; - - LimitHardVoices(md_driver->HardVoiceLimit); - LimitSoftVoices(md_driver->SoftVoiceLimit); - - if(md_driver->SetNumVoices()) { - MikMod_Exit_internal(); - if(_mm_errno) - if(_mm_errorhandler!=NULL) _mm_errorhandler(); - md_numchn = md_softchn = md_hardchn = md_sfxchn = md_sngchn = 0; - return 1; - } - - if(md_sngchn+md_sfxchn) - md_sample=(SAMPLE**)_mm_calloc(md_sngchn+md_sfxchn,sizeof(SAMPLE*)); - if(md_sfxchn) - sfxinfo = (UBYTE *)_mm_calloc(md_sfxchn,sizeof(UBYTE)); - - /* make sure the player doesn't start with garbage */ - for(t=oldchn;tPlayStart()) return 1; - isplaying = 1; - } - _mm_critical = 0; - return 0; -} - -MIKMODAPI BOOL MikMod_EnableOutput(void) -{ - BOOL result; - - MUTEX_LOCK(vars); - result=MikMod_EnableOutput_internal(); - MUTEX_UNLOCK(vars); - - return result; -} - -void MikMod_DisableOutput_internal(void) -{ - if(isplaying && md_driver) { - isplaying = 0; - md_driver->PlayStop(); - } -} - -MIKMODAPI void MikMod_DisableOutput(void) -{ - MUTEX_LOCK(vars); - MikMod_DisableOutput_internal(); - MUTEX_UNLOCK(vars); -} - -BOOL MikMod_Active_internal(void) -{ - return isplaying; -} - -MIKMODAPI BOOL MikMod_Active(void) -{ - BOOL result; - - MUTEX_LOCK(vars); - result=MikMod_Active_internal(); - MUTEX_UNLOCK(vars); - - return result; -} - -/* Plays a sound effects sample. Picks a voice from the number of voices - allocated for use as sound effects (loops through voices, skipping all active - criticals). - - Returns the voice that the sound is being played on. */ -SBYTE Sample_Play_internal(SAMPLE *s,ULONG start,UBYTE flags) -{ - int orig=sfxpool;/* for cases where all channels are critical */ - int c; - - if(!md_sfxchn) return -1; - if(s->volume>64) s->volume = 64; - - /* check the first location after sfxpool */ - do { - if(sfxinfo[sfxpool]&SFX_CRITICAL) { - if(md_driver->VoiceStopped(c=sfxpool+md_sngchn)) { - sfxinfo[sfxpool]=flags; - Voice_Play_internal(c,s,start); - md_driver->VoiceSetVolume(c,s->volume<<2); - Voice_SetPanning_internal(c,s->panning); - md_driver->VoiceSetFrequency(c,s->speed); - sfxpool++; - if(sfxpool>=md_sfxchn) sfxpool=0; - return c; - } - } else { - sfxinfo[sfxpool]=flags; - Voice_Play_internal(c=sfxpool+md_sngchn,s,start); - md_driver->VoiceSetVolume(c,s->volume<<2); - Voice_SetPanning_internal(c,s->panning); - md_driver->VoiceSetFrequency(c,s->speed); - sfxpool++; - if(sfxpool>=md_sfxchn) sfxpool=0; - return c; - } - - sfxpool++; - if(sfxpool>=md_sfxchn) sfxpool = 0; - } while(sfxpool!=orig); - - return -1; -} - -MIKMODAPI SBYTE Sample_Play(SAMPLE *s,ULONG start,UBYTE flags) -{ - SBYTE result; - - MUTEX_LOCK(vars); - result=Sample_Play_internal(s,start,flags); - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI long MikMod_GetVersion(void) -{ - return LIBMIKMOD_VERSION; -} - -/*========== MT-safe stuff */ - -#ifdef HAVE_PTHREAD -#define INIT_MUTEX(name) \ - pthread_mutex_t _mm_mutex_##name=PTHREAD_MUTEX_INITIALIZER -#elif defined(__OS2__)||defined(__EMX__) -#define INIT_MUTEX(name) \ - HMTX _mm_mutex_##name -#elif defined(WIN32) -#define INIT_MUTEX(name) \ - HANDLE _mm_mutex_##name -#else -#define INIT_MUTEX(name) -#endif - -INIT_MUTEX(vars); -INIT_MUTEX(lists); - -MIKMODAPI BOOL MikMod_InitThreads(void) -{ - static int firstcall=1; - static int result=0; - - if (firstcall) { - firstcall=0; -#ifdef HAVE_PTHREAD - result=1; -#elif defined(__OS2__)||defined(__EMX__) - if(DosCreateMutexSem((PSZ)NULL,&_mm_mutex_lists,0,0) || - DosCreateMutexSem((PSZ)NULL,&_mm_mutex_vars,0,0)) { - _mm_mutex_lists=_mm_mutex_vars=(HMTX)NULL; - result=0; - } else - result=1; -#elif defined(WIN32) - if((!(_mm_mutex_lists=CreateMutex(NULL,FALSE,"libmikmod(lists)")))|| - (!(_mm_mutex_vars=CreateMutex(NULL,FALSE,"libmikmod(vars)")))) - result=0; - else - result=1; -#endif - } - return result; -} - -MIKMODAPI void MikMod_Unlock(void) -{ - MUTEX_UNLOCK(lists); - MUTEX_UNLOCK(vars); -} - -MIKMODAPI void MikMod_Lock(void) -{ - MUTEX_LOCK(vars); - MUTEX_LOCK(lists); -} - -/*========== Parameter extraction helper */ - -CHAR *MD_GetAtom(CHAR *atomname,CHAR *cmdline,BOOL implicit) -{ - CHAR *ret=NULL; - - if(cmdline) { - CHAR *buf=strstr(cmdline,atomname); - - if((buf)&&((buf==cmdline)||(*(buf-1)==','))) { - CHAR *ptr=buf+strlen(atomname); - - if(*ptr=='=') { - for(buf=++ptr;(*ptr)&&((*ptr)!=',');ptr++); - ret=_mm_malloc((1+ptr-buf)*sizeof(CHAR)); - if(ret) - strncpy(ret,buf,ptr-buf); - } else if((*ptr==',')||(!*ptr)) { - if(implicit) { - ret=_mm_malloc((1+ptr-buf)*sizeof(CHAR)); - if(ret) - strncpy(ret,buf,ptr-buf); - } - } - } - } - return ret; -} - -#if defined unix || (defined __APPLE__ && defined __MACH__) - -/*========== Posix helper functions */ - -/* Check if the file is a regular or nonexistant file (or a link to a such a - file), and that, should the calling program be setuid, the access rights are - reasonable. Returns 1 if it is safe to rewrite the file, 0 otherwise. - The goal is to prevent a setuid root libmikmod application from overriding - files like /etc/passwd with digital sound... */ -BOOL MD_Access(CHAR *filename) -{ - struct stat buf; - - if(!stat(filename,&buf)) { - /* not a regular file ? */ - if(!S_ISREG(buf.st_mode)) return 0; - /* more than one hard link to the file ? */ - if(buf.st_nlink>1) return 0; - /* check access rights with the real user and group id */ - if(getuid()==buf.st_uid) { - if(!(buf.st_mode&S_IWUSR)) return 0; - } else if(getgid()==buf.st_gid) { - if(!(buf.st_mode&S_IWGRP)) return 0; - } else - if(!(buf.st_mode&S_IWOTH)) return 0; - } - - return 1; -} - -/* Drop all root privileges we might have */ -BOOL MD_DropPrivileges(void) -{ - if(!geteuid()) { - if(getuid()) { - /* we are setuid root -> drop setuid to become the real user */ - if(setuid(getuid())) return 1; - } else { - /* we are run as root -> drop all and become user 'nobody' */ - struct passwd *nobody; - int uid; - - if(!(nobody=getpwnam("nobody"))) return 1; /* no such user ? */ - uid=nobody->pw_uid; - if (!uid) /* user 'nobody' has root privileges ? weird... */ - return 1; - if (setuid(uid)) return 1; - } - } - return 0; -} - -#endif - -/* ex:set ts=4: */ diff --git a/mikmod/mikmod.h b/mikmod/mikmod.h deleted file mode 100644 index 6f2443d1..00000000 --- a/mikmod/mikmod.h +++ /dev/null @@ -1,741 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - MikMod sound library include file - -==============================================================================*/ - -#ifndef _MIKMOD_H_ -#define _MIKMOD_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * ========== Compiler magic for shared libraries - */ - -#if defined WIN32 && defined _DLL -#ifdef DLL_EXPORTS -#define MIKMODAPI __declspec(dllexport) -#else -#define MIKMODAPI __declspec(dllimport) -#endif -#else -#define MIKMODAPI -#endif - -/* - * ========== Library version - */ - -#define LIBMIKMOD_VERSION_MAJOR 3L -#define LIBMIKMOD_VERSION_MINOR 1L -#define LIBMIKMOD_REVISION 10L - -#define LIBMIKMOD_VERSION \ - ((LIBMIKMOD_VERSION_MAJOR<<16)| \ - (LIBMIKMOD_VERSION_MINOR<< 8)| \ - (LIBMIKMOD_REVISION)) - -MIKMODAPI extern long MikMod_GetVersion(void); - -/* - * ========== Platform independent-type definitions - */ - -#if 1 -#include "SDL_types.h" - -typedef Sint8 SBYTE; /* 1 byte, signed */ -typedef Uint8 UBYTE; /* 1 byte, unsigned */ -typedef Sint16 SWORD; /* 2 bytes, signed */ -typedef Uint16 UWORD; /* 2 bytes, unsigned */ -typedef Sint32 SLONG; /* 4 bytes, signed */ -typedef Uint32 ULONG; /* 4 bytes, unsigned */ -typedef int BOOL; /* 0=false, <>0 true */ -typedef char CHAR; - -#else -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#endif - -#if defined(__OS2__)||defined(__EMX__) -#define INCL_DOSSEMAPHORES -#include -#else -#ifndef WIN32 -typedef char CHAR; -#endif -#endif - - - -#if defined(__arch64__) || defined(__alpha) || defined(__x86_64) || defined(_LP64) -/* 64 bit architectures */ - -typedef signed char SBYTE; /* 1 byte, signed */ -typedef unsigned char UBYTE; /* 1 byte, unsigned */ -typedef signed short SWORD; /* 2 bytes, signed */ -typedef unsigned short UWORD; /* 2 bytes, unsigned */ -typedef signed int SLONG; /* 4 bytes, signed */ -typedef unsigned int ULONG; /* 4 bytes, unsigned */ -typedef int BOOL; /* 0=false, <>0 true */ - -#else -/* 32 bit architectures */ - -typedef signed char SBYTE; /* 1 byte, signed */ -typedef unsigned char UBYTE; /* 1 byte, unsigned */ -typedef signed short SWORD; /* 2 bytes, signed */ -typedef unsigned short UWORD; /* 2 bytes, unsigned */ -typedef signed long SLONG; /* 4 bytes, signed */ -#if !defined(__OS2__) && !defined(__EMX__) && !defined(_WIN32) -typedef unsigned long ULONG; /* 4 bytes, unsigned */ -typedef int BOOL; /* 0=false, <>0 true */ -#endif -#endif -#endif /* 1 */ - -/* - * ========== Error codes - */ - -enum { - MMERR_OPENING_FILE = 1, - MMERR_OUT_OF_MEMORY, - MMERR_DYNAMIC_LINKING, - - MMERR_SAMPLE_TOO_BIG, - MMERR_OUT_OF_HANDLES, - MMERR_UNKNOWN_WAVE_TYPE, - - MMERR_LOADING_PATTERN, - MMERR_LOADING_TRACK, - MMERR_LOADING_HEADER, - MMERR_LOADING_SAMPLEINFO, - MMERR_NOT_A_MODULE, - MMERR_NOT_A_STREAM, - MMERR_MED_SYNTHSAMPLES, - MMERR_ITPACK_INVALID_DATA, - - MMERR_DETECTING_DEVICE, - MMERR_INVALID_DEVICE, - MMERR_INITIALIZING_MIXER, - MMERR_OPENING_AUDIO, - MMERR_8BIT_ONLY, - MMERR_16BIT_ONLY, - MMERR_STEREO_ONLY, - MMERR_ULAW, - MMERR_NON_BLOCK, - - MMERR_AF_AUDIO_PORT, - - MMERR_AIX_CONFIG_INIT, - MMERR_AIX_CONFIG_CONTROL, - MMERR_AIX_CONFIG_START, - - MMERR_GUS_SETTINGS, - MMERR_GUS_RESET, - MMERR_GUS_TIMER, - - MMERR_HP_SETSAMPLESIZE, - MMERR_HP_SETSPEED, - MMERR_HP_CHANNELS, - MMERR_HP_AUDIO_OUTPUT, - MMERR_HP_AUDIO_DESC, - MMERR_HP_BUFFERSIZE, - - MMERR_OSS_SETFRAGMENT, - MMERR_OSS_SETSAMPLESIZE, - MMERR_OSS_SETSTEREO, - MMERR_OSS_SETSPEED, - - MMERR_SGI_SPEED, - MMERR_SGI_16BIT, - MMERR_SGI_8BIT, - MMERR_SGI_STEREO, - MMERR_SGI_MONO, - - MMERR_SUN_INIT, - - MMERR_OS2_MIXSETUP, - MMERR_OS2_SEMAPHORE, - MMERR_OS2_TIMER, - MMERR_OS2_THREAD, - - MMERR_DS_PRIORITY, - MMERR_DS_BUFFER, - MMERR_DS_FORMAT, - MMERR_DS_NOTIFY, - MMERR_DS_EVENT, - MMERR_DS_THREAD, - MMERR_DS_UPDATE, - - MMERR_WINMM_HANDLE, - MMERR_WINMM_ALLOCATED, - MMERR_WINMM_DEVICEID, - MMERR_WINMM_FORMAT, - MMERR_WINMM_UNKNOWN, - - MMERR_MAC_SPEED, - MMERR_MAC_START, - - MMERR_MAX -}; - -/* - * ========== Error handling - */ - -typedef void (MikMod_handler)(void); -typedef MikMod_handler *MikMod_handler_t; - -MIKMODAPI extern int MikMod_errno; -MIKMODAPI extern BOOL MikMod_critical; -MIKMODAPI extern char *MikMod_strerror(int); - -MIKMODAPI extern MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t); - -/* - * ========== Library initialization and core functions - */ - -struct MDRIVER; - -MIKMODAPI extern void MikMod_RegisterAllDrivers(void); -MIKMODAPI extern void MikMod_UnregisterAllDrivers(void); - -MIKMODAPI extern CHAR* MikMod_InfoDriver(void); -MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*); -MIKMODAPI extern int MikMod_DriverFromAlias(CHAR*); - -MIKMODAPI extern BOOL MikMod_Init(CHAR*); -MIKMODAPI extern void MikMod_Exit(void); -MIKMODAPI extern BOOL MikMod_Reset(CHAR*); -MIKMODAPI extern BOOL MikMod_SetNumVoices(int,int); -MIKMODAPI extern BOOL MikMod_Active(void); -MIKMODAPI extern BOOL MikMod_EnableOutput(void); -MIKMODAPI extern void MikMod_DisableOutput(void); -MIKMODAPI extern void MikMod_Update(void); - -MIKMODAPI extern BOOL MikMod_InitThreads(void); -MIKMODAPI extern void MikMod_Lock(void); -MIKMODAPI extern void MikMod_Unlock(void); - -/* - * ========== Reader, Writer - */ - -typedef struct MREADER { - BOOL (*Seek)(struct MREADER*,long,int); - long (*Tell)(struct MREADER*); - BOOL (*Read)(struct MREADER*,void*,size_t); - int (*Get)(struct MREADER*); - BOOL (*Eof)(struct MREADER*); -} MREADER; - -typedef struct MWRITER { - BOOL (*Seek)(struct MWRITER*,long,int); - long (*Tell)(struct MWRITER*); - BOOL (*Write)(struct MWRITER*,void*,size_t); - BOOL (*Put)(struct MWRITER*,int); -} MWRITER; - -/* - * ========== Samples - */ - -/* Sample playback should not be interrupted */ -#define SFX_CRITICAL 1 - -/* Sample format [loading and in-memory] flags: */ -#define SF_16BITS 0x0001 -#define SF_STEREO 0x0002 -#define SF_SIGNED 0x0004 -#define SF_BIG_ENDIAN 0x0008 -#define SF_DELTA 0x0010 -#define SF_ITPACKED 0x0020 - -#define SF_FORMATMASK 0x003F - -/* General Playback flags */ - -#define SF_LOOP 0x0100 -#define SF_BIDI 0x0200 -#define SF_REVERSE 0x0400 -#define SF_SUSTAIN 0x0800 - -#define SF_PLAYBACKMASK 0x0C00 - -/* Module-only Playback Flags */ - -#define SF_OWNPAN 0x1000 -#define SF_UST_LOOP 0x2000 - -#define SF_EXTRAPLAYBACKMASK 0x3000 - -/* Panning constants */ -#define PAN_LEFT 0 -#define PAN_HALFLEFT 64 -#define PAN_CENTER 128 -#define PAN_HALFRIGHT 192 -#define PAN_RIGHT 255 -#define PAN_SURROUND 512 /* panning value for Dolby Surround */ - -typedef struct SAMPLE { - SWORD panning; /* panning (0-255 or PAN_SURROUND) */ - ULONG speed; /* Base playing speed/frequency of note */ - UBYTE volume; /* volume 0-64 */ - UWORD inflags; /* sample format on disk */ - UWORD flags; /* sample format in memory */ - ULONG length; /* length of sample (in samples!) */ - ULONG loopstart; /* repeat position (relative to start, in samples) */ - ULONG loopend; /* repeat end */ - ULONG susbegin; /* sustain loop begin (in samples) \ Not Supported */ - ULONG susend; /* sustain loop end / Yet! */ - - /* Variables used by the module player only! (ignored for sound effects) */ - UBYTE globvol; /* global volume */ - UBYTE vibflags; /* autovibrato flag stuffs */ - UBYTE vibtype; /* Vibratos moved from INSTRUMENT to SAMPLE */ - UBYTE vibsweep; - UBYTE vibdepth; - UBYTE vibrate; - CHAR* samplename; /* name of the sample */ - - /* Values used internally only */ - UWORD avibpos; /* autovibrato pos [player use] */ - UBYTE divfactor; /* for sample scaling, maintains proper period slides */ - ULONG seekpos; /* seek position in file */ - SWORD handle; /* sample handle used by individual drivers */ -} SAMPLE; - -/* Sample functions */ - -MIKMODAPI extern SAMPLE *Sample_Load(CHAR*); -MIKMODAPI extern SAMPLE *Sample_LoadFP(FILE*); -MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*); -MIKMODAPI extern void Sample_Free(SAMPLE*); -MIKMODAPI extern SBYTE Sample_Play(SAMPLE*,ULONG,UBYTE); - -MIKMODAPI extern void Voice_SetVolume(SBYTE,UWORD); -MIKMODAPI extern UWORD Voice_GetVolume(SBYTE); -MIKMODAPI extern void Voice_SetFrequency(SBYTE,ULONG); -MIKMODAPI extern ULONG Voice_GetFrequency(SBYTE); -MIKMODAPI extern void Voice_SetPanning(SBYTE,ULONG); -MIKMODAPI extern ULONG Voice_GetPanning(SBYTE); -MIKMODAPI extern void Voice_Play(SBYTE,SAMPLE*,ULONG); -MIKMODAPI extern void Voice_Stop(SBYTE); -MIKMODAPI extern BOOL Voice_Stopped(SBYTE); -MIKMODAPI extern SLONG Voice_GetPosition(SBYTE); -MIKMODAPI extern ULONG Voice_RealVolume(SBYTE); - -/* - * ========== Internal module representation (UniMod) - */ - -/* - Instrument definition - for information only, the only field which may be - of use in user programs is the name field -*/ - -/* Instrument note count */ -#define INSTNOTES 120 - -/* Envelope point */ -typedef struct ENVPT { - SWORD pos; - SWORD val; -} ENVPT; - -/* Envelope point count */ -#define ENVPOINTS 32 - -/* Instrument structure */ -typedef struct INSTRUMENT { - CHAR* insname; - - UBYTE flags; - UWORD samplenumber[INSTNOTES]; - UBYTE samplenote[INSTNOTES]; - - UBYTE nnatype; - UBYTE dca; /* duplicate check action */ - UBYTE dct; /* duplicate check type */ - UBYTE globvol; - UWORD volfade; - SWORD panning; /* instrument-based panning var */ - - UBYTE pitpansep; /* pitch pan separation (0 to 255) */ - UBYTE pitpancenter; /* pitch pan center (0 to 119) */ - UBYTE rvolvar; /* random volume varations (0 - 100%) */ - UBYTE rpanvar; /* random panning varations (0 - 100%) */ - - /* volume envelope */ - UBYTE volflg; /* bit 0: on 1: sustain 2: loop */ - UBYTE volpts; - UBYTE volsusbeg; - UBYTE volsusend; - UBYTE volbeg; - UBYTE volend; - ENVPT volenv[ENVPOINTS]; - /* panning envelope */ - UBYTE panflg; /* bit 0: on 1: sustain 2: loop */ - UBYTE panpts; - UBYTE pansusbeg; - UBYTE pansusend; - UBYTE panbeg; - UBYTE panend; - ENVPT panenv[ENVPOINTS]; - /* pitch envelope */ - UBYTE pitflg; /* bit 0: on 1: sustain 2: loop */ - UBYTE pitpts; - UBYTE pitsusbeg; - UBYTE pitsusend; - UBYTE pitbeg; - UBYTE pitend; - ENVPT pitenv[ENVPOINTS]; -} INSTRUMENT; - -struct MP_CONTROL; -struct MP_VOICE; - -/* - Module definition -*/ - -/* maximum master channels supported */ -#define UF_MAXCHAN 64 - -/* Module flags */ -#define UF_XMPERIODS 0x0001 /* XM periods / finetuning */ -#define UF_LINEAR 0x0002 /* LINEAR periods (UF_XMPERIODS must be set) */ -#define UF_INST 0x0004 /* Instruments are used */ -#define UF_NNA 0x0008 /* IT: NNA used, set numvoices rather - than numchn */ -#define UF_S3MSLIDES 0x0010 /* uses old S3M volume slides */ -#define UF_BGSLIDES 0x0020 /* continue volume slides in the background */ -#define UF_HIGHBPM 0x0040 /* MED: can use >255 bpm */ -#define UF_NOWRAP 0x0080 /* XM-type (i.e. illogical) pattern break - semantics */ -#define UF_ARPMEM 0x0100 /* IT: need arpeggio memory */ -#define UF_FT2QUIRKS 0x0200 /* emulate some FT2 replay quirks */ -#define UF_PANNING 0x0400 /* module uses panning effects or have - non-tracker default initial panning */ - -typedef struct MODULE { - /* general module information */ - CHAR* songname; /* name of the song */ - CHAR* modtype; /* string type of module loaded */ - CHAR* comment; /* module comments */ - - UWORD flags; /* See module flags above */ - UBYTE numchn; /* number of module channels */ - UBYTE numvoices; /* max # voices used for full NNA playback */ - UWORD numpos; /* number of positions in this song */ - UWORD numpat; /* number of patterns in this song */ - UWORD numins; /* number of instruments */ - UWORD numsmp; /* number of samples */ -struct INSTRUMENT* instruments; /* all instruments */ -struct SAMPLE* samples; /* all samples */ - UBYTE realchn; /* real number of channels used */ - UBYTE totalchn; /* total number of channels used (incl NNAs) */ - - /* playback settings */ - UWORD reppos; /* restart position */ - UBYTE initspeed; /* initial song speed */ - UWORD inittempo; /* initial song tempo */ - UBYTE initvolume; /* initial global volume (0 - 128) */ - UWORD panning[UF_MAXCHAN]; /* panning positions */ - UBYTE chanvol[UF_MAXCHAN]; /* channel positions */ - UWORD bpm; /* current beats-per-minute speed */ - UWORD sngspd; /* current song speed */ - SWORD volume; /* song volume (0-128) (or user volume) */ - - BOOL extspd; /* extended speed flag (default enabled) */ - BOOL panflag; /* panning flag (default enabled) */ - BOOL wrap; /* wrap module ? (default disabled) */ - BOOL loop; /* allow module to loop ? (default enabled) */ - BOOL fadeout; /* volume fade out during last pattern */ - - UWORD patpos; /* current row number */ - SWORD sngpos; /* current song position */ - ULONG sngtime; /* current song time in 2^-10 seconds */ - - SWORD relspd; /* relative speed factor */ - - /* internal module representation */ - UWORD numtrk; /* number of tracks */ - UBYTE** tracks; /* array of numtrk pointers to tracks */ - UWORD* patterns; /* array of Patterns */ - UWORD* pattrows; /* array of number of rows for each pattern */ - UWORD* positions; /* all positions */ - - BOOL forbid; /* if true, no player update! */ - UWORD numrow; /* number of rows on current pattern */ - UWORD vbtick; /* tick counter (counts from 0 to sngspd) */ - UWORD sngremainder;/* used for song time computation */ - -struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */ -struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */ - - UBYTE globalslide; /* global volume slide rate */ - UBYTE pat_repcrazy;/* module has just looped to position -1 */ - UWORD patbrk; /* position where to start a new pattern */ - UBYTE patdly; /* patterndelay counter (command memory) */ - UBYTE patdly2; /* patterndelay counter (real one) */ - SWORD posjmp; /* flag to indicate a jump is needed... */ - UWORD bpmlimit; /* threshold to detect bpm or speed values */ -} MODULE; - -/* - * ========== Module loaders - */ - -struct MLOADER; - -MIKMODAPI extern CHAR* MikMod_InfoLoader(void); -MIKMODAPI extern void MikMod_RegisterAllLoaders(void); -MIKMODAPI extern void MikMod_UnregisterAllLoaders(void); -MIKMODAPI extern void MikMod_RegisterLoader(struct MLOADER*); - -MIKMODAPI extern struct MLOADER load_669; /* 669 and Extended-669 (by Tran/Renaissance) */ -MIKMODAPI extern struct MLOADER load_amf; /* DMP Advanced Module Format (by Otto Chrons) */ -MIKMODAPI extern struct MLOADER load_dsm; /* DSIK internal module format */ -MIKMODAPI extern struct MLOADER load_far; /* Farandole Composer (by Daniel Potter) */ -MIKMODAPI extern struct MLOADER load_gdm; /* General DigiMusic (by Edward Schlunder) */ -MIKMODAPI extern struct MLOADER load_it; /* Impulse Tracker (by Jeffrey Lim) */ -MIKMODAPI extern struct MLOADER load_imf; /* Imago Orpheus (by Lutz Roeder) */ -MIKMODAPI extern struct MLOADER load_med; /* Amiga MED modules (by Teijo Kinnunen) */ -MIKMODAPI extern struct MLOADER load_m15; /* Soundtracker 15-instrument */ -MIKMODAPI extern struct MLOADER load_mod; /* Standard 31-instrument Module loader */ -MIKMODAPI extern struct MLOADER load_mtm; /* Multi-Tracker Module (by Renaissance) */ -MIKMODAPI extern struct MLOADER load_okt; /* Amiga Oktalyzer */ -MIKMODAPI extern struct MLOADER load_stm; /* ScreamTracker 2 (by Future Crew) */ -MIKMODAPI extern struct MLOADER load_stx; /* STMIK 0.2 (by Future Crew) */ -MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (by Future Crew) */ -MIKMODAPI extern struct MLOADER load_ult; /* UltraTracker (by MAS) */ -MIKMODAPI extern struct MLOADER load_uni; /* MikMod and APlayer internal module format */ -MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */ - -/* - * ========== Module player - */ - -/* SDL_RWops compatability */ -#include "SDL_rwops.h" -MIKMODAPI extern MODULE* Player_LoadRW(SDL_RWops*,int,BOOL); -/* End SDL_RWops compatability */ -MIKMODAPI extern MODULE* Player_Load(CHAR*,int,BOOL); -MIKMODAPI extern MODULE* Player_LoadFP(FILE*,int,BOOL); -MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,BOOL); -MIKMODAPI extern CHAR* Player_LoadTitle(CHAR*); -MIKMODAPI extern CHAR* Player_LoadTitleFP(FILE*); -MIKMODAPI extern void Player_Free(MODULE*); -MIKMODAPI extern void Player_Start(MODULE*); -MIKMODAPI extern BOOL Player_Active(void); -MIKMODAPI extern void Player_Stop(void); -MIKMODAPI extern void Player_TogglePause(void); -MIKMODAPI extern BOOL Player_Paused(void); -MIKMODAPI extern void Player_NextPosition(void); -MIKMODAPI extern void Player_PrevPosition(void); -MIKMODAPI extern void Player_SetPosition(UWORD); -MIKMODAPI extern BOOL Player_Muted(UBYTE); -MIKMODAPI extern void Player_SetVolume(SWORD); -MIKMODAPI extern MODULE* Player_GetModule(void); -MIKMODAPI extern void Player_SetSpeed(UWORD); -MIKMODAPI extern void Player_SetTempo(UWORD); -MIKMODAPI extern void Player_Unmute(SLONG,...); -MIKMODAPI extern void Player_Mute(SLONG,...); -MIKMODAPI extern void Player_ToggleMute(SLONG,...); -MIKMODAPI extern int Player_GetChannelVoice(UBYTE); -MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE); -MIKMODAPI extern void Player_SetSynchroValue(int); -MIKMODAPI extern int Player_GetSynchroValue(void); - -typedef void (MikMod_player)(void); -typedef MikMod_player *MikMod_player_t; - -MIKMODAPI extern MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t); - -#define MUTE_EXCLUSIVE 32000 -#define MUTE_INCLUSIVE 32001 - -/* - * ========== Drivers - */ - -enum { - MD_MUSIC = 0, - MD_SNDFX -}; - -enum { - MD_HARDWARE = 0, - MD_SOFTWARE -}; - -/* Mixing flags */ - -/* These ones take effect only after MikMod_Init or MikMod_Reset */ -#define DMODE_16BITS 0x0001 /* enable 16 bit output */ -#define DMODE_STEREO 0x0002 /* enable stereo output */ -#define DMODE_SOFT_SNDFX 0x0004 /* Process sound effects via software mixer */ -#define DMODE_SOFT_MUSIC 0x0008 /* Process music via software mixer */ -#define DMODE_HQMIXER 0x0010 /* Use high-quality (slower) software mixer */ -/* These take effect immediately. */ -#define DMODE_SURROUND 0x0100 /* enable surround sound */ -#define DMODE_INTERP 0x0200 /* enable interpolation */ -#define DMODE_REVERSE 0x0400 /* reverse stereo */ - -struct SAMPLOAD; -typedef struct MDRIVER { -struct MDRIVER* next; - CHAR* Name; - CHAR* Version; - - UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */ - UBYTE SoftVoiceLimit; /* Limit of software mixer voices */ - - CHAR* Alias; - - void (*CommandLine) (CHAR*); - BOOL (*IsPresent) (void); - SWORD (*SampleLoad) (struct SAMPLOAD*,int); - void (*SampleUnload) (SWORD); - ULONG (*FreeSampleSpace) (int); - ULONG (*RealSampleLength) (int,struct SAMPLE*); - BOOL (*Init) (void); - void (*Exit) (void); - BOOL (*Reset) (void); - BOOL (*SetNumVoices) (void); - BOOL (*PlayStart) (void); - void (*PlayStop) (void); - void (*Update) (void); - void (*Pause) (void); - void (*VoiceSetVolume) (UBYTE,UWORD); - UWORD (*VoiceGetVolume) (UBYTE); - void (*VoiceSetFrequency)(UBYTE,ULONG); - ULONG (*VoiceGetFrequency)(UBYTE); - void (*VoiceSetPanning) (UBYTE,ULONG); - ULONG (*VoiceGetPanning) (UBYTE); - void (*VoicePlay) (UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); - void (*VoiceStop) (UBYTE); - BOOL (*VoiceStopped) (UBYTE); - SLONG (*VoiceGetPosition) (UBYTE); - ULONG (*VoiceRealVolume) (UBYTE); -} MDRIVER; - -/* These variables can be changed at ANY time and results will be immediate */ -MIKMODAPI extern UBYTE md_volume; /* global sound volume (0-128) */ -MIKMODAPI extern UBYTE md_musicvolume; /* volume of song */ -MIKMODAPI extern UBYTE md_sndfxvolume; /* volume of sound effects */ -MIKMODAPI extern UBYTE md_reverb; /* 0 = none; 15 = chaos */ -MIKMODAPI extern UBYTE md_pansep; /* 0 = mono; 128 == 100% (full left/right) */ - -/* The variables below can be changed at any time, but changes will not be - implemented until MikMod_Reset is called. A call to MikMod_Reset may result - in a skip or pop in audio (depending on the soundcard driver and the settings - changed). */ -MIKMODAPI extern UWORD md_device; /* device */ -MIKMODAPI extern UWORD md_mixfreq; /* mixing frequency */ -MIKMODAPI extern UWORD md_mode; /* mode. See DMODE_? flags above */ - -/* The following variable should not be changed! */ -MIKMODAPI extern MDRIVER* md_driver; /* Current driver in use. */ - -/* Known drivers list */ - -MIKMODAPI extern struct MDRIVER drv_nos; /* no sound */ -MIKMODAPI extern struct MDRIVER drv_pipe; /* piped output */ -MIKMODAPI extern struct MDRIVER drv_raw; /* raw file disk writer [music.raw] */ -MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */ -MIKMODAPI extern struct MDRIVER drv_wav; /* RIFF WAVE file disk writer [music.wav] */ - -MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */ -MIKMODAPI extern struct MDRIVER drv_sam9407; /* Linux sam9407 driver */ - -MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */ -MIKMODAPI extern struct MDRIVER drv_aix; /* AIX audio device */ -MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */ -MIKMODAPI extern struct MDRIVER drv_esd; /* Enlightened sound daemon (EsounD) */ -MIKMODAPI extern struct MDRIVER drv_hp; /* HP-UX audio device */ -MIKMODAPI extern struct MDRIVER drv_oss; /* OpenSound System (Linux,FreeBSD...) */ -MIKMODAPI extern struct MDRIVER drv_sgi; /* SGI audio library */ -MIKMODAPI extern struct MDRIVER drv_sun; /* Sun/NetBSD/OpenBSD audio device */ - -MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */ -MIKMODAPI extern struct MDRIVER drv_os2; /* OS/2 MMPM/2 */ - -MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */ -MIKMODAPI extern struct MDRIVER drv_win; /* Win32 multimedia API driver */ - -MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager driver */ - -/*========== Virtual channel mixer interface (for user-supplied drivers only) */ - -MIKMODAPI extern BOOL VC_Init(void); -MIKMODAPI extern void VC_Exit(void); -MIKMODAPI extern BOOL VC_SetNumVoices(void); -MIKMODAPI extern ULONG VC_SampleSpace(int); -MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*); - -MIKMODAPI extern BOOL VC_PlayStart(void); -MIKMODAPI extern void VC_PlayStop(void); - -MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int); -MIKMODAPI extern void VC_SampleUnload(SWORD); - -MIKMODAPI extern ULONG VC_WriteBytes(SBYTE*,ULONG); -MIKMODAPI extern ULONG VC_SilenceBytes(SBYTE*,ULONG); - -MIKMODAPI extern void VC_VoiceSetVolume(UBYTE,UWORD); -MIKMODAPI extern UWORD VC_VoiceGetVolume(UBYTE); -MIKMODAPI extern void VC_VoiceSetFrequency(UBYTE,ULONG); -MIKMODAPI extern ULONG VC_VoiceGetFrequency(UBYTE); -MIKMODAPI extern void VC_VoiceSetPanning(UBYTE,ULONG); -MIKMODAPI extern ULONG VC_VoiceGetPanning(UBYTE); -MIKMODAPI extern void VC_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); - -MIKMODAPI extern void VC_VoiceStop(UBYTE); -MIKMODAPI extern BOOL VC_VoiceStopped(UBYTE); -MIKMODAPI extern SLONG VC_VoiceGetPosition(UBYTE); -MIKMODAPI extern ULONG VC_VoiceRealVolume(UBYTE); - -#ifdef __cplusplus -} -#endif - -#endif - -/* ex:set ts=4: */ diff --git a/mikmod/mikmod_build.h b/mikmod/mikmod_build.h deleted file mode 100644 index 0d2d1227..00000000 --- a/mikmod/mikmod_build.h +++ /dev/null @@ -1,717 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - MikMod sound library include file - -==============================================================================*/ - -#ifndef _MIKMOD_H_ -#define _MIKMOD_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * ========== Compiler magic for shared libraries - */ - -#if defined WIN32 && defined _DLL -#ifdef DLL_EXPORTS -#define MIKMODAPI __declspec(dllexport) -#else -#define MIKMODAPI __declspec(dllimport) -#endif -#else -#define MIKMODAPI -#endif - -/* - * ========== Library version - */ - -#define LIBMIKMOD_VERSION_MAJOR 3L -#define LIBMIKMOD_VERSION_MINOR 1L -#define LIBMIKMOD_REVISION 10L - -#define LIBMIKMOD_VERSION \ - ((LIBMIKMOD_VERSION_MAJOR<<16)| \ - (LIBMIKMOD_VERSION_MINOR<< 8)| \ - (LIBMIKMOD_REVISION)) - -MIKMODAPI extern long MikMod_GetVersion(void); - -/* - * ========== Platform independent-type definitions - */ - -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#endif - -#if defined(__OS2__)||defined(__EMX__) -#define INCL_DOSSEMAPHORES -#include -#else -typedef char CHAR; -#endif - - - -#if defined(__arch64__) || defined(__alpha) || defined(__x86_64) -/* 64 bit architectures */ - -typedef signed char SBYTE; /* 1 byte, signed */ -typedef unsigned char UBYTE; /* 1 byte, unsigned */ -typedef signed short SWORD; /* 2 bytes, signed */ -typedef unsigned short UWORD; /* 2 bytes, unsigned */ -typedef signed int SLONG; /* 4 bytes, signed */ -typedef unsigned int ULONG; /* 4 bytes, unsigned */ -typedef int BOOL; /* 0=false, <>0 true */ - -#else -/* 32 bit architectures */ - -typedef signed char SBYTE; /* 1 byte, signed */ -typedef unsigned char UBYTE; /* 1 byte, unsigned */ -typedef signed short SWORD; /* 2 bytes, signed */ -typedef unsigned short UWORD; /* 2 bytes, unsigned */ -typedef signed long SLONG; /* 4 bytes, signed */ -#if !defined(__OS2__)&&!defined(__EMX__)&&!defined(WIN32) -typedef unsigned long ULONG; /* 4 bytes, unsigned */ -typedef int BOOL; /* 0=false, <>0 true */ -#endif -#endif - -/* - * ========== Error codes - */ - -enum { - MMERR_OPENING_FILE = 1, - MMERR_OUT_OF_MEMORY, - MMERR_DYNAMIC_LINKING, - - MMERR_SAMPLE_TOO_BIG, - MMERR_OUT_OF_HANDLES, - MMERR_UNKNOWN_WAVE_TYPE, - - MMERR_LOADING_PATTERN, - MMERR_LOADING_TRACK, - MMERR_LOADING_HEADER, - MMERR_LOADING_SAMPLEINFO, - MMERR_NOT_A_MODULE, - MMERR_NOT_A_STREAM, - MMERR_MED_SYNTHSAMPLES, - MMERR_ITPACK_INVALID_DATA, - - MMERR_DETECTING_DEVICE, - MMERR_INVALID_DEVICE, - MMERR_INITIALIZING_MIXER, - MMERR_OPENING_AUDIO, - MMERR_8BIT_ONLY, - MMERR_16BIT_ONLY, - MMERR_STEREO_ONLY, - MMERR_ULAW, - MMERR_NON_BLOCK, - - MMERR_AF_AUDIO_PORT, - - MMERR_AIX_CONFIG_INIT, - MMERR_AIX_CONFIG_CONTROL, - MMERR_AIX_CONFIG_START, - - MMERR_GUS_SETTINGS, - MMERR_GUS_RESET, - MMERR_GUS_TIMER, - - MMERR_HP_SETSAMPLESIZE, - MMERR_HP_SETSPEED, - MMERR_HP_CHANNELS, - MMERR_HP_AUDIO_OUTPUT, - MMERR_HP_AUDIO_DESC, - MMERR_HP_BUFFERSIZE, - - MMERR_OSS_SETFRAGMENT, - MMERR_OSS_SETSAMPLESIZE, - MMERR_OSS_SETSTEREO, - MMERR_OSS_SETSPEED, - - MMERR_SGI_SPEED, - MMERR_SGI_16BIT, - MMERR_SGI_8BIT, - MMERR_SGI_STEREO, - MMERR_SGI_MONO, - - MMERR_SUN_INIT, - - MMERR_OS2_MIXSETUP, - MMERR_OS2_SEMAPHORE, - MMERR_OS2_TIMER, - MMERR_OS2_THREAD, - - MMERR_DS_PRIORITY, - MMERR_DS_BUFFER, - MMERR_DS_FORMAT, - MMERR_DS_NOTIFY, - MMERR_DS_EVENT, - MMERR_DS_THREAD, - MMERR_DS_UPDATE, - - MMERR_WINMM_HANDLE, - MMERR_WINMM_ALLOCATED, - MMERR_WINMM_DEVICEID, - MMERR_WINMM_FORMAT, - MMERR_WINMM_UNKNOWN, - - MMERR_MAC_SPEED, - MMERR_MAC_START, - - MMERR_MAX -}; - -/* - * ========== Error handling - */ - -typedef void (MikMod_handler)(void); -typedef MikMod_handler *MikMod_handler_t; - -MIKMODAPI extern int MikMod_errno; -MIKMODAPI extern BOOL MikMod_critical; -MIKMODAPI extern char *MikMod_strerror(int); - -MIKMODAPI extern MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t); - -/* - * ========== Library initialization and core functions - */ - -struct MDRIVER; - -MIKMODAPI extern void MikMod_RegisterAllDrivers(void); - -MIKMODAPI extern CHAR* MikMod_InfoDriver(void); -MIKMODAPI extern void MikMod_RegisterDriver(struct MDRIVER*); -MIKMODAPI extern int MikMod_DriverFromAlias(CHAR*); - -MIKMODAPI extern BOOL MikMod_Init(CHAR*); -MIKMODAPI extern void MikMod_Exit(void); -MIKMODAPI extern BOOL MikMod_Reset(CHAR*); -MIKMODAPI extern BOOL MikMod_SetNumVoices(int,int); -MIKMODAPI extern BOOL MikMod_Active(void); -MIKMODAPI extern BOOL MikMod_EnableOutput(void); -MIKMODAPI extern void MikMod_DisableOutput(void); -MIKMODAPI extern void MikMod_Update(void); - -MIKMODAPI extern BOOL MikMod_InitThreads(void); -MIKMODAPI extern void MikMod_Lock(void); -MIKMODAPI extern void MikMod_Unlock(void); - -/* - * ========== Reader, Writer - */ - -typedef struct MREADER { - BOOL (*Seek)(struct MREADER*,long,int); - long (*Tell)(struct MREADER*); - BOOL (*Read)(struct MREADER*,void*,size_t); - int (*Get)(struct MREADER*); - BOOL (*Eof)(struct MREADER*); -} MREADER; - -typedef struct MWRITER { - BOOL (*Seek)(struct MWRITER*,long,int); - long (*Tell)(struct MWRITER*); - BOOL (*Write)(struct MWRITER*,void*,size_t); - BOOL (*Put)(struct MWRITER*,int); -} MWRITER; - -/* - * ========== Samples - */ - -/* Sample playback should not be interrupted */ -#define SFX_CRITICAL 1 - -/* Sample format [loading and in-memory] flags: */ -#define SF_16BITS 0x0001 -#define SF_STEREO 0x0002 -#define SF_SIGNED 0x0004 -#define SF_BIG_ENDIAN 0x0008 -#define SF_DELTA 0x0010 -#define SF_ITPACKED 0x0020 - -#define SF_FORMATMASK 0x003F - -/* General Playback flags */ - -#define SF_LOOP 0x0100 -#define SF_BIDI 0x0200 -#define SF_REVERSE 0x0400 -#define SF_SUSTAIN 0x0800 - -#define SF_PLAYBACKMASK 0x0C00 - -/* Module-only Playback Flags */ - -#define SF_OWNPAN 0x1000 -#define SF_UST_LOOP 0x2000 - -#define SF_EXTRAPLAYBACKMASK 0x3000 - -/* Panning constants */ -#define PAN_LEFT 0 -#define PAN_HALFLEFT 64 -#define PAN_CENTER 128 -#define PAN_HALFRIGHT 192 -#define PAN_RIGHT 255 -#define PAN_SURROUND 512 /* panning value for Dolby Surround */ - -typedef struct SAMPLE { - SWORD panning; /* panning (0-255 or PAN_SURROUND) */ - ULONG speed; /* Base playing speed/frequency of note */ - UBYTE volume; /* volume 0-64 */ - UWORD inflags; /* sample format on disk */ - UWORD flags; /* sample format in memory */ - ULONG length; /* length of sample (in samples!) */ - ULONG loopstart; /* repeat position (relative to start, in samples) */ - ULONG loopend; /* repeat end */ - ULONG susbegin; /* sustain loop begin (in samples) \ Not Supported */ - ULONG susend; /* sustain loop end / Yet! */ - - /* Variables used by the module player only! (ignored for sound effects) */ - UBYTE globvol; /* global volume */ - UBYTE vibflags; /* autovibrato flag stuffs */ - UBYTE vibtype; /* Vibratos moved from INSTRUMENT to SAMPLE */ - UBYTE vibsweep; - UBYTE vibdepth; - UBYTE vibrate; - CHAR* samplename; /* name of the sample */ - - /* Values used internally only */ - UWORD avibpos; /* autovibrato pos [player use] */ - UBYTE divfactor; /* for sample scaling, maintains proper period slides */ - ULONG seekpos; /* seek position in file */ - SWORD handle; /* sample handle used by individual drivers */ -} SAMPLE; - -/* Sample functions */ - -MIKMODAPI extern SAMPLE *Sample_Load(CHAR*); -MIKMODAPI extern SAMPLE *Sample_LoadFP(FILE*); -MIKMODAPI extern SAMPLE *Sample_LoadGeneric(MREADER*); -MIKMODAPI extern void Sample_Free(SAMPLE*); -MIKMODAPI extern SBYTE Sample_Play(SAMPLE*,ULONG,UBYTE); - -MIKMODAPI extern void Voice_SetVolume(SBYTE,UWORD); -MIKMODAPI extern UWORD Voice_GetVolume(SBYTE); -MIKMODAPI extern void Voice_SetFrequency(SBYTE,ULONG); -MIKMODAPI extern ULONG Voice_GetFrequency(SBYTE); -MIKMODAPI extern void Voice_SetPanning(SBYTE,ULONG); -MIKMODAPI extern ULONG Voice_GetPanning(SBYTE); -MIKMODAPI extern void Voice_Play(SBYTE,SAMPLE*,ULONG); -MIKMODAPI extern void Voice_Stop(SBYTE); -MIKMODAPI extern BOOL Voice_Stopped(SBYTE); -MIKMODAPI extern SLONG Voice_GetPosition(SBYTE); -MIKMODAPI extern ULONG Voice_RealVolume(SBYTE); - -/* - * ========== Internal module representation (UniMod) - */ - -/* - Instrument definition - for information only, the only field which may be - of use in user programs is the name field -*/ - -/* Instrument note count */ -#define INSTNOTES 120 - -/* Envelope point */ -typedef struct ENVPT { - SWORD pos; - SWORD val; -} ENVPT; - -/* Envelope point count */ -#define ENVPOINTS 32 - -/* Instrument structure */ -typedef struct INSTRUMENT { - CHAR* insname; - - UBYTE flags; - UWORD samplenumber[INSTNOTES]; - UBYTE samplenote[INSTNOTES]; - - UBYTE nnatype; - UBYTE dca; /* duplicate check action */ - UBYTE dct; /* duplicate check type */ - UBYTE globvol; - UWORD volfade; - SWORD panning; /* instrument-based panning var */ - - UBYTE pitpansep; /* pitch pan separation (0 to 255) */ - UBYTE pitpancenter; /* pitch pan center (0 to 119) */ - UBYTE rvolvar; /* random volume varations (0 - 100%) */ - UBYTE rpanvar; /* random panning varations (0 - 100%) */ - - /* volume envelope */ - UBYTE volflg; /* bit 0: on 1: sustain 2: loop */ - UBYTE volpts; - UBYTE volsusbeg; - UBYTE volsusend; - UBYTE volbeg; - UBYTE volend; - ENVPT volenv[ENVPOINTS]; - /* panning envelope */ - UBYTE panflg; /* bit 0: on 1: sustain 2: loop */ - UBYTE panpts; - UBYTE pansusbeg; - UBYTE pansusend; - UBYTE panbeg; - UBYTE panend; - ENVPT panenv[ENVPOINTS]; - /* pitch envelope */ - UBYTE pitflg; /* bit 0: on 1: sustain 2: loop */ - UBYTE pitpts; - UBYTE pitsusbeg; - UBYTE pitsusend; - UBYTE pitbeg; - UBYTE pitend; - ENVPT pitenv[ENVPOINTS]; -} INSTRUMENT; - -struct MP_CONTROL; -struct MP_VOICE; - -/* - Module definition -*/ - -/* maximum master channels supported */ -#define UF_MAXCHAN 64 - -/* Module flags */ -#define UF_XMPERIODS 0x0001 /* XM periods / finetuning */ -#define UF_LINEAR 0x0002 /* LINEAR periods (UF_XMPERIODS must be set) */ -#define UF_INST 0x0004 /* Instruments are used */ -#define UF_NNA 0x0008 /* IT: NNA used, set numvoices rather - than numchn */ -#define UF_S3MSLIDES 0x0010 /* uses old S3M volume slides */ -#define UF_BGSLIDES 0x0020 /* continue volume slides in the background */ -#define UF_HIGHBPM 0x0040 /* MED: can use >255 bpm */ -#define UF_NOWRAP 0x0080 /* XM-type (i.e. illogical) pattern break - semantics */ -#define UF_ARPMEM 0x0100 /* IT: need arpeggio memory */ -#define UF_FT2QUIRKS 0x0200 /* emulate some FT2 replay quirks */ -#define UF_PANNING 0x0400 /* module uses panning effects or have - non-tracker default initial panning */ - -typedef struct MODULE { - /* general module information */ - CHAR* songname; /* name of the song */ - CHAR* modtype; /* string type of module loaded */ - CHAR* comment; /* module comments */ - - UWORD flags; /* See module flags above */ - UBYTE numchn; /* number of module channels */ - UBYTE numvoices; /* max # voices used for full NNA playback */ - UWORD numpos; /* number of positions in this song */ - UWORD numpat; /* number of patterns in this song */ - UWORD numins; /* number of instruments */ - UWORD numsmp; /* number of samples */ -struct INSTRUMENT* instruments; /* all instruments */ -struct SAMPLE* samples; /* all samples */ - UBYTE realchn; /* real number of channels used */ - UBYTE totalchn; /* total number of channels used (incl NNAs) */ - - /* playback settings */ - UWORD reppos; /* restart position */ - UBYTE initspeed; /* initial song speed */ - UWORD inittempo; /* initial song tempo */ - UBYTE initvolume; /* initial global volume (0 - 128) */ - UWORD panning[UF_MAXCHAN]; /* panning positions */ - UBYTE chanvol[UF_MAXCHAN]; /* channel positions */ - UWORD bpm; /* current beats-per-minute speed */ - UWORD sngspd; /* current song speed */ - SWORD volume; /* song volume (0-128) (or user volume) */ - - BOOL extspd; /* extended speed flag (default enabled) */ - BOOL panflag; /* panning flag (default enabled) */ - BOOL wrap; /* wrap module ? (default disabled) */ - BOOL loop; /* allow module to loop ? (default enabled) */ - BOOL fadeout; /* volume fade out during last pattern */ - - UWORD patpos; /* current row number */ - SWORD sngpos; /* current song position */ - ULONG sngtime; /* current song time in 2^-10 seconds */ - - SWORD relspd; /* relative speed factor */ - - /* internal module representation */ - UWORD numtrk; /* number of tracks */ - UBYTE** tracks; /* array of numtrk pointers to tracks */ - UWORD* patterns; /* array of Patterns */ - UWORD* pattrows; /* array of number of rows for each pattern */ - UWORD* positions; /* all positions */ - - BOOL forbid; /* if true, no player update! */ - UWORD numrow; /* number of rows on current pattern */ - UWORD vbtick; /* tick counter (counts from 0 to sngspd) */ - UWORD sngremainder;/* used for song time computation */ - -struct MP_CONTROL* control; /* Effects Channel info (size pf->numchn) */ -struct MP_VOICE* voice; /* Audio Voice information (size md_numchn) */ - - UBYTE globalslide; /* global volume slide rate */ - UBYTE pat_repcrazy;/* module has just looped to position -1 */ - UWORD patbrk; /* position where to start a new pattern */ - UBYTE patdly; /* patterndelay counter (command memory) */ - UBYTE patdly2; /* patterndelay counter (real one) */ - SWORD posjmp; /* flag to indicate a jump is needed... */ - UWORD bpmlimit; /* threshold to detect bpm or speed values */ -} MODULE; - -/* - * ========== Module loaders - */ - -struct MLOADER; - -MIKMODAPI extern CHAR* MikMod_InfoLoader(void); -MIKMODAPI extern void MikMod_RegisterAllLoaders(void); -MIKMODAPI extern void MikMod_RegisterLoader(struct MLOADER*); - -MIKMODAPI extern struct MLOADER load_669; /* 669 and Extended-669 (by Tran/Renaissance) */ -MIKMODAPI extern struct MLOADER load_amf; /* DMP Advanced Module Format (by Otto Chrons) */ -MIKMODAPI extern struct MLOADER load_dsm; /* DSIK internal module format */ -MIKMODAPI extern struct MLOADER load_far; /* Farandole Composer (by Daniel Potter) */ -MIKMODAPI extern struct MLOADER load_gdm; /* General DigiMusic (by Edward Schlunder) */ -MIKMODAPI extern struct MLOADER load_it; /* Impulse Tracker (by Jeffrey Lim) */ -MIKMODAPI extern struct MLOADER load_imf; /* Imago Orpheus (by Lutz Roeder) */ -MIKMODAPI extern struct MLOADER load_med; /* Amiga MED modules (by Teijo Kinnunen) */ -MIKMODAPI extern struct MLOADER load_m15; /* Soundtracker 15-instrument */ -MIKMODAPI extern struct MLOADER load_mod; /* Standard 31-instrument Module loader */ -MIKMODAPI extern struct MLOADER load_mtm; /* Multi-Tracker Module (by Renaissance) */ -MIKMODAPI extern struct MLOADER load_okt; /* Amiga Oktalyzer */ -MIKMODAPI extern struct MLOADER load_stm; /* ScreamTracker 2 (by Future Crew) */ -MIKMODAPI extern struct MLOADER load_stx; /* STMIK 0.2 (by Future Crew) */ -MIKMODAPI extern struct MLOADER load_s3m; /* ScreamTracker 3 (by Future Crew) */ -MIKMODAPI extern struct MLOADER load_ult; /* UltraTracker (by MAS) */ -MIKMODAPI extern struct MLOADER load_uni; /* MikMod and APlayer internal module format */ -MIKMODAPI extern struct MLOADER load_xm; /* FastTracker 2 (by Triton) */ - -/* - * ========== Module player - */ - -MIKMODAPI extern MODULE* Player_Load(CHAR*,int,BOOL); -MIKMODAPI extern MODULE* Player_LoadFP(FILE*,int,BOOL); -MIKMODAPI extern MODULE* Player_LoadGeneric(MREADER*,int,BOOL); -MIKMODAPI extern CHAR* Player_LoadTitle(CHAR*); -MIKMODAPI extern CHAR* Player_LoadTitleFP(FILE*); -MIKMODAPI extern void Player_Free(MODULE*); -MIKMODAPI extern void Player_Start(MODULE*); -MIKMODAPI extern BOOL Player_Active(void); -MIKMODAPI extern void Player_Stop(void); -MIKMODAPI extern void Player_TogglePause(void); -MIKMODAPI extern BOOL Player_Paused(void); -MIKMODAPI extern void Player_NextPosition(void); -MIKMODAPI extern void Player_PrevPosition(void); -MIKMODAPI extern void Player_SetPosition(UWORD); -MIKMODAPI extern BOOL Player_Muted(UBYTE); -MIKMODAPI extern void Player_SetVolume(SWORD); -MIKMODAPI extern MODULE* Player_GetModule(void); -MIKMODAPI extern void Player_SetSpeed(UWORD); -MIKMODAPI extern void Player_SetTempo(UWORD); -MIKMODAPI extern void Player_Unmute(SLONG,...); -MIKMODAPI extern void Player_Mute(SLONG,...); -MIKMODAPI extern void Player_ToggleMute(SLONG,...); -MIKMODAPI extern int Player_GetChannelVoice(UBYTE); -MIKMODAPI extern UWORD Player_GetChannelPeriod(UBYTE); - -typedef void (MikMod_player)(void); -typedef MikMod_player *MikMod_player_t; - -MIKMODAPI extern MikMod_player_t MikMod_RegisterPlayer(MikMod_player_t); - -#define MUTE_EXCLUSIVE 32000 -#define MUTE_INCLUSIVE 32001 - -/* - * ========== Drivers - */ - -enum { - MD_MUSIC = 0, - MD_SNDFX -}; - -enum { - MD_HARDWARE = 0, - MD_SOFTWARE -}; - -/* Mixing flags */ - -/* These ones take effect only after MikMod_Init or MikMod_Reset */ -#define DMODE_16BITS 0x0001 /* enable 16 bit output */ -#define DMODE_STEREO 0x0002 /* enable stereo output */ -#define DMODE_SOFT_SNDFX 0x0004 /* Process sound effects via software mixer */ -#define DMODE_SOFT_MUSIC 0x0008 /* Process music via software mixer */ -#define DMODE_HQMIXER 0x0010 /* Use high-quality (slower) software mixer */ -/* These take effect immediately. */ -#define DMODE_SURROUND 0x0100 /* enable surround sound */ -#define DMODE_INTERP 0x0200 /* enable interpolation */ -#define DMODE_REVERSE 0x0400 /* reverse stereo */ - -struct SAMPLOAD; -typedef struct MDRIVER { -struct MDRIVER* next; - CHAR* Name; - CHAR* Version; - - UBYTE HardVoiceLimit; /* Limit of hardware mixer voices */ - UBYTE SoftVoiceLimit; /* Limit of software mixer voices */ - - CHAR* Alias; - - void (*CommandLine) (CHAR*); - BOOL (*IsPresent) (void); - SWORD (*SampleLoad) (struct SAMPLOAD*,int); - void (*SampleUnload) (SWORD); - ULONG (*FreeSampleSpace) (int); - ULONG (*RealSampleLength) (int,struct SAMPLE*); - BOOL (*Init) (void); - void (*Exit) (void); - BOOL (*Reset) (void); - BOOL (*SetNumVoices) (void); - BOOL (*PlayStart) (void); - void (*PlayStop) (void); - void (*Update) (void); - void (*Pause) (void); - void (*VoiceSetVolume) (UBYTE,UWORD); - UWORD (*VoiceGetVolume) (UBYTE); - void (*VoiceSetFrequency)(UBYTE,ULONG); - ULONG (*VoiceGetFrequency)(UBYTE); - void (*VoiceSetPanning) (UBYTE,ULONG); - ULONG (*VoiceGetPanning) (UBYTE); - void (*VoicePlay) (UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); - void (*VoiceStop) (UBYTE); - BOOL (*VoiceStopped) (UBYTE); - SLONG (*VoiceGetPosition) (UBYTE); - ULONG (*VoiceRealVolume) (UBYTE); -} MDRIVER; - -/* These variables can be changed at ANY time and results will be immediate */ -MIKMODAPI extern UBYTE md_volume; /* global sound volume (0-128) */ -MIKMODAPI extern UBYTE md_musicvolume; /* volume of song */ -MIKMODAPI extern UBYTE md_sndfxvolume; /* volume of sound effects */ -MIKMODAPI extern UBYTE md_reverb; /* 0 = none; 15 = chaos */ -MIKMODAPI extern UBYTE md_pansep; /* 0 = mono; 128 == 100% (full left/right) */ - -/* The variables below can be changed at any time, but changes will not be - implemented until MikMod_Reset is called. A call to MikMod_Reset may result - in a skip or pop in audio (depending on the soundcard driver and the settings - changed). */ -MIKMODAPI extern UWORD md_device; /* device */ -MIKMODAPI extern UWORD md_mixfreq; /* mixing frequency */ -MIKMODAPI extern UWORD md_mode; /* mode. See DMODE_? flags above */ - -/* The following variable should not be changed! */ -MIKMODAPI extern MDRIVER* md_driver; /* Current driver in use. */ - -/* Known drivers list */ - -MIKMODAPI extern struct MDRIVER drv_nos; /* no sound */ -MIKMODAPI extern struct MDRIVER drv_pipe; /* piped output */ -MIKMODAPI extern struct MDRIVER drv_raw; /* raw file disk writer [music.raw] */ -MIKMODAPI extern struct MDRIVER drv_stdout; /* output to stdout */ -MIKMODAPI extern struct MDRIVER drv_wav; /* RIFF WAVE file disk writer [music.wav] */ - -MIKMODAPI extern struct MDRIVER drv_ultra; /* Linux Ultrasound driver */ -MIKMODAPI extern struct MDRIVER drv_sam9407; /* Linux sam9407 driver */ - -MIKMODAPI extern struct MDRIVER drv_AF; /* Dec Alpha AudioFile */ -MIKMODAPI extern struct MDRIVER drv_aix; /* AIX audio device */ -MIKMODAPI extern struct MDRIVER drv_alsa; /* Advanced Linux Sound Architecture (ALSA) */ -MIKMODAPI extern struct MDRIVER drv_esd; /* Enlightened sound daemon (EsounD) */ -MIKMODAPI extern struct MDRIVER drv_hp; /* HP-UX audio device */ -MIKMODAPI extern struct MDRIVER drv_oss; /* OpenSound System (Linux,FreeBSD...) */ -MIKMODAPI extern struct MDRIVER drv_sgi; /* SGI audio library */ -MIKMODAPI extern struct MDRIVER drv_sun; /* Sun/NetBSD/OpenBSD audio device */ - -MIKMODAPI extern struct MDRIVER drv_dart; /* OS/2 Direct Audio RealTime */ -MIKMODAPI extern struct MDRIVER drv_os2; /* OS/2 MMPM/2 */ - -MIKMODAPI extern struct MDRIVER drv_ds; /* Win32 DirectSound driver */ -MIKMODAPI extern struct MDRIVER drv_win; /* Win32 multimedia API driver */ - -MIKMODAPI extern struct MDRIVER drv_mac; /* Macintosh Sound Manager driver */ - -/*========== Virtual channel mixer interface (for user-supplied drivers only) */ - -MIKMODAPI extern BOOL VC_Init(void); -MIKMODAPI extern void VC_Exit(void); -MIKMODAPI extern BOOL VC_SetNumVoices(void); -MIKMODAPI extern ULONG VC_SampleSpace(int); -MIKMODAPI extern ULONG VC_SampleLength(int,SAMPLE*); - -MIKMODAPI extern BOOL VC_PlayStart(void); -MIKMODAPI extern void VC_PlayStop(void); - -MIKMODAPI extern SWORD VC_SampleLoad(struct SAMPLOAD*,int); -MIKMODAPI extern void VC_SampleUnload(SWORD); - -MIKMODAPI extern ULONG VC_WriteBytes(SBYTE*,ULONG); -MIKMODAPI extern ULONG VC_SilenceBytes(SBYTE*,ULONG); - -MIKMODAPI extern void VC_VoiceSetVolume(UBYTE,UWORD); -MIKMODAPI extern UWORD VC_VoiceGetVolume(UBYTE); -MIKMODAPI extern void VC_VoiceSetFrequency(UBYTE,ULONG); -MIKMODAPI extern ULONG VC_VoiceGetFrequency(UBYTE); -MIKMODAPI extern void VC_VoiceSetPanning(UBYTE,ULONG); -MIKMODAPI extern ULONG VC_VoiceGetPanning(UBYTE); -MIKMODAPI extern void VC_VoicePlay(UBYTE,SWORD,ULONG,ULONG,ULONG,ULONG,UWORD); - -MIKMODAPI extern void VC_VoiceStop(UBYTE); -MIKMODAPI extern BOOL VC_VoiceStopped(UBYTE); -MIKMODAPI extern SLONG VC_VoiceGetPosition(UBYTE); -MIKMODAPI extern ULONG VC_VoiceRealVolume(UBYTE); - -#ifdef __cplusplus -} -#endif - -#endif - -/* ex:set ts=4: */ diff --git a/mikmod/mikmod_internals.h b/mikmod/mikmod_internals.h deleted file mode 100644 index 5cc5e033..00000000 --- a/mikmod/mikmod_internals.h +++ /dev/null @@ -1,720 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - MikMod sound library internal definitions - -==============================================================================*/ - -#ifndef _MIKMOD_INTERNALS_H -#define _MIKMOD_INTERNALS_H - -#ifdef HAVE_MALLOC_H -#include -#endif -#include -#if defined(__OS2__)||defined(__EMX__)||defined(WIN32) -#define strcasecmp(s,t) stricmp(s,t) -#endif - -#include - -#ifdef macintosh -#ifndef __MWERKS__ -#define __STDC__=1 -#endif -static char *strdup(const char *str) -{ - char *newstr; - - newstr = (char *)malloc(strlen(str)+1); - if ( newstr != NULL ) { - strcpy(newstr, str); - } - return(newstr); -} -#endif - -#ifdef WIN32 -#ifndef __STDC__ -#define __STDC__ -#endif -#pragma warning(disable:4761) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*========== More type definitions */ - -/* SLONGLONG: 64bit, signed */ -#if 1 -#include "SDL_types.h" -typedef Sint64 SLONGLONG; -#else -#if defined (__arch64__) || defined(__alpha) || defined(_LP64) -typedef long SLONGLONG; -#define NATIVE_64BIT_INT -#elif defined(__WATCOMC__) -typedef __int64 SLONGLONG; -#elif defined(WIN32) && !defined(__MWERKS__) -typedef LONGLONG SLONGLONG; -#else -typedef long long SLONGLONG; -#endif -#endif /* 1 */ - -/*========== Error handling */ - -#define _mm_errno MikMod_errno -#define _mm_critical MikMod_critical -extern MikMod_handler_t _mm_errorhandler; - -/*========== Memory allocation */ - -/* _mm_malloc and _mm_free are defined in malloc.h in Visual C++ 6 */ -#ifdef _mm_malloc -#undef _mm_malloc -#endif -#ifdef _mm_free -#undef _mm_free -#endif -extern void* _mm_malloc(size_t); -extern void* _mm_calloc(size_t,size_t); -#define _mm_free(p) do { if (p) free(p); p = NULL; } while(0) - -/*========== MT stuff */ - -#ifdef HAVE_PTHREAD -#include -#define DECLARE_MUTEX(name) \ - extern pthread_mutex_t _mm_mutex_##name; -#define MUTEX_LOCK(name) \ - pthread_mutex_lock(&_mm_mutex_##name) -#define MUTEX_UNLOCK(name) \ - pthread_mutex_unlock(&_mm_mutex_##name) -#elif defined(__OS2__)||defined(__EMX__) -#define DECLARE_MUTEX(name) \ - extern HMTX _mm_mutex_##name; -#define MUTEX_LOCK(name) \ - if(_mm_mutex_##name) \ - DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT) -#define MUTEX_UNLOCK(name) \ - if(_mm_mutex_##name) \ - DosReleaseMutexSem(_mm_mutex_##name) -#elif defined(WIN32) -#include -#define DECLARE_MUTEX(name) \ - extern HANDLE _mm_mutex_##name; -#define MUTEX_LOCK(name) \ - if(_mm_mutex_##name) \ - WaitForSingleObject(_mm_mutex_##name,INFINITE) -#define MUTEX_UNLOCK(name) \ - if(_mm_mutex_##name) \ - ReleaseMutex(_mm_mutex_##name) -#else -#define DECLARE_MUTEX(name) -#define MUTEX_LOCK(name) -#define MUTEX_UNLOCK(name) -#endif - -DECLARE_MUTEX(lists) -DECLARE_MUTEX(vars) - -/*========== Portable file I/O */ - -/* SDL_RWops compatability */ -#include "SDL_rwops.h" -extern MREADER *_mm_new_rwops_reader(SDL_RWops * rw); -extern void _mm_delete_rwops_reader (MREADER*); -/* End SDL_RWops compatability */ - -extern MREADER* _mm_new_file_reader(FILE* fp); -extern void _mm_delete_file_reader(MREADER*); - -extern MWRITER* _mm_new_file_writer(FILE *fp); -extern void _mm_delete_file_writer(MWRITER*); - -extern BOOL _mm_FileExists(CHAR *fname); - -#define _mm_write_SBYTE(x,y) y->Put(y,(int)x) -#define _mm_write_UBYTE(x,y) y->Put(y,(int)x) - -#define _mm_read_SBYTE(x) (SBYTE)x->Get(x) -#define _mm_read_UBYTE(x) (UBYTE)x->Get(x) - -#define _mm_write_SBYTES(x,y,z) z->Write(z,(void *)x,y) -#define _mm_write_UBYTES(x,y,z) z->Write(z,(void *)x,y) -#define _mm_read_SBYTES(x,y,z) z->Read(z,(void *)x,y) -#define _mm_read_UBYTES(x,y,z) z->Read(z,(void *)x,y) - -#define _mm_fseek(x,y,z) x->Seek(x,y,z) -#define _mm_ftell(x) x->Tell(x) -#define _mm_rewind(x) _mm_fseek(x,0,SEEK_SET) - -#define _mm_eof(x) x->Eof(x) - -extern void _mm_iobase_setcur(MREADER*); -extern void _mm_iobase_revert(void); -extern FILE *_mm_fopen(CHAR*,CHAR*); -extern int _mm_fclose(FILE *); -extern void _mm_write_string(CHAR*,MWRITER*); -extern int _mm_read_string (CHAR*,int,MREADER*); - -extern SWORD _mm_read_M_SWORD(MREADER*); -extern SWORD _mm_read_I_SWORD(MREADER*); -extern UWORD _mm_read_M_UWORD(MREADER*); -extern UWORD _mm_read_I_UWORD(MREADER*); - -extern SLONG _mm_read_M_SLONG(MREADER*); -extern SLONG _mm_read_I_SLONG(MREADER*); -extern ULONG _mm_read_M_ULONG(MREADER*); -extern ULONG _mm_read_I_ULONG(MREADER*); - -extern int _mm_read_M_SWORDS(SWORD*,int,MREADER*); -extern int _mm_read_I_SWORDS(SWORD*,int,MREADER*); -extern int _mm_read_M_UWORDS(UWORD*,int,MREADER*); -extern int _mm_read_I_UWORDS(UWORD*,int,MREADER*); - -extern int _mm_read_M_SLONGS(SLONG*,int,MREADER*); -extern int _mm_read_I_SLONGS(SLONG*,int,MREADER*); -extern int _mm_read_M_ULONGS(ULONG*,int,MREADER*); -extern int _mm_read_I_ULONGS(ULONG*,int,MREADER*); - -extern void _mm_write_M_SWORD(SWORD,MWRITER*); -extern void _mm_write_I_SWORD(SWORD,MWRITER*); -extern void _mm_write_M_UWORD(UWORD,MWRITER*); -extern void _mm_write_I_UWORD(UWORD,MWRITER*); - -extern void _mm_write_M_SLONG(SLONG,MWRITER*); -extern void _mm_write_I_SLONG(SLONG,MWRITER*); -extern void _mm_write_M_ULONG(ULONG,MWRITER*); -extern void _mm_write_I_ULONG(ULONG,MWRITER*); - -extern void _mm_write_M_SWORDS(SWORD*,int,MWRITER*); -extern void _mm_write_I_SWORDS(SWORD*,int,MWRITER*); -extern void _mm_write_M_UWORDS(UWORD*,int,MWRITER*); -extern void _mm_write_I_UWORDS(UWORD*,int,MWRITER*); - -extern void _mm_write_M_SLONGS(SLONG*,int,MWRITER*); -extern void _mm_write_I_SLONGS(SLONG*,int,MWRITER*); -extern void _mm_write_M_ULONGS(ULONG*,int,MWRITER*); -extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*); - -/*========== Samples */ - -/* This is a handle of sorts attached to any sample registered with - SL_RegisterSample. Generally, this only need be used or changed by the - loaders and drivers of mikmod. */ -typedef struct SAMPLOAD { - struct SAMPLOAD *next; - - ULONG length; /* length of sample (in samples!) */ - ULONG loopstart; /* repeat position (relative to start, in samples) */ - ULONG loopend; /* repeat end */ - UWORD infmt,outfmt; - int scalefactor; - SAMPLE* sample; - MREADER* reader; -} SAMPLOAD; - -/*========== Sample and waves loading interface */ - -extern void SL_HalveSample(SAMPLOAD*,int); -extern void SL_Sample8to16(SAMPLOAD*); -extern void SL_Sample16to8(SAMPLOAD*); -extern void SL_SampleSigned(SAMPLOAD*); -extern void SL_SampleUnsigned(SAMPLOAD*); -extern BOOL SL_LoadSamples(void); -extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*); -extern BOOL SL_Load(void*,SAMPLOAD*,ULONG); -extern BOOL SL_Init(SAMPLOAD*); -extern void SL_Exit(SAMPLOAD*); - -/*========== Internal module representation (UniMod) interface */ - -/* number of notes in an octave */ -#define OCTAVE 12 - -extern void UniSetRow(UBYTE*); -extern UBYTE UniGetByte(void); -extern UWORD UniGetWord(void); -extern UBYTE* UniFindRow(UBYTE*,UWORD); -extern void UniSkipOpcode(void); -extern void UniReset(void); -extern void UniWriteByte(UBYTE); -extern void UniWriteWord(UWORD); -extern void UniNewline(void); -extern UBYTE* UniDup(void); -extern BOOL UniInit(void); -extern void UniCleanup(void); -extern void UniEffect(UWORD,UWORD); -#define UniInstrument(x) UniEffect(UNI_INSTRUMENT,x) -#define UniNote(x) UniEffect(UNI_NOTE,x) -extern void UniPTEffect(UBYTE,UBYTE); -extern void UniVolEffect(UWORD,UBYTE); - -/*========== Module Commands */ - -enum { - /* Simple note */ - UNI_NOTE = 1, - /* Instrument change */ - UNI_INSTRUMENT, - /* Protracker effects */ - UNI_PTEFFECT0, /* arpeggio */ - UNI_PTEFFECT1, /* porta up */ - UNI_PTEFFECT2, /* porta down */ - UNI_PTEFFECT3, /* porta to note */ - UNI_PTEFFECT4, /* vibrato */ - UNI_PTEFFECT5, /* dual effect 3+A */ - UNI_PTEFFECT6, /* dual effect 4+A */ - UNI_PTEFFECT7, /* tremolo */ - UNI_PTEFFECT8, /* pan */ - UNI_PTEFFECT9, /* sample offset */ - UNI_PTEFFECTA, /* volume slide */ - UNI_PTEFFECTB, /* pattern jump */ - UNI_PTEFFECTC, /* set volume */ - UNI_PTEFFECTD, /* pattern break */ - UNI_PTEFFECTE, /* extended effects */ - UNI_PTEFFECTF, /* set speed */ - /* Scream Tracker effects */ - UNI_S3MEFFECTA, /* set speed */ - UNI_S3MEFFECTD, /* volume slide */ - UNI_S3MEFFECTE, /* porta down */ - UNI_S3MEFFECTF, /* porta up */ - UNI_S3MEFFECTI, /* tremor */ - UNI_S3MEFFECTQ, /* retrig */ - UNI_S3MEFFECTR, /* tremolo */ - UNI_S3MEFFECTT, /* set tempo */ - UNI_S3MEFFECTU, /* fine vibrato */ - UNI_KEYOFF, /* note off */ - /* Fast Tracker effects */ - UNI_KEYFADE, /* note fade */ - UNI_VOLEFFECTS, /* volume column effects */ - UNI_XMEFFECT4, /* vibrato */ - UNI_XMEFFECT6, /* dual effect 4+A */ - UNI_XMEFFECTA, /* volume slide */ - UNI_XMEFFECTE1, /* fine porta up */ - UNI_XMEFFECTE2, /* fine porta down */ - UNI_XMEFFECTEA, /* fine volume slide up */ - UNI_XMEFFECTEB, /* fine volume slide down */ - UNI_XMEFFECTG, /* set global volume */ - UNI_XMEFFECTH, /* global volume slide */ - UNI_XMEFFECTL, /* set envelope position */ - UNI_XMEFFECTP, /* pan slide */ - UNI_XMEFFECTX1, /* extra fine porta up */ - UNI_XMEFFECTX2, /* extra fine porta down */ - /* Impulse Tracker effects */ - UNI_ITEFFECTG, /* porta to note */ - UNI_ITEFFECTH, /* vibrato */ - UNI_ITEFFECTI, /* tremor (xy not incremented) */ - UNI_ITEFFECTM, /* set channel volume */ - UNI_ITEFFECTN, /* slide / fineslide channel volume */ - UNI_ITEFFECTP, /* slide / fineslide channel panning */ - UNI_ITEFFECTT, /* slide tempo */ - UNI_ITEFFECTU, /* fine vibrato */ - UNI_ITEFFECTW, /* slide / fineslide global volume */ - UNI_ITEFFECTY, /* panbrello */ - UNI_ITEFFECTZ, /* resonant filters */ - UNI_ITEFFECTS0, - /* UltraTracker effects */ - UNI_ULTEFFECT9, /* Sample fine offset */ - /* OctaMED effects */ - UNI_MEDSPEED, - UNI_MEDEFFECTF1, /* play note twice */ - UNI_MEDEFFECTF2, /* delay note */ - UNI_MEDEFFECTF3, /* play note three times */ - /* Oktalyzer effects */ - UNI_OKTARP, /* arpeggio */ - UNI_XMEFFECTZ, /* XM Z synchro */ - - UNI_LAST -}; - -extern UWORD unioperands[UNI_LAST]; - -/* IT / S3M Extended SS effects: */ -enum { - SS_GLISSANDO = 1, - SS_FINETUNE, - SS_VIBWAVE, - SS_TREMWAVE, - SS_PANWAVE, - SS_FRAMEDELAY, - SS_S7EFFECTS, - SS_PANNING, - SS_SURROUND, - SS_HIOFFSET, - SS_PATLOOP, - SS_NOTECUT, - SS_NOTEDELAY, - SS_PATDELAY -}; - -/* IT Volume column effects */ -enum { - VOL_VOLUME = 1, - VOL_PANNING, - VOL_VOLSLIDE, - VOL_PITCHSLIDEDN, - VOL_PITCHSLIDEUP, - VOL_PORTAMENTO, - VOL_VIBRATO -}; - -/* IT resonant filter information */ - -#define UF_MAXMACRO 0x10 -#define UF_MAXFILTER 0x100 - -#define FILT_CUT 0x80 -#define FILT_RESONANT 0x81 - -typedef struct FILTER { - UBYTE filter,inf; -} FILTER; - -/*========== Instruments */ - -/* Instrument format flags */ -#define IF_OWNPAN 1 -#define IF_PITCHPAN 2 - -/* Envelope flags: */ -#define EF_ON 1 -#define EF_SUSTAIN 2 -#define EF_LOOP 4 -#define EF_VOLENV 8 - -/* New Note Action Flags */ -#define NNA_CUT 0 -#define NNA_CONTINUE 1 -#define NNA_OFF 2 -#define NNA_FADE 3 - -#define NNA_MASK 3 - -#define DCT_OFF 0 -#define DCT_NOTE 1 -#define DCT_SAMPLE 2 -#define DCT_INST 3 - -#define DCA_CUT 0 -#define DCA_OFF 1 -#define DCA_FADE 2 - -#define KEY_KICK 0 -#define KEY_OFF 1 -#define KEY_FADE 2 -#define KEY_KILL (KEY_OFF|KEY_FADE) - -#define KICK_ABSENT 0 -#define KICK_NOTE 1 -#define KICK_KEYOFF 2 -#define KICK_ENV 4 - -#define AV_IT 1 /* IT vs. XM vibrato info */ - -/*========== Playing */ - -#define POS_NONE (-2) /* no loop position defined */ - -#define LAST_PATTERN (UWORD)(-1) /* special ``end of song'' pattern */ - -typedef struct ENVPR { - UBYTE flg; /* envelope flag */ - UBYTE pts; /* number of envelope points */ - UBYTE susbeg; /* envelope sustain index begin */ - UBYTE susend; /* envelope sustain index end */ - UBYTE beg; /* envelope loop begin */ - UBYTE end; /* envelope loop end */ - SWORD p; /* current envelope counter */ - UWORD a; /* envelope index a */ - UWORD b; /* envelope index b */ - ENVPT* env; /* envelope points */ -} ENVPR; - -typedef struct MP_CHANNEL { - INSTRUMENT* i; - SAMPLE* s; - UBYTE sample; /* which sample number */ - UBYTE note; /* the audible note as heard, direct rep of period */ - SWORD outvolume; /* output volume (vol + sampcol + instvol) */ - SBYTE chanvol; /* channel's "global" volume */ - UWORD fadevol; /* fading volume rate */ - SWORD panning; /* panning position */ - UBYTE kick; /* if true = sample has to be restarted */ - UWORD period; /* period to play the sample at */ - UBYTE nna; /* New note action type + master/slave flags */ - - UBYTE volflg; /* volume envelope settings */ - UBYTE panflg; /* panning envelope settings */ - UBYTE pitflg; /* pitch envelope settings */ - - UBYTE keyoff; /* if true = fade out and stuff */ - SWORD handle; /* which sample-handle */ - UBYTE notedelay; /* (used for note delay) */ - SLONG start; /* The starting byte index in the sample */ -} MP_CHANNEL; - -typedef struct MP_CONTROL { - struct MP_CHANNEL main; - - struct MP_VOICE *slave; /* Audio Slave of current effects control channel */ - - UBYTE slavechn; /* Audio Slave of current effects control channel */ - UBYTE muted; /* if set, channel not played */ - UWORD ultoffset; /* fine sample offset memory */ - UBYTE anote; /* the note that indexes the audible */ - UBYTE oldnote; - SWORD ownper; - SWORD ownvol; - UBYTE dca; /* duplicate check action */ - UBYTE dct; /* duplicate check type */ - UBYTE* row; /* row currently playing on this channel */ - SBYTE retrig; /* retrig value (0 means don't retrig) */ - ULONG speed; /* what finetune to use */ - SWORD volume; /* amiga volume (0 t/m 64) to play the sample at */ - - SWORD tmpvolume; /* tmp volume */ - UWORD tmpperiod; /* tmp period */ - UWORD wantedperiod; /* period to slide to (with effect 3 or 5) */ - - UBYTE arpmem; /* arpeggio command memory */ - UBYTE pansspd; /* panslide speed */ - UWORD slidespeed; - UWORD portspeed; /* noteslide speed (toneportamento) */ - - UBYTE s3mtremor; /* s3m tremor (effect I) counter */ - UBYTE s3mtronof; /* s3m tremor ontime/offtime */ - UBYTE s3mvolslide; /* last used volslide */ - SBYTE sliding; - UBYTE s3mrtgspeed; /* last used retrig speed */ - UBYTE s3mrtgslide; /* last used retrig slide */ - - UBYTE glissando; /* glissando (0 means off) */ - UBYTE wavecontrol; - - SBYTE vibpos; /* current vibrato position */ - UBYTE vibspd; /* "" speed */ - UBYTE vibdepth; /* "" depth */ - - SBYTE trmpos; /* current tremolo position */ - UBYTE trmspd; /* "" speed */ - UBYTE trmdepth; /* "" depth */ - - UBYTE fslideupspd; - UBYTE fslidednspd; - UBYTE fportupspd; /* fx E1 (extra fine portamento up) data */ - UBYTE fportdnspd; /* fx E2 (extra fine portamento dn) data */ - UBYTE ffportupspd; /* fx X1 (extra fine portamento up) data */ - UBYTE ffportdnspd; /* fx X2 (extra fine portamento dn) data */ - - ULONG hioffset; /* last used high order of sample offset */ - UWORD soffset; /* last used low order of sample-offset (effect 9) */ - - UBYTE sseffect; /* last used Sxx effect */ - UBYTE ssdata; /* last used Sxx data info */ - UBYTE chanvolslide; /* last used channel volume slide */ - - UBYTE panbwave; /* current panbrello waveform */ - UBYTE panbpos; /* current panbrello position */ - SBYTE panbspd; /* "" speed */ - UBYTE panbdepth; /* "" depth */ - - UWORD newsamp; /* set to 1 upon a sample / inst change */ - UBYTE voleffect; /* Volume Column Effect Memory as used by IT */ - UBYTE voldata; /* Volume Column Data Memory */ - - SWORD pat_reppos; /* patternloop position */ - UWORD pat_repcnt; /* times to loop */ -} MP_CONTROL; - -/* Used by NNA only player (audio control. AUDTMP is used for full effects - control). */ -typedef struct MP_VOICE { - struct MP_CHANNEL main; - - ENVPR venv; - ENVPR penv; - ENVPR cenv; - - UWORD avibpos; /* autovibrato pos */ - UWORD aswppos; /* autovibrato sweep pos */ - - ULONG totalvol; /* total volume of channel (before global mixings) */ - - BOOL mflag; - SWORD masterchn; - UWORD masterperiod; - - MP_CONTROL* master; /* index of "master" effects channel */ -} MP_VOICE; - -/*========== Loaders */ - -typedef struct MLOADER { -struct MLOADER* next; - CHAR* type; - CHAR* version; - BOOL (*Init)(void); - BOOL (*Test)(void); - BOOL (*Load)(BOOL); - void (*Cleanup)(void); - CHAR* (*LoadTitle)(void); -} MLOADER; - -/* internal loader variables */ -extern MREADER* modreader; -extern UWORD finetune[16]; -extern MODULE of; /* static unimod loading space */ -extern UWORD npertab[7*OCTAVE]; /* used by the original MOD loaders */ - -extern SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ -extern UBYTE* poslookup; /* lookup table for pattern jumps after - blank pattern removal */ -extern UWORD poslookupcnt; -extern UWORD* origpositions; - -extern BOOL filters; /* resonant filters in use */ -extern UBYTE activemacro; /* active midi macro number for Sxx */ -extern UBYTE filtermacros[UF_MAXMACRO]; /* midi macro settings */ -extern FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */ - -extern int* noteindex; - -/*========== Internal loader interface */ - -extern BOOL ReadComment(UWORD); -extern BOOL ReadLinedComment(UWORD,UWORD); -extern BOOL AllocPositions(int); -extern BOOL AllocPatterns(void); -extern BOOL AllocTracks(void); -extern BOOL AllocInstruments(void); -extern BOOL AllocSamples(void); -extern CHAR* DupStr(CHAR*,UWORD,BOOL); - -/* loader utility functions */ -extern int* AllocLinear(void); -extern void FreeLinear(void); -extern int speed_to_finetune(ULONG,int); -extern void S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int); -extern void S3MIT_CreateOrders(BOOL); - -/* flags for S3MIT_ProcessCmd */ -#define S3MIT_OLDSTYLE 1 /* behave as old scream tracker */ -#define S3MIT_IT 2 /* behave as impulse tracker */ -#define S3MIT_SCREAM 4 /* enforce scream tracker specific limits */ - -/* used to convert c4spd to linear XM periods (IT and IMF loaders). */ -extern UWORD getlinearperiod(UWORD,ULONG); -extern ULONG getfrequency(UWORD,ULONG); - -/* loader shared data */ -#define STM_NTRACKERS 3 -extern CHAR *STM_Signatures[STM_NTRACKERS]; - -/*========== Player interface */ - -extern BOOL Player_Init(MODULE*); -extern void Player_Exit(MODULE*); -extern void Player_HandleTick(void); - -/*========== Drivers */ - -/* max. number of handles a driver has to provide. (not strict) */ -#define MAXSAMPLEHANDLES 384 - -/* These variables can be changed at ANY time and results will be immediate */ -extern UWORD md_bpm; /* current song / hardware BPM rate */ - -/* Variables below can be changed via MD_SetNumVoices at any time. However, a - call to MD_SetNumVoicess while the driver is active will cause the sound to - skip slightly. */ -extern UBYTE md_numchn; /* number of song + sound effects voices */ -extern UBYTE md_sngchn; /* number of song voices */ -extern UBYTE md_sfxchn; /* number of sound effects voices */ -extern UBYTE md_hardchn; /* number of hardware mixed voices */ -extern UBYTE md_softchn; /* number of software mixed voices */ - -/* This is for use by the hardware drivers only. It points to the registered - tickhandler function. */ -extern void (*md_player)(void); - -extern SWORD MD_SampleLoad(SAMPLOAD*,int); -extern void MD_SampleUnload(SWORD); -extern ULONG MD_SampleSpace(int); -extern ULONG MD_SampleLength(int,SAMPLE*); - -/* uLaw conversion */ -extern void unsignedtoulaw(char *,int); - -/* Parameter extraction helper */ -extern CHAR *MD_GetAtom(CHAR*,CHAR*,BOOL); - -/* Internal software mixer stuff */ -extern void VC_SetupPointers(void); -extern BOOL VC1_Init(void); -extern BOOL VC2_Init(void); - -#if defined(unix) || defined(__APPLE__) && defined(__MACH__) -/* POSIX helper functions */ -extern BOOL MD_Access(CHAR *); -extern BOOL MD_DropPrivileges(void); -#endif - -/* Macro to define a missing driver, yet allowing binaries to dynamically link - with the library without missing symbol errors */ -#define MISSING(a) MDRIVER a = { NULL, NULL, NULL, 0, 0 } - -/*========== Prototypes for non-MT safe versions of some public functions */ - -extern void _mm_registerdriver(struct MDRIVER*); -extern void _mm_unregisterdrivers(void); -extern void _mm_registerloader(struct MLOADER*); -extern void _mm_unregisterloaders(void); -extern BOOL MikMod_Active_internal(void); -extern void MikMod_DisableOutput_internal(void); -extern BOOL MikMod_EnableOutput_internal(void); -extern void MikMod_Exit_internal(void); -extern BOOL MikMod_SetNumVoices_internal(int,int); -extern void Player_Exit_internal(MODULE*); -extern void Player_Stop_internal(void); -extern BOOL Player_Paused_internal(void); -extern void Sample_Free_internal(SAMPLE*); -extern void Voice_Play_internal(SBYTE,SAMPLE*,ULONG); -extern void Voice_SetFrequency_internal(SBYTE,ULONG); -extern void Voice_SetPanning_internal(SBYTE,ULONG); -extern void Voice_SetVolume_internal(SBYTE,UWORD); -extern void Voice_Stop_internal(SBYTE); -extern BOOL Voice_Stopped_internal(SBYTE); - -#ifdef __cplusplus -} -#endif - -#endif - -/* ex:set ts=4: */ diff --git a/mikmod/mloader.c b/mikmod/mloader.c deleted file mode 100644 index 202a7edf..00000000 --- a/mikmod/mloader.c +++ /dev/null @@ -1,594 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - These routines are used to access the available module loaders - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - - MREADER *modreader; - MODULE of; - -static MLOADER *firstloader=NULL; - -UWORD finetune[16]={ - 8363,8413,8463,8529,8581,8651,8723,8757, - 7895,7941,7985,8046,8107,8169,8232,8280 -}; - -MIKMODAPI CHAR* MikMod_InfoLoader(void) -{ - int len=0; - MLOADER *l; - CHAR *list=NULL; - - MUTEX_LOCK(lists); - /* compute size of buffer */ - for(l=firstloader;l;l=l->next) len+=1+(l->next?1:0)+strlen(l->version); - - if(len) - if((list=_mm_malloc(len*sizeof(CHAR)))) { - list[0]=0; - /* list all registered module loders */ - for(l=firstloader;l;l=l->next) - sprintf(list,(l->next)?"%s%s\n":"%s%s",list,l->version); - } - MUTEX_UNLOCK(lists); - return list; -} - -void _mm_registerloader(MLOADER* ldr) -{ - MLOADER *cruise=firstloader; - - if(cruise) { - while(cruise->next) cruise = cruise->next; - cruise->next=ldr; - } else - firstloader=ldr; -} - -void _mm_unregisterloaders(void) -{ - MLOADER *cruise=firstloader, *ldr; - - while ( cruise ) { - ldr = cruise; - cruise = cruise->next; - ldr->next = NULL; - } - firstloader = NULL; -} - -MIKMODAPI void MikMod_RegisterLoader(struct MLOADER* ldr) -{ - /* if we try to register an invalid loader, or an already registered loader, - ignore this attempt */ - if ((!ldr)||(ldr->next)) - return; - - MUTEX_LOCK(lists); - _mm_registerloader(ldr); - MUTEX_UNLOCK(lists); -} - -BOOL ReadComment(UWORD len) -{ - if(len) { - int i; - - if(!(of.comment=(CHAR*)_mm_malloc(len+1))) return 0; - _mm_read_UBYTES(of.comment,len,modreader); - - /* translate IT linefeeds */ - for(i=0;i=0)&&(line[i]==' ');i--) line[i]=0; - for(i=0;ilines) { - if(!(of.comment=(CHAR*)_mm_malloc(total+1))) { - free(storage); - free(tempcomment); - return 0; - } - - /* convert message */ - for(line=tempcomment,t=0;tlength) SL_RegisterSample(s,MD_MUSIC,modreader); - - return 1; -} - -/* Creates a CSTR out of a character buffer of 'len' bytes, but strips any - terminating non-printing characters like 0, spaces etc. */ -CHAR *DupStr(CHAR* s,UWORD len,BOOL strict) -{ - UWORD t; - CHAR *d=NULL; - - /* Scan for last printing char in buffer [includes high ascii up to 254] */ - while(len) { - if(s[len-1]>0x20) break; - len--; - } - - /* Scan forward for possible NULL character */ - if(strict) { - for(t=0;thandle>=0) - MD_SampleUnload(s->handle); - if(s->samplename) free(s->samplename); -} - -static void ML_XFreeInstrument(INSTRUMENT *i) -{ - if(i->insname) free(i->insname); -} - -static void ML_FreeEx(MODULE *mf) -{ - UWORD t; - - if(mf->songname) free(mf->songname); - if(mf->comment) free(mf->comment); - - if(mf->modtype) free(mf->modtype); - if(mf->positions) free(mf->positions); - if(mf->patterns) free(mf->patterns); - if(mf->pattrows) free(mf->pattrows); - - if(mf->tracks) { - for(t=0;tnumtrk;t++) - if(mf->tracks[t]) free(mf->tracks[t]); - free(mf->tracks); - } - if(mf->instruments) { - for(t=0;tnumins;t++) - ML_XFreeInstrument(&mf->instruments[t]); - free(mf->instruments); - } - if(mf->samples) { - for(t=0;tnumsmp;t++) - if(mf->samples[t].length) ML_XFreeSample(&mf->samples[t]); - free(mf->samples); - } - memset(mf,0,sizeof(MODULE)); - if(mf!=&of) free(mf); -} - -static MODULE *ML_AllocUniMod(void) -{ - MODULE *mf; - - return (mf=_mm_malloc(sizeof(MODULE))); -} - -void Player_Free_internal(MODULE *mf) -{ - if(mf) { - Player_Exit_internal(mf); - ML_FreeEx(mf); - } -} - -MIKMODAPI void Player_Free(MODULE *mf) -{ - MUTEX_LOCK(vars); - Player_Free_internal(mf); - MUTEX_UNLOCK(vars); -} - -static CHAR* Player_LoadTitle_internal(MREADER *reader) -{ - MLOADER *l; - - modreader=reader; - _mm_errno = 0; - _mm_critical = 0; - _mm_iobase_setcur(modreader); - - /* Try to find a loader that recognizes the module */ - for(l=firstloader;l;l=l->next) { - _mm_rewind(modreader); - if(l->Test()) break; - } - - if(!l) { - _mm_errno = MMERR_NOT_A_MODULE; - if(_mm_errorhandler) _mm_errorhandler(); - return NULL; - } - - return l->LoadTitle(); -} - -MIKMODAPI CHAR* Player_LoadTitleFP(FILE *fp) -{ - CHAR* result=NULL; - MREADER* reader; - - if(fp && (reader=_mm_new_file_reader(fp))) { - MUTEX_LOCK(lists); - result=Player_LoadTitle_internal(reader); - MUTEX_UNLOCK(lists); - _mm_delete_file_reader(reader); - } - return result; -} - -MIKMODAPI CHAR* Player_LoadTitle(CHAR* filename) -{ - CHAR* result=NULL; - FILE* fp; - MREADER* reader; - - if((fp=_mm_fopen(filename,"rb"))) { - if((reader=_mm_new_file_reader(fp))) { - MUTEX_LOCK(lists); - result=Player_LoadTitle_internal(reader); - MUTEX_UNLOCK(lists); - _mm_delete_file_reader(reader); - } - _mm_fclose(fp); - } - return result; -} - -/* Loads a module given an reader */ -MODULE* Player_LoadGeneric_internal(MREADER *reader,int maxchan,BOOL curious) -{ - int t; - MLOADER *l; - BOOL ok; - MODULE *mf; - - modreader = reader; - _mm_errno = 0; - _mm_critical = 0; - _mm_iobase_setcur(modreader); - - /* Try to find a loader that recognizes the module */ - for(l=firstloader;l;l=l->next) { - _mm_rewind(modreader); - if(l->Test()) break; - } - - if(!l) { - _mm_errno = MMERR_NOT_A_MODULE; - if(_mm_errorhandler) _mm_errorhandler(); - _mm_rewind(modreader);_mm_iobase_revert(); - return NULL; - } - - /* init unitrk routines */ - if(!UniInit()) { - if(_mm_errorhandler) _mm_errorhandler(); - _mm_rewind(modreader);_mm_iobase_revert(); - return NULL; - } - - /* init the module structure with vanilla settings */ - memset(&of,0,sizeof(MODULE)); - of.bpmlimit = 33; - of.initvolume = 128; - for (t = 0; t < UF_MAXCHAN; t++) of.chanvol[t] = 64; - for (t = 0; t < UF_MAXCHAN; t++) - of.panning[t] = ((t + 1) & 2) ? PAN_RIGHT : PAN_LEFT; - - /* init module loader and load the header / patterns */ - if (!l->Init || l->Init()) { - _mm_rewind(modreader); - ok = l->Load(curious); - /* propagate inflags=flags for in-module samples */ - for (t = 0; t < of.numsmp; t++) - if (of.samples[t].inflags == 0) - of.samples[t].inflags = of.samples[t].flags; - } else - ok = 0; - - /* free loader and unitrk allocations */ - if (l->Cleanup) l->Cleanup(); - UniCleanup(); - - if(!ok) { - ML_FreeEx(&of); - if(_mm_errorhandler) _mm_errorhandler(); - _mm_rewind(modreader);_mm_iobase_revert(); - return NULL; - } - - if(!ML_LoadSamples()) { - ML_FreeEx(&of); - if(_mm_errorhandler) _mm_errorhandler(); - _mm_rewind(modreader);_mm_iobase_revert(); - return NULL; - } - - if(!(mf=ML_AllocUniMod())) { - ML_FreeEx(&of); - _mm_rewind(modreader);_mm_iobase_revert(); - if(_mm_errorhandler) _mm_errorhandler(); - return NULL; - } - - /* If the module doesn't have any specific panning, create a - MOD-like panning, with the channels half-separated. */ - if (!(of.flags & UF_PANNING)) - for (t = 0; t < of.numchn; t++) - of.panning[t] = ((t + 1) & 2) ? PAN_HALFRIGHT : PAN_HALFLEFT; - - /* Copy the static MODULE contents into the dynamic MODULE struct. */ - memcpy(mf,&of,sizeof(MODULE)); - - if(maxchan>0) { - if(!(mf->flags&UF_NNA)&&(mf->numchnnumchn; - else - if((mf->numvoices)&&(mf->numvoicesnumvoices; - - if(maxchannumchn) mf->flags |= UF_NNA; - - if(MikMod_SetNumVoices_internal(maxchan,-1)) { - _mm_iobase_revert(); - Player_Free(mf); - return NULL; - } - } - if(SL_LoadSamples()) { - _mm_iobase_revert(); - Player_Free_internal(mf); - return NULL; - } - if(Player_Init(mf)) { - _mm_iobase_revert(); - Player_Free_internal(mf); - mf=NULL; - } - _mm_iobase_revert(); - return mf; -} - -MIKMODAPI MODULE* Player_LoadGeneric(MREADER *reader,int maxchan,BOOL curious) -{ - MODULE* result; - - MUTEX_LOCK(vars); - MUTEX_LOCK(lists); - result=Player_LoadGeneric_internal(reader,maxchan,curious); - MUTEX_UNLOCK(lists); - MUTEX_UNLOCK(vars); - - return result; -} - -/* Loads a module given a file pointer. - File is loaded from the current file seek position. */ -MIKMODAPI MODULE* Player_LoadFP(FILE* fp,int maxchan,BOOL curious) -{ - MODULE* result=NULL; - struct MREADER* reader=_mm_new_file_reader (fp); - - if (reader) { - result=Player_LoadGeneric(reader,maxchan,curious); - _mm_delete_file_reader(reader); - } - return result; -} - -/* Open a module via its filename. The loader will initialize the specified - song-player 'player'. */ -MIKMODAPI MODULE* Player_Load(CHAR* filename,int maxchan,BOOL curious) -{ - FILE *fp; - MODULE *mf=NULL; - - if((fp=_mm_fopen(filename,"rb"))) { - mf=Player_LoadFP(fp,maxchan,curious); - _mm_fclose(fp); - } - return mf; -} - -/* SDL_RWops compatability */ - -/* Open a module via an SDL_rwop. The loader will initialize the specified - song-player 'player'. */ -MODULE* Player_LoadRW(SDL_RWops *rw,int maxchan,BOOL curious) -{ - MODULE* result=NULL; - struct MREADER* reader=_mm_new_rwops_reader (rw); - - if (reader) { - result=Player_LoadGeneric(reader,maxchan,curious); - _mm_delete_rwops_reader(reader); - } - return result; -} - -/* End SDL_RWops compatability */ - -/* ex:set ts=4: */ diff --git a/mikmod/mlreg.c b/mikmod/mlreg.c deleted file mode 100644 index 33d98106..00000000 --- a/mikmod/mlreg.c +++ /dev/null @@ -1,72 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Routine for registering all loaders in libmikmod for the current platform. - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mikmod_internals.h" - -void MikMod_RegisterAllLoaders_internal(void) -{ - _mm_registerloader(&load_669); - _mm_registerloader(&load_amf); - _mm_registerloader(&load_dsm); - _mm_registerloader(&load_far); - _mm_registerloader(&load_gdm); - _mm_registerloader(&load_it); - _mm_registerloader(&load_imf); - _mm_registerloader(&load_mod); - _mm_registerloader(&load_med); - _mm_registerloader(&load_mtm); - _mm_registerloader(&load_okt); - _mm_registerloader(&load_s3m); - _mm_registerloader(&load_stm); - _mm_registerloader(&load_stx); - _mm_registerloader(&load_ult); - _mm_registerloader(&load_uni); - _mm_registerloader(&load_xm); - - _mm_registerloader(&load_m15); -} - -void MikMod_RegisterAllLoaders(void) -{ - MUTEX_LOCK(lists); - MikMod_RegisterAllLoaders_internal(); - MUTEX_UNLOCK(lists); -} - -void MikMod_UnregisterAllLoaders(void) -{ - MUTEX_LOCK(lists); - _mm_unregisterloaders(); - MUTEX_UNLOCK(lists); -} - -/* ex:set ts=4: */ diff --git a/mikmod/mlutil.c b/mikmod/mlutil.c deleted file mode 100644 index 8aa0514b..00000000 --- a/mikmod/mlutil.c +++ /dev/null @@ -1,336 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Utility functions for the module loader - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -/*========== Shared tracker identifiers */ - -CHAR *STM_Signatures[STM_NTRACKERS] = { - "!Scream!", - "BMOD2STM", - "WUZAMOD!" -}; - -CHAR *STM_Version[STM_NTRACKERS] = { - "Screamtracker 2", - "Converted by MOD2STM (STM format)", - "Wuzamod (STM format)" -}; - -/*========== Shared loader variables */ - -SBYTE remap[UF_MAXCHAN]; /* for removing empty channels */ -UBYTE* poslookup=NULL; /* lookup table for pattern jumps after blank - pattern removal */ -UWORD poslookupcnt; -UWORD* origpositions=NULL; - -BOOL filters; /* resonant filters in use */ -UBYTE activemacro; /* active midi macro number for Sxx,xx<80h */ -UBYTE filtermacros[UF_MAXMACRO]; /* midi macro settings */ -FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */ - -/*========== Linear periods stuff */ - -int* noteindex=NULL; /* remap value for linear period modules */ -static int noteindexcount=0; - -int *AllocLinear(void) -{ - if(of.numsmp>noteindexcount) { - noteindexcount=of.numsmp; - noteindex=realloc(noteindex,noteindexcount*sizeof(int)); - } - return noteindex; -} - -void FreeLinear(void) -{ - if(noteindex) { - free(noteindex); - noteindex=NULL; - } - noteindexcount=0; -} - -int speed_to_finetune(ULONG speed,int sample) -{ - int ctmp=0,tmp,note=1,finetune=0; - - speed>>=1; - while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))speed) - tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune)); - else { - note--; - while(ctmp>4; - - /* process S3M / IT specific command structure */ - - if(cmd!=255) { - switch(cmd) { - case 1: /* Axx set speed to xx */ - UniEffect(UNI_S3MEFFECTA,inf); - break; - case 2: /* Bxx position jump */ - if (inf>4)*10+(inf&0xf)); - else - UniPTEffect(0xd,inf); - break; - case 4: /* Dxy volumeslide */ - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 5: /* Exy toneslide down */ - UniEffect(UNI_S3MEFFECTE,inf); - break; - case 6: /* Fxy toneslide up */ - UniEffect(UNI_S3MEFFECTF,inf); - break; - case 7: /* Gxx Tone portamento, speed xx */ - if (flags & S3MIT_OLDSTYLE) - UniPTEffect(0x3,inf); - else - UniEffect(UNI_ITEFFECTG,inf); - break; - case 8: /* Hxy vibrato */ - if (flags & S3MIT_OLDSTYLE) - UniPTEffect(0x4,inf); - else - UniEffect(UNI_ITEFFECTH,inf); - break; - case 9: /* Ixy tremor, ontime x, offtime y */ - if (flags & S3MIT_OLDSTYLE) - UniEffect(UNI_S3MEFFECTI,inf); - else - UniEffect(UNI_ITEFFECTI,inf); - break; - case 0xa: /* Jxy arpeggio */ - UniPTEffect(0x0,inf); - break; - case 0xb: /* Kxy Dual command H00 & Dxy */ - if (flags & S3MIT_OLDSTYLE) - UniPTEffect(0x4,0); - else - UniEffect(UNI_ITEFFECTH,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 0xc: /* Lxy Dual command G00 & Dxy */ - if (flags & S3MIT_OLDSTYLE) - UniPTEffect(0x3,0); - else - UniEffect(UNI_ITEFFECTG,0); - UniEffect(UNI_S3MEFFECTD,inf); - break; - case 0xd: /* Mxx Set Channel Volume */ - UniEffect(UNI_ITEFFECTM,inf); - break; - case 0xe: /* Nxy Slide Channel Volume */ - UniEffect(UNI_ITEFFECTN,inf); - break; - case 0xf: /* Oxx set sampleoffset xx00h */ - UniPTEffect(0x9,inf); - break; - case 0x10: /* Pxy Slide Panning Commands */ - UniEffect(UNI_ITEFFECTP,inf); - break; - case 0x11: /* Qxy Retrig (+volumeslide) */ - UniWriteByte(UNI_S3MEFFECTQ); - if(inf && !lo && !(flags & S3MIT_OLDSTYLE)) - UniWriteByte(1); - else - UniWriteByte(inf); - break; - case 0x12: /* Rxy tremolo speed x, depth y */ - UniEffect(UNI_S3MEFFECTR,inf); - break; - case 0x13: /* Sxx special commands */ - if (inf>=0xf0) { - /* change resonant filter settings if necessary */ - if((filters)&&((inf&0xf)!=activemacro)) { - activemacro=inf&0xf; - for(inf=0;inf<0x80;inf++) - filtersettings[inf].filter=filtermacros[activemacro]; - } - } else { - /* Scream Tracker does not have samples larger than - 64 Kb, thus doesn't need the SAx effect */ - if ((flags & S3MIT_SCREAM) && ((inf & 0xf0) == 0xa0)) - break; - - UniEffect(UNI_ITEFFECTS0,inf); - } - break; - case 0x14: /* Txx tempo */ - if(inf>=0x20) - UniEffect(UNI_S3MEFFECTT,inf); - else { - if(!(flags & S3MIT_OLDSTYLE)) - /* IT Tempo slide */ - UniEffect(UNI_ITEFFECTT,inf); - } - break; - case 0x15: /* Uxy Fine Vibrato speed x, depth y */ - if(flags & S3MIT_OLDSTYLE) - UniEffect(UNI_S3MEFFECTU,inf); - else - UniEffect(UNI_ITEFFECTU,inf); - break; - case 0x16: /* Vxx Set Global Volume */ - UniEffect(UNI_XMEFFECTG,inf); - break; - case 0x17: /* Wxy Global Volume Slide */ - UniEffect(UNI_ITEFFECTW,inf); - break; - case 0x18: /* Xxx amiga command 8xx */ - if(flags & S3MIT_OLDSTYLE) { - if(inf>128) - UniEffect(UNI_ITEFFECTS0,0x91); /* surround */ - else - UniPTEffect(0x8,(inf==128)?255:(inf<<1)); - } else - UniPTEffect(0x8,inf); - break; - case 0x19: /* Yxy Panbrello speed x, depth y */ - UniEffect(UNI_ITEFFECTY,inf); - break; - case 0x1a: /* Zxx midi/resonant filters */ - if(filtersettings[inf].filter) { - UniWriteByte(UNI_ITEFFECTZ); - UniWriteByte(filtersettings[inf].filter); - UniWriteByte(filtersettings[inf].inf); - } - break; - } - } -} - -/*========== Unitrk stuff */ - -/* Generic effect writing routine */ -void UniEffect(UWORD eff,UWORD dat) -{ - if((!eff)||(eff>=UNI_LAST)) return; - - UniWriteByte(eff); - if(unioperands[eff]==2) - UniWriteWord(dat); - else - UniWriteByte(dat); -} - -/* Appends UNI_PTEFFECTX opcode to the unitrk stream. */ -void UniPTEffect(UBYTE eff, UBYTE dat) -{ -#ifdef MIKMOD_DEBUG - if (eff>=0x10) - fprintf(stderr,"UniPTEffect called with incorrect eff value %d\n",eff); - else -#endif - if((eff)||(dat)||(of.flags&UF_ARPMEM)) UniEffect(UNI_PTEFFECT0+eff,dat); -} - -/* Appends UNI_VOLEFFECT + effect/dat to unistream. */ -void UniVolEffect(UWORD eff,UBYTE dat) -{ - if((eff)||(dat)) { /* don't write empty effect */ - UniWriteByte(UNI_VOLEFFECTS); - UniWriteByte(eff);UniWriteByte(dat); - } -} - -/* ex:set ts=4: */ diff --git a/mikmod/mmalloc.c b/mikmod/mmalloc.c deleted file mode 100644 index 9ad65cae..00000000 --- a/mikmod/mmalloc.c +++ /dev/null @@ -1,59 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Dynamic memory routines - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mikmod_internals.h" - -/* Same as malloc, but sets error variable _mm_error when fails */ -void* _mm_malloc(size_t size) -{ - void *d; - - if(!(d=calloc(1,size))) { - _mm_errno = MMERR_OUT_OF_MEMORY; - if(_mm_errorhandler) _mm_errorhandler(); - } - return d; -} - -/* Same as calloc, but sets error variable _mm_error when fails */ -void* _mm_calloc(size_t nitems,size_t size) -{ - void *d; - - if(!(d=calloc(nitems,size))) { - _mm_errno = MMERR_OUT_OF_MEMORY; - if(_mm_errorhandler) _mm_errorhandler(); - } - return d; -} - -/* ex:set ts=4: */ diff --git a/mikmod/mmerror.c b/mikmod/mmerror.c deleted file mode 100644 index efbde194..00000000 --- a/mikmod/mmerror.c +++ /dev/null @@ -1,197 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Error handling functions. - Register an error handler with _mm_RegisterErrorHandler() and you're all set. - -==============================================================================*/ - -/* - - The global variables _mm_errno, and _mm_critical are set before the error - handler in called. See below for the values of these variables. - -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mikmod_internals.h" - -CHAR *_mm_errmsg[MMERR_MAX+1] = -{ -/* No error */ - - "No error", - -/* Generic errors */ - - "Could not open requested file", - "Out of memory", - "Dynamic linking failed", - -/* Sample errors */ - - "Out of memory to load sample", - "Out of sample handles to load sample", - "Sample format not recognized", - -/* Module errors */ - - "Failure loading module pattern", - "Failure loading module track", - "Failure loading module header", - "Failure loading sampleinfo", - "Module format not recognized", - "Module sample format not recognized", - "Synthsounds not supported in MED files", - "Compressed sample is invalid", - -/* Driver errors: */ - - "Sound device not detected", - "Device number out of range", - "Software mixer failure", - "Could not open sound device", - "This driver supports 8 bit linear output only", - "This driver supports 16 bit linear output only", - "This driver supports stereo output only", - "This driver supports uLaw output (8 bit mono, 8 kHz) only", - "Unable to set non-blocking mode for audio device", - -/* AudioFile driver errors */ - - "Cannot find suitable AudioFile audio port", - -/* AIX driver errors */ - - "Configuration (init step) of audio device failed", - "Configuration (control step) of audio device failed", - "Configuration (start step) of audio device failed", - -/* ALSA driver errors */ - -/* EsounD driver errors */ - -/* Ultrasound driver errors */ - - "Ultrasound driver only works in 16 bit stereo 44 KHz", - "Ultrasound card could not be reset", - "Could not start Ultrasound timer", - -/* HP driver errors */ - - "Unable to select 16bit-linear sample format", - "Could not select requested sample-rate", - "Could not select requested number of channels", - "Unable to select audio output", - "Unable to get audio description", - "Could not set transmission buffer size", - -/* Open Sound System driver errors */ - - "Could not set fragment size", - "Could not set sample size", - "Could not set mono/stereo setting", - "Could not set sample rate", - -/* SGI driver errors */ - - "Unsupported sample rate", - "Hardware does not support 16 bit sound", - "Hardware does not support 8 bit sound", - "Hardware does not support stereo sound", - "Hardware does not support mono sound", - -/* Sun driver errors */ - - "Sound device initialization failed", - -/* OS/2 drivers errors */ - - "Could not set mixing parameters", - "Could not create playback semaphores", - "Could not create playback timer", - "Could not create playback thread", - -/* DirectSound driver errors */ - - "Could not set playback priority", - "Could not create playback buffers", - "Could not set playback format", - "Could not register callback", - "Could not register event", - "Could not create playback thread", - "Could not initialize playback thread", - -/* Windows Multimedia API driver errors */ - - "Invalid device handle", - "The resource is already allocated", - "Invalid device identifier", - "Unsupported output format", - "Unknown error", - -/* Macintosh driver errors */ - - "Unsupported sample rate", - "Could not start playback", - -/* Invalid error */ - - "Invalid error code" -}; - -MIKMODAPI char *MikMod_strerror(int code) -{ - if ((code<0)||(code>MMERR_MAX)) code=MMERR_MAX+1; - return _mm_errmsg[code]; -} - -/* User installed error callback */ -MikMod_handler_t _mm_errorhandler = NULL; -MIKMODAPI int _mm_errno = 0; -MIKMODAPI BOOL _mm_critical = 0; - -MikMod_handler_t _mm_registererrorhandler(MikMod_handler_t proc) -{ - MikMod_handler_t oldproc=_mm_errorhandler; - - _mm_errorhandler = proc; - return oldproc; -} - -MIKMODAPI MikMod_handler_t MikMod_RegisterErrorHandler(MikMod_handler_t proc) -{ - MikMod_handler_t result; - - MUTEX_LOCK(vars); - result=_mm_registererrorhandler(proc); - MUTEX_UNLOCK(vars); - - return result; -} - -/* ex:set ts=4: */ diff --git a/mikmod/mmio.c b/mikmod/mmio.c deleted file mode 100644 index 1bba2adf..00000000 --- a/mikmod/mmio.c +++ /dev/null @@ -1,454 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Portable file I/O routines - -==============================================================================*/ - -/* - - The way this module works: - - - _mm_fopen will call the errorhandler [see mmerror.c] in addition to - setting _mm_errno on exit. - - _mm_iobase is for internal use. It is used by Player_LoadFP to - ensure that it works properly with wad files. - - _mm_read_I_* and _mm_read_M_* differ : the first is for reading data - written by a little endian (intel) machine, and the second is for reading - big endian (Mac, RISC, Alpha) machine data. - - _mm_write functions work the same as the _mm_read functions. - - _mm_read_string is for reading binary strings. It is basically the same - as an fread of bytes. - -*/ - -/* FIXME - the _mm_iobase variable ought to be MREADER-specific. It will eventually - become a private field of the MREADER structure, but this will require a - soname version bump. - - In the meantime, the drawback is that if you use the xxx_LoadFP functions, - you can't have several MREADER objects with different iobase values. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fclose(FILE *); -extern int fgetc(FILE *); -extern int fputc(int, FILE *); -extern size_t fread(void *, size_t, size_t, FILE *); -extern int fseek(FILE *, long, int); -extern size_t fwrite(const void *, size_t, size_t, FILE *); -#endif - -#define COPY_BUFSIZE 1024 - -static long _mm_iobase=0,temp_iobase=0; - -/* - - This section is added to use SDL_rwops for IO - - -Matt Campbell (matt@campbellhome.dhs.org) April 2000 - -*/ - -typedef struct MRWOPSREADER { - MREADER core; - SDL_RWops* rw; - int end; -} MRWOPSREADER; - -static BOOL _mm_RWopsReader_Eof(MREADER* reader) -{ - if ( ((MRWOPSREADER*)reader)->end < - SDL_RWtell(((MRWOPSREADER*)reader)->rw) ) return 1; - else return 0; -} - -static BOOL _mm_RWopsReader_Read(MREADER* reader,void* ptr,size_t size) -{ - return SDL_RWread(((MRWOPSREADER*)reader)->rw, ptr, size, 1); -} - -static int _mm_RWopsReader_Get(MREADER* reader) -{ - char buf; - if ( SDL_RWread(((MRWOPSREADER*)reader)->rw, &buf, 1, 1) != 1 ) return EOF; - else return (int)buf; -} - -static BOOL _mm_RWopsReader_Seek(MREADER* reader,long offset,int whence) -{ - return SDL_RWseek(((MRWOPSREADER*)reader)->rw, - (whence==SEEK_SET)?offset+_mm_iobase:offset,whence); -} - -static long _mm_RWopsReader_Tell(MREADER* reader) -{ - return SDL_RWtell(((MRWOPSREADER*)reader)->rw) - _mm_iobase; -} - -MREADER *_mm_new_rwops_reader(SDL_RWops * rw) -{ - int here; - MRWOPSREADER* reader=(MRWOPSREADER*)_mm_malloc(sizeof(MRWOPSREADER)); - if (reader) { - reader->core.Eof =&_mm_RWopsReader_Eof; - reader->core.Read=&_mm_RWopsReader_Read; - reader->core.Get =&_mm_RWopsReader_Get; - reader->core.Seek=&_mm_RWopsReader_Seek; - reader->core.Tell=&_mm_RWopsReader_Tell; - reader->rw=rw; - - /* RWops does not explicitly support an eof check, so we shall find - the end manually - this requires seek support for the RWop */ - here = SDL_RWtell(rw); - reader->end = SDL_RWseek(rw, 0, SEEK_END); - SDL_RWseek(rw, here, SEEK_SET); /* Move back */ - } - return (MREADER*)reader; -} - -void _mm_delete_rwops_reader (MREADER* reader) -{ - if(reader) free(reader); -} - -/* - - End SDL_rwops section - -*/ - -FILE* _mm_fopen(CHAR* fname,CHAR* attrib) -{ - FILE *fp; - - if(!(fp=fopen(fname,attrib))) { - _mm_errno = MMERR_OPENING_FILE; - if(_mm_errorhandler) _mm_errorhandler(); - } - return fp; -} - -BOOL _mm_FileExists(CHAR* fname) -{ - FILE *fp; - - if(!(fp=fopen(fname,"r"))) return 0; - fclose(fp); - - return 1; -} - -int _mm_fclose(FILE *fp) -{ - return fclose(fp); -} - -/* Sets the current file-position as the new _mm_iobase */ -void _mm_iobase_setcur(MREADER* reader) -{ - temp_iobase=_mm_iobase; /* store old value in case of revert */ - _mm_iobase=reader->Tell(reader); -} - -/* Reverts to the last known _mm_iobase value. */ -void _mm_iobase_revert(void) -{ - _mm_iobase=temp_iobase; -} - -/*========== File Reader */ - -typedef struct MFILEREADER { - MREADER core; - FILE* file; -} MFILEREADER; - -static BOOL _mm_FileReader_Eof(MREADER* reader) -{ - return feof(((MFILEREADER*)reader)->file); -} - -static BOOL _mm_FileReader_Read(MREADER* reader,void* ptr,size_t size) -{ - return fread(ptr,size,1,((MFILEREADER*)reader)->file); -} - -static int _mm_FileReader_Get(MREADER* reader) -{ - return fgetc(((MFILEREADER*)reader)->file); -} - -static BOOL _mm_FileReader_Seek(MREADER* reader,long offset,int whence) -{ - return fseek(((MFILEREADER*)reader)->file, - (whence==SEEK_SET)?offset+_mm_iobase:offset,whence); -} - -static long _mm_FileReader_Tell(MREADER* reader) -{ - return ftell(((MFILEREADER*)reader)->file)-_mm_iobase; -} - -MREADER *_mm_new_file_reader(FILE* fp) -{ - MFILEREADER* reader=(MFILEREADER*)_mm_malloc(sizeof(MFILEREADER)); - if (reader) { - reader->core.Eof =&_mm_FileReader_Eof; - reader->core.Read=&_mm_FileReader_Read; - reader->core.Get =&_mm_FileReader_Get; - reader->core.Seek=&_mm_FileReader_Seek; - reader->core.Tell=&_mm_FileReader_Tell; - reader->file=fp; - } - return (MREADER*)reader; -} - -void _mm_delete_file_reader (MREADER* reader) -{ - if(reader) free(reader); -} - -/*========== File Writer */ - -typedef struct MFILEWRITER { - MWRITER core; - FILE* file; -} MFILEWRITER; - -static BOOL _mm_FileWriter_Seek(MWRITER* writer,long offset,int whence) -{ - return fseek(((MFILEWRITER*)writer)->file,offset,whence); -} - -static long _mm_FileWriter_Tell(MWRITER* writer) -{ - return ftell(((MFILEWRITER*)writer)->file); -} - -static BOOL _mm_FileWriter_Write(MWRITER* writer,void* ptr,size_t size) -{ - return (fwrite(ptr,size,1,((MFILEWRITER*)writer)->file)==size); -} - -static BOOL _mm_FileWriter_Put(MWRITER* writer,int value) -{ - return fputc(value,((MFILEWRITER*)writer)->file); -} - -MWRITER *_mm_new_file_writer(FILE* fp) -{ - MFILEWRITER* writer=(MFILEWRITER*)_mm_malloc(sizeof(MFILEWRITER)); - if (writer) { - writer->core.Seek =&_mm_FileWriter_Seek; - writer->core.Tell =&_mm_FileWriter_Tell; - writer->core.Write=&_mm_FileWriter_Write; - writer->core.Put =&_mm_FileWriter_Put; - writer->file=fp; - } - return (MWRITER*) writer; -} - -void _mm_delete_file_writer (MWRITER* writer) -{ - if(writer) free (writer); -} - -/*========== Write functions */ - -void _mm_write_string(CHAR* data,MWRITER* writer) -{ - if(data) - _mm_write_UBYTES(data,strlen(data),writer); -} - -void _mm_write_M_UWORD(UWORD data,MWRITER* writer) -{ - _mm_write_UBYTE(data>>8,writer); - _mm_write_UBYTE(data&0xff,writer); -} - -void _mm_write_I_UWORD(UWORD data,MWRITER* writer) -{ - _mm_write_UBYTE(data&0xff,writer); - _mm_write_UBYTE(data>>8,writer); -} - -void _mm_write_M_ULONG(ULONG data,MWRITER* writer) -{ - _mm_write_M_UWORD(data>>16,writer); - _mm_write_M_UWORD(data&0xffff,writer); -} - -void _mm_write_I_ULONG(ULONG data,MWRITER* writer) -{ - _mm_write_I_UWORD(data&0xffff,writer); - _mm_write_I_UWORD(data>>16,writer); -} - -void _mm_write_M_SWORD(SWORD data,MWRITER* writer) -{ - _mm_write_M_UWORD((UWORD)data,writer); -} - -void _mm_write_I_SWORD(SWORD data,MWRITER* writer) -{ - _mm_write_I_UWORD((UWORD)data,writer); -} - -void _mm_write_M_SLONG(SLONG data,MWRITER* writer) -{ - _mm_write_M_ULONG((ULONG)data,writer); -} - -void _mm_write_I_SLONG(SLONG data,MWRITER* writer) -{ - _mm_write_I_ULONG((ULONG)data,writer); -} - -#if defined __STDC__ || defined _MSC_VER -#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ -void _mm_write_##type_name##S (type *buffer,int number,MWRITER* writer) \ -{ \ - while(number-->0) \ - _mm_write_##type_name(*(buffer++),writer); \ -} -#else -#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name,type) \ -void _mm_write_/**/type_name/**/S (type *buffer,int number,MWRITER* writer) \ -{ \ - while(number-->0) \ - _mm_write_/**/type_name(*(buffer++),writer); \ -} -#endif - -DEFINE_MULTIPLE_WRITE_FUNCTION(M_SWORD,SWORD) -DEFINE_MULTIPLE_WRITE_FUNCTION(M_UWORD,UWORD) -DEFINE_MULTIPLE_WRITE_FUNCTION(I_SWORD,SWORD) -DEFINE_MULTIPLE_WRITE_FUNCTION(I_UWORD,UWORD) - -DEFINE_MULTIPLE_WRITE_FUNCTION(M_SLONG,SLONG) -DEFINE_MULTIPLE_WRITE_FUNCTION(M_ULONG,ULONG) -DEFINE_MULTIPLE_WRITE_FUNCTION(I_SLONG,SLONG) -DEFINE_MULTIPLE_WRITE_FUNCTION(I_ULONG,ULONG) - -/*========== Read functions */ - -int _mm_read_string(CHAR* buffer,int number,MREADER* reader) -{ - return reader->Read(reader,buffer,number); -} - -UWORD _mm_read_M_UWORD(MREADER* reader) -{ - UWORD result=((UWORD)_mm_read_UBYTE(reader))<<8; - result|=_mm_read_UBYTE(reader); - return result; -} - -UWORD _mm_read_I_UWORD(MREADER* reader) -{ - UWORD result=_mm_read_UBYTE(reader); - result|=((UWORD)_mm_read_UBYTE(reader))<<8; - return result; -} - -ULONG _mm_read_M_ULONG(MREADER* reader) -{ - ULONG result=((ULONG)_mm_read_M_UWORD(reader))<<16; - result|=_mm_read_M_UWORD(reader); - return result; -} - -ULONG _mm_read_I_ULONG(MREADER* reader) -{ - ULONG result=_mm_read_I_UWORD(reader); - result|=((ULONG)_mm_read_I_UWORD(reader))<<16; - return result; -} - -SWORD _mm_read_M_SWORD(MREADER* reader) -{ - return((SWORD)_mm_read_M_UWORD(reader)); -} - -SWORD _mm_read_I_SWORD(MREADER* reader) -{ - return((SWORD)_mm_read_I_UWORD(reader)); -} - -SLONG _mm_read_M_SLONG(MREADER* reader) -{ - return((SLONG)_mm_read_M_ULONG(reader)); -} - -SLONG _mm_read_I_SLONG(MREADER* reader) -{ - return((SLONG)_mm_read_I_ULONG(reader)); -} - -#if defined __STDC__ || defined _MSC_VER -#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ -int _mm_read_##type_name##S (type *buffer,int number,MREADER* reader) \ -{ \ - while(number-->0) \ - *(buffer++)=_mm_read_##type_name(reader); \ - return !reader->Eof(reader); \ -} -#else -#define DEFINE_MULTIPLE_READ_FUNCTION(type_name,type) \ -int _mm_read_/**/type_name/**/S (type *buffer,int number,MREADER* reader) \ -{ \ - while(number-->0) \ - *(buffer++)=_mm_read_/**/type_name(reader); \ - return !reader->Eof(reader); \ -} -#endif - -DEFINE_MULTIPLE_READ_FUNCTION(M_SWORD,SWORD) -DEFINE_MULTIPLE_READ_FUNCTION(M_UWORD,UWORD) -DEFINE_MULTIPLE_READ_FUNCTION(I_SWORD,SWORD) -DEFINE_MULTIPLE_READ_FUNCTION(I_UWORD,UWORD) - -DEFINE_MULTIPLE_READ_FUNCTION(M_SLONG,SLONG) -DEFINE_MULTIPLE_READ_FUNCTION(M_ULONG,ULONG) -DEFINE_MULTIPLE_READ_FUNCTION(I_SLONG,SLONG) -DEFINE_MULTIPLE_READ_FUNCTION(I_ULONG,ULONG) - -/* ex:set ts=4: */ diff --git a/mikmod/mplayer.c b/mikmod/mplayer.c deleted file mode 100644 index 2b0123d8..00000000 --- a/mikmod/mplayer.c +++ /dev/null @@ -1,3386 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - The Protracker Player Driver - - The protracker driver supports all base Protracker 3.x commands and features. - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#ifdef SRANDOM_IN_MATH_H -#include -#else -#include -#endif - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -extern long int random(void); -#endif - -/* The currently playing module */ -/* This variable should better be static, but it would break the ABI, so this - will wait */ -/*static*/ MODULE *pf = NULL; - -#define HIGH_OCTAVE 2 /* number of above-range octaves */ - -static UWORD oldperiods[OCTAVE*2]={ - 0x6b00, 0x6800, 0x6500, 0x6220, 0x5f50, 0x5c80, - 0x5a00, 0x5740, 0x54d0, 0x5260, 0x5010, 0x4dc0, - 0x4b90, 0x4960, 0x4750, 0x4540, 0x4350, 0x4160, - 0x3f90, 0x3dc0, 0x3c10, 0x3a40, 0x38b0, 0x3700 -}; - -static UBYTE VibratoTable[32]={ - 0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253, - 255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24 -}; - -static UBYTE avibtab[128]={ - 0, 1, 3, 4, 6, 7, 9,10,12,14,15,17,18,20,21,23, - 24,25,27,28,30,31,32,34,35,36,38,39,40,41,42,44, - 45,46,47,48,49,50,51,52,53,54,54,55,56,57,57,58, - 59,59,60,60,61,61,62,62,62,63,63,63,63,63,63,63, - 64,63,63,63,63,63,63,63,62,62,62,61,61,60,60,59, - 59,58,57,57,56,55,54,54,53,52,51,50,49,48,47,46, - 45,44,42,41,40,39,38,36,35,34,32,31,30,28,27,25, - 24,23,21,20,18,17,15,14,12,10, 9, 7, 6, 4, 3, 1 -}; - -/* Triton's linear periods to frequency translation table (for XM modules) */ -static ULONG lintab[768]={ - 535232,534749,534266,533784,533303,532822,532341,531861, - 531381,530902,530423,529944,529466,528988,528511,528034, - 527558,527082,526607,526131,525657,525183,524709,524236, - 523763,523290,522818,522346,521875,521404,520934,520464, - 519994,519525,519057,518588,518121,517653,517186,516720, - 516253,515788,515322,514858,514393,513929,513465,513002, - 512539,512077,511615,511154,510692,510232,509771,509312, - 508852,508393,507934,507476,507018,506561,506104,505647, - 505191,504735,504280,503825,503371,502917,502463,502010, - 501557,501104,500652,500201,499749,499298,498848,498398, - 497948,497499,497050,496602,496154,495706,495259,494812, - 494366,493920,493474,493029,492585,492140,491696,491253, - 490809,490367,489924,489482,489041,488600,488159,487718, - 487278,486839,486400,485961,485522,485084,484647,484210, - 483773,483336,482900,482465,482029,481595,481160,480726, - 480292,479859,479426,478994,478562,478130,477699,477268, - 476837,476407,475977,475548,475119,474690,474262,473834, - 473407,472979,472553,472126,471701,471275,470850,470425, - 470001,469577,469153,468730,468307,467884,467462,467041, - 466619,466198,465778,465358,464938,464518,464099,463681, - 463262,462844,462427,462010,461593,461177,460760,460345, - 459930,459515,459100,458686,458272,457859,457446,457033, - 456621,456209,455797,455386,454975,454565,454155,453745, - 453336,452927,452518,452110,451702,451294,450887,450481, - 450074,449668,449262,448857,448452,448048,447644,447240, - 446836,446433,446030,445628,445226,444824,444423,444022, - 443622,443221,442821,442422,442023,441624,441226,440828, - 440430,440033,439636,439239,438843,438447,438051,437656, - 437261,436867,436473,436079,435686,435293,434900,434508, - 434116,433724,433333,432942,432551,432161,431771,431382, - 430992,430604,430215,429827,429439,429052,428665,428278, - 427892,427506,427120,426735,426350,425965,425581,425197, - 424813,424430,424047,423665,423283,422901,422519,422138, - 421757,421377,420997,420617,420237,419858,419479,419101, - 418723,418345,417968,417591,417214,416838,416462,416086, - 415711,415336,414961,414586,414212,413839,413465,413092, - 412720,412347,411975,411604,411232,410862,410491,410121, - 409751,409381,409012,408643,408274,407906,407538,407170, - 406803,406436,406069,405703,405337,404971,404606,404241, - 403876,403512,403148,402784,402421,402058,401695,401333, - 400970,400609,400247,399886,399525,399165,398805,398445, - 398086,397727,397368,397009,396651,396293,395936,395579, - 395222,394865,394509,394153,393798,393442,393087,392733, - 392378,392024,391671,391317,390964,390612,390259,389907, - 389556,389204,388853,388502,388152,387802,387452,387102, - 386753,386404,386056,385707,385359,385012,384664,384317, - 383971,383624,383278,382932,382587,382242,381897,381552, - 381208,380864,380521,380177,379834,379492,379149,378807, - 378466,378124,377783,377442,377102,376762,376422,376082, - 375743,375404,375065,374727,374389,374051,373714,373377, - 373040,372703,372367,372031,371695,371360,371025,370690, - 370356,370022,369688,369355,369021,368688,368356,368023, - 367691,367360,367028,366697,366366,366036,365706,365376, - 365046,364717,364388,364059,363731,363403,363075,362747, - 362420,362093,361766,361440,361114,360788,360463,360137, - 359813,359488,359164,358840,358516,358193,357869,357547, - 357224,356902,356580,356258,355937,355616,355295,354974, - 354654,354334,354014,353695,353376,353057,352739,352420, - 352103,351785,351468,351150,350834,350517,350201,349885, - 349569,349254,348939,348624,348310,347995,347682,347368, - 347055,346741,346429,346116,345804,345492,345180,344869, - 344558,344247,343936,343626,343316,343006,342697,342388, - 342079,341770,341462,341154,340846,340539,340231,339924, - 339618,339311,339005,338700,338394,338089,337784,337479, - 337175,336870,336566,336263,335959,335656,335354,335051, - 334749,334447,334145,333844,333542,333242,332941,332641, - 332341,332041,331741,331442,331143,330844,330546,330247, - 329950,329652,329355,329057,328761,328464,328168,327872, - 327576,327280,326985,326690,326395,326101,325807,325513, - 325219,324926,324633,324340,324047,323755,323463,323171, - 322879,322588,322297,322006,321716,321426,321136,320846, - 320557,320267,319978,319690,319401,319113,318825,318538, - 318250,317963,317676,317390,317103,316817,316532,316246, - 315961,315676,315391,315106,314822,314538,314254,313971, - 313688,313405,313122,312839,312557,312275,311994,311712, - 311431,311150,310869,310589,310309,310029,309749,309470, - 309190,308911,308633,308354,308076,307798,307521,307243, - 306966,306689,306412,306136,305860,305584,305308,305033, - 304758,304483,304208,303934,303659,303385,303112,302838, - 302565,302292,302019,301747,301475,301203,300931,300660, - 300388,300117,299847,299576,299306,299036,298766,298497, - 298227,297958,297689,297421,297153,296884,296617,296349, - 296082,295815,295548,295281,295015,294749,294483,294217, - 293952,293686,293421,293157,292892,292628,292364,292100, - 291837,291574,291311,291048,290785,290523,290261,289999, - 289737,289476,289215,288954,288693,288433,288173,287913, - 287653,287393,287134,286875,286616,286358,286099,285841, - 285583,285326,285068,284811,284554,284298,284041,283785, - 283529,283273,283017,282762,282507,282252,281998,281743, - 281489,281235,280981,280728,280475,280222,279969,279716, - 279464,279212,278960,278708,278457,278206,277955,277704, - 277453,277203,276953,276703,276453,276204,275955,275706, - 275457,275209,274960,274712,274465,274217,273970,273722, - 273476,273229,272982,272736,272490,272244,271999,271753, - 271508,271263,271018,270774,270530,270286,270042,269798, - 269555,269312,269069,268826,268583,268341,268099,267857 -}; - -#define LOGFAC 2*16 -static UWORD logtab[104]={ - LOGFAC*907,LOGFAC*900,LOGFAC*894,LOGFAC*887, - LOGFAC*881,LOGFAC*875,LOGFAC*868,LOGFAC*862, - LOGFAC*856,LOGFAC*850,LOGFAC*844,LOGFAC*838, - LOGFAC*832,LOGFAC*826,LOGFAC*820,LOGFAC*814, - LOGFAC*808,LOGFAC*802,LOGFAC*796,LOGFAC*791, - LOGFAC*785,LOGFAC*779,LOGFAC*774,LOGFAC*768, - LOGFAC*762,LOGFAC*757,LOGFAC*752,LOGFAC*746, - LOGFAC*741,LOGFAC*736,LOGFAC*730,LOGFAC*725, - LOGFAC*720,LOGFAC*715,LOGFAC*709,LOGFAC*704, - LOGFAC*699,LOGFAC*694,LOGFAC*689,LOGFAC*684, - LOGFAC*678,LOGFAC*675,LOGFAC*670,LOGFAC*665, - LOGFAC*660,LOGFAC*655,LOGFAC*651,LOGFAC*646, - LOGFAC*640,LOGFAC*636,LOGFAC*632,LOGFAC*628, - LOGFAC*623,LOGFAC*619,LOGFAC*614,LOGFAC*610, - LOGFAC*604,LOGFAC*601,LOGFAC*597,LOGFAC*592, - LOGFAC*588,LOGFAC*584,LOGFAC*580,LOGFAC*575, - LOGFAC*570,LOGFAC*567,LOGFAC*563,LOGFAC*559, - LOGFAC*555,LOGFAC*551,LOGFAC*547,LOGFAC*543, - LOGFAC*538,LOGFAC*535,LOGFAC*532,LOGFAC*528, - LOGFAC*524,LOGFAC*520,LOGFAC*516,LOGFAC*513, - LOGFAC*508,LOGFAC*505,LOGFAC*502,LOGFAC*498, - LOGFAC*494,LOGFAC*491,LOGFAC*487,LOGFAC*484, - LOGFAC*480,LOGFAC*477,LOGFAC*474,LOGFAC*470, - LOGFAC*467,LOGFAC*463,LOGFAC*460,LOGFAC*457, - LOGFAC*453,LOGFAC*450,LOGFAC*447,LOGFAC*443, - LOGFAC*440,LOGFAC*437,LOGFAC*434,LOGFAC*431 -}; - -static SBYTE PanbrelloTable[256]={ - 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23, - 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, - 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60, - 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, - 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26, - 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2, - 0,- 2,- 3,- 5,- 6,- 8,- 9,-11,-12,-14,-16,-17,-19,-20,-22,-23, - -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44, - -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59, - -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64, - -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60, - -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46, - -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26, - -24,-23,-22,-20,-19,-17,-16,-14,-12,-11,- 9,- 8,- 6,- 5,- 3,- 2 -}; - -static int _pl_synchro_value; -void Player_SetSynchroValue(int i) -{ - _pl_synchro_value = i; -} - -int Player_GetSynchroValue(void) -{ - return _pl_synchro_value; -} - -/* returns a random value between 0 and ceil-1, ceil must be a power of two */ -static int getrandom(int ceil) -{ -#ifdef HAVE_SRANDOM - return random()&(ceil-1); -#else - return (int)((rand()*ceil)/(RAND_MAX+1.0)); -#endif -} - -/* New Note Action Scoring System : - -------------------------------- - 1) total-volume (fadevol, chanvol, volume) is the main scorer. - 2) a looping sample is a bonus x2 - 3) a foreground channel is a bonus x4 - 4) an active envelope with keyoff is a handicap -x2 -*/ -static int MP_FindEmptyChannel(MODULE *mod) -{ - MP_VOICE *a; - ULONG t,k,tvol,pp; - - for (t=0;tvoice[t].main.kick==KICK_ABSENT)|| - (mod->voice[t].main.kick==KICK_ENV))&& - Voice_Stopped_internal(t)) - return t; - - tvol=0xffffffUL;t=-1;a=mod->voice; - for (k=0;kmain.s) - return k; - - if ((a->main.kick==KICK_ABSENT)||(a->main.kick==KICK_ENV)) { - pp=a->totalvol<<((a->main.s->flags&SF_LOOP)?1:0); - if ((a->master)&&(a==a->master->slave)) - pp<<=2; - - if (pp8000*7) return -1; - return t; -} - -static SWORD Interpolate(SWORD p,SWORD p1,SWORD p2,SWORD v1,SWORD v2) -{ - if ((p1==p2)||(p==p1)) return v1; - return v1+((SLONG)((p-p1)*(v2-v1))/(p2-p1)); -} - -UWORD getlinearperiod(UWORD note,ULONG fine) -{ - UWORD t; - - t=((20L+2*HIGH_OCTAVE)*OCTAVE+2-note)*32L-(fine>>1); - return t; -} - -static UWORD getlogperiod(UWORD note,ULONG fine) -{ - UWORD n,o; - UWORD p1,p2; - ULONG i; - - n=note%(2*OCTAVE); - o=note/(2*OCTAVE); - i=(n<<2)+(fine>>4); /* n*8 + fine/16 */ - - p1=logtab[i]; - p2=logtab[i+1]; - - return (Interpolate(fine>>4,0,15,p1,p2)>>o); -} - -static UWORD getoldperiod(UWORD note,ULONG speed) -{ - UWORD n,o; - - /* This happens sometimes on badly converted AMF, and old MOD */ - if (!speed) { -#ifdef MIKMOD_DEBUG - fprintf(stderr,"\rmplayer: getoldperiod() called with note=%d, speed=0 !\n",note); -#endif - return 4242; /* <- prevent divide overflow.. (42 hehe) */ - } - - n=note%(2*OCTAVE); - o=note/(2*OCTAVE); - return ((8363L*(ULONG)oldperiods[n])>>o)/speed; -} - -static UWORD GetPeriod(UWORD flags, UWORD note, ULONG speed) -{ - if (flags & UF_XMPERIODS) { - if (flags & UF_LINEAR) - return getlinearperiod(note, speed); - else - return getlogperiod(note, speed); - } else - return getoldperiod(note, speed); -} - -static SWORD InterpolateEnv(SWORD p,ENVPT *a,ENVPT *b) -{ - return (Interpolate(p,a->pos,b->pos,a->val,b->val)); -} - -static SWORD DoPan(SWORD envpan,SWORD pan) -{ - int newpan; - - newpan=pan+(((envpan-PAN_CENTER)*(128-abs(pan-PAN_CENTER)))/128); - - return (newpanPAN_RIGHT?PAN_RIGHT:newpan); -} - -static SWORD StartEnvelope(ENVPR *t,UBYTE flg,UBYTE pts,UBYTE susbeg,UBYTE susend,UBYTE beg,UBYTE end,ENVPT *p,UBYTE keyoff) -{ - t->flg=flg; - t->pts=pts; - t->susbeg=susbeg; - t->susend=susend; - t->beg=beg; - t->end=end; - t->env=p; - t->p=0; - t->a=0; - t->b=((t->flg&EF_SUSTAIN)&&(!(keyoff&KEY_OFF)))?0:1; - - /* Imago Orpheus sometimes stores an extra initial point in the envelope */ - if ((t->pts>=2)&&(t->env[0].pos==t->env[1].pos)) { - t->a++;t->b++; - } - - /* Fit in the envelope, still */ - if (t->a >= t->pts) - t->a = t->pts - 1; - if (t->b >= t->pts) - t->b = t->pts-1; - - return t->env[t->a].val; -} - -/* This procedure processes all envelope types, include volume, pitch, and - panning. Envelopes are defined by a set of points, each with a magnitude - [relating either to volume, panning position, or pitch modifier] and a tick - position. - - Envelopes work in the following manner: - - (a) Each tick the envelope is moved a point further in its progression. For - an accurate progression, magnitudes between two envelope points are - interpolated. - - (b) When progression reaches a defined point on the envelope, values are - shifted to interpolate between this point and the next, and checks for - loops or envelope end are done. - - Misc: - Sustain loops are loops that are only active as long as the keyoff flag is - clear. When a volume envelope terminates, so does the current fadeout. -*/ -static SWORD ProcessEnvelope(MP_VOICE *aout, ENVPR *t, SWORD v) -{ - if (t->flg & EF_ON) { - UBYTE a, b; /* actual points in the envelope */ - UWORD p; /* the 'tick counter' - real point being played */ - - a = t->a; - b = t->b; - p = t->p; - - /* - * Sustain loop on one point (XM type). - * Not processed if KEYOFF. - * Don't move and don't interpolate when the point is reached - */ - if ((t->flg & EF_SUSTAIN) && t->susbeg == t->susend && - (!(aout->main.keyoff & KEY_OFF) && p == t->env[t->susbeg].pos)) { - v = t->env[t->susbeg].val; - } else { - /* - * All following situations will require interpolation between - * two envelope points. - */ - - /* - * Sustain loop between two points (IT type). - * Not processed if KEYOFF. - */ - /* if we were on a loop point, loop now */ - if ((t->flg & EF_SUSTAIN) && !(aout->main.keyoff & KEY_OFF) && - a >= t->susend) { - a = t->susbeg; - b = (t->susbeg==t->susend)?a:a+1; - p = t->env[a].pos; - v = t->env[a].val; - } else - /* - * Regular loop. - * Be sure to correctly handle single point loops. - */ - if ((t->flg & EF_LOOP) && a >= t->end) { - a = t->beg; - b = t->beg == t->end ? a : a + 1; - p = t->env[a].pos; - v = t->env[a].val; - } else - /* - * Non looping situations. - */ - if (a != b) - v = InterpolateEnv(p, &t->env[a], &t->env[b]); - else - v = t->env[a].val; - - /* - * Start to fade if the volume envelope is finished. - */ - if (p >= t->env[t->pts - 1].pos) { - if (t->flg & EF_VOLENV) { - aout->main.keyoff |= KEY_FADE; - if (!v) - aout->main.fadevol = 0; - } - } else { - p++; - /* did pointer reach point b? */ - if (p >= t->env[b].pos) - a = b++; /* shift points a and b */ - } - t->a = a; - t->b = b; - t->p = p; - } - } - return v; -} - -/* XM linear period to frequency conversion */ -ULONG getfrequency(UWORD flags,ULONG period) -{ - if (flags & UF_LINEAR) { - SLONG shift = ((SLONG)period / 768) - HIGH_OCTAVE; - - if (shift >= 0) - return lintab[period % 768] >> shift; - else - return lintab[period % 768] << (-shift); - } else - return (8363L*1712L)/(period?period:1); -} - -/*========== Protracker effects */ - -static void DoArpeggio(UWORD tick, UWORD flags, MP_CONTROL *a, UBYTE style) -{ - UBYTE note=a->main.note; - - if (a->arpmem) { - switch (style) { - case 0: /* mod style: N, N+x, N+y */ - switch (tick % 3) { - /* case 0: unchanged */ - case 1: - note += (a->arpmem >> 4); - break; - case 2: - note += (a->arpmem & 0xf); - break; - } - break; - case 3: /* okt arpeggio 3: N-x, N, N+y */ - switch (tick % 3) { - case 0: - note -= (a->arpmem >> 4); - break; - /* case 1: unchanged */ - case 2: - note += (a->arpmem & 0xf); - break; - } - break; - case 4: /* okt arpeggio 4: N, N+y, N, N-x */ - switch (tick % 4) { - /* case 0, case 2: unchanged */ - case 1: - note += (a->arpmem & 0xf); - break; - case 3: - note -= (a->arpmem >> 4); - break; - } - break; - case 5: /* okt arpeggio 5: N-x, N+y, N, and nothing at tick 0 */ - if (!tick) - break; - switch (tick % 3) { - /* case 0: unchanged */ - case 1: - note -= (a->arpmem >> 4); - break; - case 2: - note += (a->arpmem & 0xf); - break; - } - break; - } - a->main.period = GetPeriod(flags, (UWORD)note << 1, a->speed); - a->ownper = 1; - } -} - -static int DoPTEffect0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat = UniGetByte(); - if (!tick) { - if (!dat && (flags & UF_ARPMEM)) - dat=a->arpmem; - else - a->arpmem=dat; - } - if (a->main.period) - DoArpeggio(tick, flags, a, 0); - - return 0; -} - -static int DoPTEffect1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat = UniGetByte(); - if (!tick && dat) - a->slidespeed = (UWORD)dat << 2; - if (a->main.period) - if (tick) - a->tmpperiod -= a->slidespeed; - - return 0; -} - -static int DoPTEffect2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat = UniGetByte(); - if (!tick && dat) - a->slidespeed = (UWORD)dat << 2; - if (a->main.period) - if (tick) - a->tmpperiod += a->slidespeed; - - return 0; -} - -static void DoToneSlide(UWORD tick, MP_CONTROL *a) -{ - if (!a->main.fadevol) - a->main.kick = (a->main.kick == KICK_NOTE)? KICK_NOTE : KICK_KEYOFF; - else - a->main.kick = (a->main.kick == KICK_NOTE)? KICK_ENV : KICK_ABSENT; - - if (tick != 0) { - int dist; - - /* We have to slide a->main.period towards a->wantedperiod, so compute - the difference between those two values */ - dist=a->main.period-a->wantedperiod; - - /* if they are equal or if portamentospeed is too big ...*/ - if (dist == 0 || a->portspeed > abs(dist)) - /* ...make tmpperiod equal tperiod */ - a->tmpperiod=a->main.period=a->wantedperiod; - else if (dist>0) { - a->tmpperiod-=a->portspeed; - a->main.period-=a->portspeed; /* dist>0, slide up */ - } else { - a->tmpperiod+=a->portspeed; - a->main.period+=a->portspeed; /* dist<0, slide down */ - } - } else - a->tmpperiod=a->main.period; - a->ownper = 1; -} - -static int DoPTEffect3(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if ((!tick)&&(dat)) a->portspeed=(UWORD)dat<<2; - if (a->main.period) - DoToneSlide(tick, a); - - return 0; -} - -static void DoVibrato(UWORD tick, MP_CONTROL *a) -{ - UBYTE q; - UWORD temp = 0; /* silence warning */ - - if (!tick) - return; - - q=(a->vibpos>>2)&0x1f; - - switch (a->wavecontrol&3) { - case 0: /* sine */ - temp=VibratoTable[q]; - break; - case 1: /* ramp down */ - q<<=3; - if (a->vibpos<0) q=255-q; - temp=q; - break; - case 2: /* square wave */ - temp=255; - break; - case 3: /* random wave */ - temp=getrandom(256); - break; - } - - temp*=a->vibdepth; - temp>>=7;temp<<=2; - - if (a->vibpos>=0) - a->main.period=a->tmpperiod+temp; - else - a->main.period=a->tmpperiod-temp; - a->ownper = 1; - - if (tick != 0) - a->vibpos+=a->vibspd; -} - -static int DoPTEffect4(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (!tick) { - if (dat&0x0f) a->vibdepth=dat&0xf; - if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; - } - if (a->main.period) - DoVibrato(tick, a); - - return 0; -} - -static void DoVolSlide(MP_CONTROL *a, UBYTE dat) -{ - if (dat&0xf) { - a->tmpvolume-=(dat&0x0f); - if (a->tmpvolume<0) - a->tmpvolume=0; - } else { - a->tmpvolume+=(dat>>4); - if (a->tmpvolume>64) - a->tmpvolume=64; - } -} - -static int DoPTEffect5(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (a->main.period) - DoToneSlide(tick, a); - - if (tick) - DoVolSlide(a, dat); - - return 0; -} - -/* DoPTEffect6 after DoPTEffectA */ - -static int DoPTEffect7(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - UBYTE q; - UWORD temp = 0; /* silence warning */ - - dat=UniGetByte(); - if (!tick) { - if (dat&0x0f) a->trmdepth=dat&0xf; - if (dat&0xf0) a->trmspd=(dat&0xf0)>>2; - } - if (a->main.period) { - q=(a->trmpos>>2)&0x1f; - - switch ((a->wavecontrol>>4)&3) { - case 0: /* sine */ - temp=VibratoTable[q]; - break; - case 1: /* ramp down */ - q<<=3; - if (a->trmpos<0) q=255-q; - temp=q; - break; - case 2: /* square wave */ - temp=255; - break; - case 3: /* random wave */ - temp=getrandom(256); - break; - } - temp*=a->trmdepth; - temp>>=6; - - if (a->trmpos>=0) { - a->volume=a->tmpvolume+temp; - if (a->volume>64) a->volume=64; - } else { - a->volume=a->tmpvolume-temp; - if (a->volume<0) a->volume=0; - } - a->ownvol = 1; - - if (tick) - a->trmpos+=a->trmspd; - } - - return 0; -} - -static int DoPTEffect8(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat = UniGetByte(); - if (mod->panflag) - a->main.panning = mod->panning[channel] = dat; - - return 0; -} - -static int DoPTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (!tick) { - if (dat) a->soffset=(UWORD)dat<<8; - a->main.start=a->hioffset|a->soffset; - - if ((a->main.s)&&(a->main.start>a->main.s->length)) - a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? - a->main.s->loopstart:a->main.s->length; - } - - return 0; -} - -static int DoPTEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (tick) - DoVolSlide(a, dat); - - return 0; -} - -static int DoPTEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - if (a->main.period) - DoVibrato(tick, a); - DoPTEffectA(tick, flags, a, mod, channel); - - return 0; -} - -static int DoPTEffectB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - - if (tick || mod->patdly2) - return 0; - - /* Vincent Voois uses a nasty trick in "Universal Bolero" */ - if (dat == mod->sngpos && mod->patbrk == mod->patpos) - return 0; - - if (!mod->loop && !mod->patbrk && - (dat < mod->sngpos || - (mod->sngpos == (mod->numpos - 1) && !mod->patbrk) || - (dat == mod->sngpos && (flags & UF_NOWRAP)) - )) { - /* if we don't loop, better not to skip the end of the - pattern, after all... so: - mod->patbrk=0; */ - mod->posjmp=3; - } else { - /* if we were fading, adjust... */ - if (mod->sngpos == (mod->numpos-1)) - mod->volume=mod->initvolume>128?128:mod->initvolume; - mod->sngpos=dat; - mod->posjmp=2; - mod->patpos=0; - } - - return 0; -} - -static int DoPTEffectC(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (tick) return 0; - if (dat==(UBYTE)-1) a->anote=dat=0; /* note cut */ - else if (dat>64) dat=64; - a->tmpvolume=dat; - - return 0; -} - -static int DoPTEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if ((tick)||(mod->patdly2)) return 0; - if ((mod->positions[mod->sngpos]!=LAST_PATTERN)&& - (dat>mod->pattrows[mod->positions[mod->sngpos]])) - dat=mod->pattrows[mod->positions[mod->sngpos]]; - mod->patbrk=dat; - if (!mod->posjmp) { - /* don't ask me to explain this code - it makes - backwards.s3m and children.xm (heretic's version) play - correctly, among others. Take that for granted, or write - the page of comments yourself... you might need some - aspirin - Miod */ - if ((mod->sngpos==mod->numpos-1)&&(dat)&&((mod->loop)|| - (mod->positions[mod->sngpos]==(mod->numpat-1) - && !(flags&UF_NOWRAP)))) { - mod->sngpos=0; - mod->posjmp=2; - } else - mod->posjmp=3; - } - - return 0; -} - -static void DoEEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, - SWORD channel, UBYTE dat) -{ - UBYTE nib = dat & 0xf; - - switch (dat>>4) { - case 0x0: /* hardware filter toggle, not supported */ - break; - case 0x1: /* fineslide up */ - if (a->main.period) - if (!tick) - a->tmpperiod-=(nib<<2); - break; - case 0x2: /* fineslide dn */ - if (a->main.period) - if (!tick) - a->tmpperiod+=(nib<<2); - break; - case 0x3: /* glissando ctrl */ - a->glissando=nib; - break; - case 0x4: /* set vibrato waveform */ - a->wavecontrol&=0xf0; - a->wavecontrol|=nib; - break; - case 0x5: /* set finetune */ - if (a->main.period) { - if (flags&UF_XMPERIODS) - a->speed=nib+128; - else - a->speed=finetune[nib]; - a->tmpperiod=GetPeriod(flags, (UWORD)a->main.note<<1,a->speed); - } - break; - case 0x6: /* set patternloop */ - if (tick) - break; - if (nib) { /* set reppos or repcnt ? */ - /* set repcnt, so check if repcnt already is set, which means we - are already looping */ - if (a->pat_repcnt) - a->pat_repcnt--; /* already looping, decrease counter */ - else { -#if 0 - /* this would make walker.xm, shipped with Xsoundtracker, - play correctly, but it's better to remain compatible - with FT2 */ - if ((!(flags&UF_NOWRAP))||(a->pat_reppos!=POS_NONE)) -#endif - a->pat_repcnt=nib; /* not yet looping, so set repcnt */ - } - - if (a->pat_repcnt) { /* jump to reppos if repcnt>0 */ - if (a->pat_reppos==POS_NONE) - a->pat_reppos=mod->patpos-1; - if (a->pat_reppos==-1) { - mod->pat_repcrazy=1; - mod->patpos=0; - } else - mod->patpos=a->pat_reppos; - } else a->pat_reppos=POS_NONE; - } else - a->pat_reppos=mod->patpos-1; /* set reppos - can be (-1) */ - break; - case 0x7: /* set tremolo waveform */ - a->wavecontrol&=0x0f; - a->wavecontrol|=nib<<4; - break; - case 0x8: /* set panning */ - if (mod->panflag) { - if (nib<=8) nib<<=4; - else nib*=17; - a->main.panning=mod->panning[channel]=nib; - } - break; - case 0x9: /* retrig note */ - /* do not retrigger on tick 0, until we are emulating FT2 and effect - data is zero */ - if (!tick && !((flags & UF_FT2QUIRKS) && (!nib))) - break; - /* only retrigger if data nibble > 0, or if tick 0 (FT2 compat) */ - if (nib || !tick) { - if (!a->retrig) { - /* when retrig counter reaches 0, reset counter and restart - the sample */ - if (a->main.period) a->main.kick=KICK_NOTE; - a->retrig=nib; - } - a->retrig--; /* countdown */ - } - break; - case 0xa: /* fine volume slide up */ - if (tick) - break; - a->tmpvolume+=nib; - if (a->tmpvolume>64) a->tmpvolume=64; - break; - case 0xb: /* fine volume slide dn */ - if (tick) - break; - a->tmpvolume-=nib; - if (a->tmpvolume<0)a->tmpvolume=0; - break; - case 0xc: /* cut note */ - /* When tick reaches the cut-note value, turn the volume to - zero (just like on the amiga) */ - if (tick>=nib) - a->tmpvolume=0; /* just turn the volume down */ - break; - case 0xd: /* note delay */ - /* delay the start of the sample until tick==nib */ - if (!tick) - a->main.notedelay=nib; - else if (a->main.notedelay) - a->main.notedelay--; - break; - case 0xe: /* pattern delay */ - if (!tick) - if (!mod->patdly2) - mod->patdly=nib+1; /* only once, when tick=0 */ - break; - case 0xf: /* invert loop, not supported */ - break; - } -} - -static int DoPTEffectE(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - DoEEffects(tick, flags, a, mod, channel, UniGetByte()); - - return 0; -} - -static int DoPTEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (tick||mod->patdly2) return 0; - if (mod->extspd&&(dat>=mod->bpmlimit)) - mod->bpm=dat; - else - if (dat) { - mod->sngspd=(dat>=mod->bpmlimit)?mod->bpmlimit-1:dat; - mod->vbtick=0; - } - - return 0; -} - -/*========== Scream Tracker effects */ - -static int DoS3MEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE speed; - - speed = UniGetByte(); - - if (tick || mod->patdly2) - return 0; - - if (speed > 128) - speed -= 128; - if (speed) { - mod->sngspd = speed; - mod->vbtick = 0; - } - - return 0; -} - -static void DoS3MVolSlide(UWORD tick, UWORD flags, MP_CONTROL *a, UBYTE inf) -{ - UBYTE lo, hi; - - if (inf) - a->s3mvolslide=inf; - else - inf=a->s3mvolslide; - - lo=inf&0xf; - hi=inf>>4; - - if (!lo) { - if ((tick)||(flags&UF_S3MSLIDES)) a->tmpvolume+=hi; - } else - if (!hi) { - if ((tick)||(flags&UF_S3MSLIDES)) a->tmpvolume-=lo; - } else - if (lo==0xf) { - if (!tick) a->tmpvolume+=(hi?hi:0xf); - } else - if (hi==0xf) { - if (!tick) a->tmpvolume-=(lo?lo:0xf); - } else - return; - - if (a->tmpvolume<0) - a->tmpvolume=0; - else if (a->tmpvolume>64) - a->tmpvolume=64; -} - -static int DoS3MEffectD(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - DoS3MVolSlide(tick, flags, a, UniGetByte()); - - return 1; -} - -static void DoS3MSlideDn(UWORD tick, MP_CONTROL *a, UBYTE inf) -{ - UBYTE hi,lo; - - if (inf) - a->slidespeed=inf; - else - inf=a->slidespeed; - - hi=inf>>4; - lo=inf&0xf; - - if (hi==0xf) { - if (!tick) a->tmpperiod+=(UWORD)lo<<2; - } else - if (hi==0xe) { - if (!tick) a->tmpperiod+=lo; - } else { - if (tick) a->tmpperiod+=(UWORD)inf<<2; - } -} - -static int DoS3MEffectE(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (a->main.period) - DoS3MSlideDn(tick, a,dat); - - return 0; -} - -static void DoS3MSlideUp(UWORD tick, MP_CONTROL *a, UBYTE inf) -{ - UBYTE hi,lo; - - if (inf) a->slidespeed=inf; - else inf=a->slidespeed; - - hi=inf>>4; - lo=inf&0xf; - - if (hi==0xf) { - if (!tick) a->tmpperiod-=(UWORD)lo<<2; - } else - if (hi==0xe) { - if (!tick) a->tmpperiod-=lo; - } else { - if (tick) a->tmpperiod-=(UWORD)inf<<2; - } -} - -static int DoS3MEffectF(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (a->main.period) - DoS3MSlideUp(tick, a,dat); - - return 0; -} - -static int DoS3MEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf, on, off; - - inf = UniGetByte(); - if (inf) - a->s3mtronof = inf; - else { - inf = a->s3mtronof; - if (!inf) - return 0; - } - - if (!tick) - return 0; - - on=(inf>>4)+1; - off=(inf&0xf)+1; - a->s3mtremor%=(on+off); - a->volume=(a->s3mtremortmpvolume:0; - a->ownvol=1; - a->s3mtremor++; - - return 0; -} - -static int DoS3MEffectQ(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf; - - inf = UniGetByte(); - if (a->main.period) { - if (inf) { - a->s3mrtgslide=inf>>4; - a->s3mrtgspeed=inf&0xf; - } - - /* only retrigger if low nibble > 0 */ - if (a->s3mrtgspeed>0) { - if (!a->retrig) { - /* when retrig counter reaches 0, reset counter and restart the - sample */ - if (a->main.kick!=KICK_NOTE) a->main.kick=KICK_KEYOFF; - a->retrig=a->s3mrtgspeed; - - if ((tick)||(flags&UF_S3MSLIDES)) { - switch (a->s3mrtgslide) { - case 1: - case 2: - case 3: - case 4: - case 5: - a->tmpvolume-=(1<<(a->s3mrtgslide-1)); - break; - case 6: - a->tmpvolume=(2*a->tmpvolume)/3; - break; - case 7: - a->tmpvolume>>=1; - break; - case 9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - a->tmpvolume+=(1<<(a->s3mrtgslide-9)); - break; - case 0xe: - a->tmpvolume=(3*a->tmpvolume)>>1; - break; - case 0xf: - a->tmpvolume=a->tmpvolume<<1; - break; - } - if (a->tmpvolume<0) - a->tmpvolume=0; - else if (a->tmpvolume>64) - a->tmpvolume=64; - } - } - a->retrig--; /* countdown */ - } - } - - return 0; -} - -static int DoS3MEffectR(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat, q; - UWORD temp=0; /* silence warning */ - - dat = UniGetByte(); - if (!tick) { - if (dat&0x0f) a->trmdepth=dat&0xf; - if (dat&0xf0) a->trmspd=(dat&0xf0)>>2; - } - - q=(a->trmpos>>2)&0x1f; - - switch ((a->wavecontrol>>4)&3) { - case 0: /* sine */ - temp=VibratoTable[q]; - break; - case 1: /* ramp down */ - q<<=3; - if (a->trmpos<0) q=255-q; - temp=q; - break; - case 2: /* square wave */ - temp=255; - break; - case 3: /* random */ - temp=getrandom(256); - break; - } - - temp*=a->trmdepth; - temp>>=7; - - if (a->trmpos>=0) { - a->volume=a->tmpvolume+temp; - if (a->volume>64) a->volume=64; - } else { - a->volume=a->tmpvolume-temp; - if (a->volume<0) a->volume=0; - } - a->ownvol = 1; - - if (tick) - a->trmpos+=a->trmspd; - - return 0; -} - -static int DoS3MEffectT(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE tempo; - - tempo = UniGetByte(); - - if (tick || mod->patdly2) - return 0; - - mod->bpm = (tempo < 32) ? 32 : tempo; - - return 0; -} - -static int DoS3MEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat, q; - UWORD temp = 0; /* silence warning */ - - dat = UniGetByte(); - if (!tick) { - if (dat&0x0f) a->vibdepth=dat&0xf; - if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; - } else - if (a->main.period) { - q=(a->vibpos>>2)&0x1f; - - switch (a->wavecontrol&3) { - case 0: /* sine */ - temp=VibratoTable[q]; - break; - case 1: /* ramp down */ - q<<=3; - if (a->vibpos<0) q=255-q; - temp=q; - break; - case 2: /* square wave */ - temp=255; - break; - case 3: /* random */ - temp=getrandom(256); - break; - } - - temp*=a->vibdepth; - temp>>=8; - - if (a->vibpos>=0) - a->main.period=a->tmpperiod+temp; - else - a->main.period=a->tmpperiod-temp; - a->ownper = 1; - - a->vibpos+=a->vibspd; - } - - return 0; -} - -/*========== Envelope helpers */ - -static int DoKeyOff(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - a->main.keyoff|=KEY_OFF; - if ((!(a->main.volflg&EF_ON))||(a->main.volflg&EF_LOOP)) - a->main.keyoff=KEY_KILL; - - return 0; -} - -static int DoKeyFade(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if ((tick>=dat)||(tick==mod->sngspd-1)) { - a->main.keyoff=KEY_KILL; - if (!(a->main.volflg&EF_ON)) - a->main.fadevol=0; - } - - return 0; -} - -/*========== Fast Tracker effects */ - -/* DoXMEffect6 after DoXMEffectA */ - -static int DoXMEffectA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf, lo, hi; - - inf = UniGetByte(); - if (inf) - a->s3mvolslide = inf; - else - inf = a->s3mvolslide; - - if (tick) { - lo=inf&0xf; - hi=inf>>4; - - if (!hi) { - a->tmpvolume-=lo; - if (a->tmpvolume<0) a->tmpvolume=0; - } else { - a->tmpvolume+=hi; - if (a->tmpvolume>64) a->tmpvolume=64; - } - } - - return 0; -} - -static int DoXMEffect6(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - if (a->main.period) - DoVibrato(tick, a); - - return DoXMEffectA(tick, flags, a, mod, channel); -} - -static int DoXMEffectE1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (!tick) { - if (dat) a->fportupspd=dat; - if (a->main.period) - a->tmpperiod-=(a->fportupspd<<2); - } - - return 0; -} - -static int DoXMEffectE2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (!tick) { - if (dat) a->fportdnspd=dat; - if (a->main.period) - a->tmpperiod+=(a->fportdnspd<<2); - } - - return 0; -} - -static int DoXMEffectEA(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (!tick) - if (dat) a->fslideupspd=dat; - a->tmpvolume+=a->fslideupspd; - if (a->tmpvolume>64) a->tmpvolume=64; - - return 0; -} - -static int DoXMEffectEB(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if (!tick) - if (dat) a->fslidednspd=dat; - a->tmpvolume-=a->fslidednspd; - if (a->tmpvolume<0) a->tmpvolume=0; - - return 0; -} - -static int DoXMEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - mod->volume=UniGetByte()<<1; - if (mod->volume>128) mod->volume=128; - - return 0; -} - -static int DoXMEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf; - - inf = UniGetByte(); - - if (tick) { - if (inf) mod->globalslide=inf; - else inf=mod->globalslide; - if (inf & 0xf0) inf&=0xf0; - mod->volume=mod->volume+((inf>>4)-(inf&0xf))*2; - - if (mod->volume<0) - mod->volume=0; - else if (mod->volume>128) - mod->volume=128; - } - - return 0; -} - -static int DoXMEffectL(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat=UniGetByte(); - if ((!tick)&&(a->main.i)) { - UWORD points; - INSTRUMENT *i=a->main.i; - MP_VOICE *aout; - - if ((aout=a->slave)) { - if (aout->venv.env) { - points=i->volenv[i->volpts-1].pos; - aout->venv.p=aout->venv.env[(dat>points)?points:dat].pos; - } - if (aout->penv.env) { - points=i->panenv[i->panpts-1].pos; - aout->penv.p=aout->penv.env[(dat>points)?points:dat].pos; - } - } - } - - return 0; -} - -static int DoXMEffectP(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf, lo, hi; - SWORD pan; - - inf = UniGetByte(); - if (!mod->panflag) - return 0; - - if (inf) - a->pansspd = inf; - else - inf =a->pansspd; - - if (tick) { - lo=inf&0xf; - hi=inf>>4; - - /* slide right has absolute priority */ - if (hi) - lo = 0; - - pan=((a->main.panning==PAN_SURROUND)?PAN_CENTER:a->main.panning)+hi-lo; - a->main.panning=(panPAN_RIGHT?PAN_RIGHT:pan); - } - - return 0; -} - -static int DoXMEffectX1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat = UniGetByte(); - if (dat) - a->ffportupspd = dat; - else - dat = a->ffportupspd; - - if (a->main.period) - if (!tick) { - a->main.period-=dat; - a->tmpperiod-=dat; - a->ownper = 1; - } - - return 0; -} - -static int DoXMEffectX2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat; - - dat = UniGetByte(); - if (dat) - a->ffportdnspd=dat; - else - dat = a->ffportdnspd; - - if (a->main.period) - if (!tick) { - a->main.period+=dat; - a->tmpperiod+=dat; - a->ownper = 1; - } - - return 0; -} - -/*========== Impulse Tracker effects */ - -static void DoITToneSlide(UWORD tick, MP_CONTROL *a, UBYTE dat) -{ - if (dat) - a->portspeed = dat; - - /* if we don't come from another note, ignore the slide and play the note - as is */ - if (!a->oldnote || !a->main.period) - return; - - if ((!tick)&&(a->newsamp)){ - a->main.kick=KICK_NOTE; - a->main.start=-1; - } else - a->main.kick=(a->main.kick==KICK_NOTE)?KICK_ENV:KICK_ABSENT; - - if (tick) { - int dist; - - /* We have to slide a->main.period towards a->wantedperiod, compute the - difference between those two values */ - dist=a->main.period-a->wantedperiod; - - /* if they are equal or if portamentospeed is too big... */ - if ((!dist)||((a->portspeed<<2)>abs(dist))) - /* ... make tmpperiod equal tperiod */ - a->tmpperiod=a->main.period=a->wantedperiod; - else - if (dist>0) { - a->tmpperiod-=a->portspeed<<2; - a->main.period-=a->portspeed<<2; /* dist>0 slide up */ - } else { - a->tmpperiod+=a->portspeed<<2; - a->main.period+=a->portspeed<<2; /* dist<0 slide down */ - } - } else - a->tmpperiod=a->main.period; - a->ownper=1; -} - -static int DoITEffectG(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - DoITToneSlide(tick, a, UniGetByte()); - - return 0; -} - -static void DoITVibrato(UWORD tick, MP_CONTROL *a, UBYTE dat) -{ - UBYTE q; - UWORD temp=0; - - if (!tick) { - if (dat&0x0f) a->vibdepth=dat&0xf; - if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; - } - if (!a->main.period) - return; - - q=(a->vibpos>>2)&0x1f; - - switch (a->wavecontrol&3) { - case 0: /* sine */ - temp=VibratoTable[q]; - break; - case 1: /* square wave */ - temp=255; - break; - case 2: /* ramp down */ - q<<=3; - if (a->vibpos<0) q=255-q; - temp=q; - break; - case 3: /* random */ - temp=getrandom(256); - break; - } - - temp*=a->vibdepth; - temp>>=8; - temp<<=2; - - if (a->vibpos>=0) - a->main.period=a->tmpperiod+temp; - else - a->main.period=a->tmpperiod-temp; - a->ownper=1; - - a->vibpos+=a->vibspd; -} - -static int DoITEffectH(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - DoITVibrato(tick, a, UniGetByte()); - - return 0; -} - -static int DoITEffectI(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf, on, off; - - inf = UniGetByte(); - if (inf) - a->s3mtronof = inf; - else { - inf = a->s3mtronof; - if (!inf) - return 0; - } - - on=(inf>>4); - off=(inf&0xf); - - a->s3mtremor%=(on+off); - a->volume=(a->s3mtremortmpvolume:0; - a->ownvol = 1; - a->s3mtremor++; - - return 0; -} - -static int DoITEffectM(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - a->main.chanvol=UniGetByte(); - if (a->main.chanvol>64) - a->main.chanvol=64; - else if (a->main.chanvol<0) - a->main.chanvol=0; - - return 0; -} - -static int DoITEffectN(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf, lo, hi; - - inf = UniGetByte(); - - if (inf) - a->chanvolslide = inf; - else - inf = a->chanvolslide; - - lo=inf&0xf; - hi=inf>>4; - - if (!hi) - a->main.chanvol-=lo; - else - if (!lo) { - a->main.chanvol+=hi; - } else - if (hi==0xf) { - if (!tick) a->main.chanvol-=lo; - } else - if (lo==0xf) { - if (!tick) a->main.chanvol+=hi; - } - - if (a->main.chanvol<0) - a->main.chanvol=0; - else if (a->main.chanvol>64) - a->main.chanvol=64; - - return 0; -} - -static int DoITEffectP(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf, lo, hi; - SWORD pan; - - inf = UniGetByte(); - if (inf) - a->pansspd = inf; - else - inf = a->pansspd; - - if (!mod->panflag) - return 0; - - lo=inf&0xf; - hi=inf>>4; - - pan=(a->main.panning==PAN_SURROUND)?PAN_CENTER:a->main.panning; - - if (!hi) - pan+=lo<<2; - else - if (!lo) { - pan-=hi<<2; - } else - if (hi==0xf) { - if (!tick) pan+=lo<<2; - } else - if (lo==0xf) { - if (!tick) pan-=hi<<2; - } - a->main.panning= - (panPAN_RIGHT?PAN_RIGHT:pan); - - return 0; -} - -static int DoITEffectT(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE tempo; - SWORD temp; - - tempo = UniGetByte(); - - if (mod->patdly2) - return 0; - - temp = mod->bpm; - if (tempo & 0x10) - temp += (tempo & 0x0f); - else - temp -= tempo; - - mod->bpm=(temp>255)?255:(temp<1?1:temp); - - return 0; -} - -static int DoITEffectU(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat, q; - UWORD temp = 0; /* silence warning */ - - dat = UniGetByte(); - if (!tick) { - if (dat&0x0f) a->vibdepth=dat&0xf; - if (dat&0xf0) a->vibspd=(dat&0xf0)>>2; - } - if (a->main.period) { - q=(a->vibpos>>2)&0x1f; - - switch (a->wavecontrol&3) { - case 0: /* sine */ - temp=VibratoTable[q]; - break; - case 1: /* square wave */ - temp=255; - break; - case 2: /* ramp down */ - q<<=3; - if (a->vibpos<0) q=255-q; - temp=q; - break; - case 3: /* random */ - temp=getrandom(256); - break; - } - - temp*=a->vibdepth; - temp>>=8; - - if (a->vibpos>=0) - a->main.period=a->tmpperiod+temp; - else - a->main.period=a->tmpperiod-temp; - a->ownper = 1; - - a->vibpos+=a->vibspd; - } - - return 0; -} - -static int DoITEffectW(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE inf, lo, hi; - - inf = UniGetByte(); - - if (inf) - mod->globalslide = inf; - else - inf = mod->globalslide; - - lo=inf&0xf; - hi=inf>>4; - - if (!lo) { - if (tick) mod->volume+=hi; - } else - if (!hi) { - if (tick) mod->volume-=lo; - } else - if (lo==0xf) { - if (!tick) mod->volume+=hi; - } else - if (hi==0xf) { - if (!tick) mod->volume-=lo; - } - - if (mod->volume<0) - mod->volume=0; - else if (mod->volume>128) - mod->volume=128; - - return 0; -} - -static int DoITEffectY(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat, q; - SLONG temp = 0; /* silence warning */ - - - dat=UniGetByte(); - if (!tick) { - if (dat&0x0f) a->panbdepth=(dat&0xf); - if (dat&0xf0) a->panbspd=(dat&0xf0)>>4; - } - if (mod->panflag) { - q=a->panbpos; - - switch (a->panbwave) { - case 0: /* sine */ - temp=PanbrelloTable[q]; - break; - case 1: /* square wave */ - temp=(q<0x80)?64:0; - break; - case 2: /* ramp down */ - q<<=3; - temp=q; - break; - case 3: /* random */ - temp=getrandom(256); - break; - } - - temp*=a->panbdepth; - temp=(temp/8)+mod->panning[channel]; - - a->main.panning= - (tempPAN_RIGHT?PAN_RIGHT:temp); - a->panbpos+=a->panbspd; - - } - - return 0; -} - -static void DoNNAEffects(MODULE *, MP_CONTROL *, UBYTE); - -/* Impulse/Scream Tracker Sxx effects. - All Sxx effects share the same memory space. */ -static int DoITEffectS0(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat, inf, c; - - dat = UniGetByte(); - inf=dat&0xf; - c=dat>>4; - - if (!dat) { - c=a->sseffect; - inf=a->ssdata; - } else { - a->sseffect=c; - a->ssdata=inf; - } - - switch (c) { - case SS_GLISSANDO: /* S1x set glissando voice */ - DoEEffects(tick, flags, a, mod, channel, 0x30|inf); - break; - case SS_FINETUNE: /* S2x set finetune */ - DoEEffects(tick, flags, a, mod, channel, 0x50|inf); - break; - case SS_VIBWAVE: /* S3x set vibrato waveform */ - DoEEffects(tick, flags, a, mod, channel, 0x40|inf); - break; - case SS_TREMWAVE: /* S4x set tremolo waveform */ - DoEEffects(tick, flags, a, mod, channel, 0x70|inf); - break; - case SS_PANWAVE: /* S5x panbrello */ - a->panbwave=inf; - break; - case SS_FRAMEDELAY: /* S6x delay x number of frames (patdly) */ - DoEEffects(tick, flags, a, mod, channel, 0xe0|inf); - break; - case SS_S7EFFECTS: /* S7x instrument / NNA commands */ - DoNNAEffects(mod, a, inf); - break; - case SS_PANNING: /* S8x set panning position */ - DoEEffects(tick, flags, a, mod, channel, 0x80 | inf); - break; - case SS_SURROUND: /* S9x set surround sound */ - if (mod->panflag) - a->main.panning = mod->panning[channel] = PAN_SURROUND; - break; - case SS_HIOFFSET: /* SAy set high order sample offset yxx00h */ - if (!tick) { - a->hioffset=inf<<16; - a->main.start=a->hioffset|a->soffset; - - if ((a->main.s)&&(a->main.start>a->main.s->length)) - a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? - a->main.s->loopstart:a->main.s->length; - } - break; - case SS_PATLOOP: /* SBx pattern loop */ - DoEEffects(tick, flags, a, mod, channel, 0x60|inf); - break; - case SS_NOTECUT: /* SCx notecut */ - if (!inf) inf = 1; - DoEEffects(tick, flags, a, mod, channel, 0xC0|inf); - break; - case SS_NOTEDELAY: /* SDx notedelay */ - DoEEffects(tick, flags, a, mod, channel, 0xD0|inf); - break; - case SS_PATDELAY: /* SEx patterndelay */ - DoEEffects(tick, flags, a, mod, channel, 0xE0|inf); - break; - } - - return 0; -} - -/*========== Impulse Tracker Volume/Pan Column effects */ - -/* - * All volume/pan column effects share the same memory space. - */ - -static int DoVolEffects(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE c, inf; - - c = UniGetByte(); - inf = UniGetByte(); - - if ((!c)&&(!inf)) { - c=a->voleffect; - inf=a->voldata; - } else { - a->voleffect=c; - a->voldata=inf; - } - - if (c) - switch (c) { - case VOL_VOLUME: - if (tick) break; - if (inf>64) inf=64; - a->tmpvolume=inf; - break; - case VOL_PANNING: - if (mod->panflag) - a->main.panning=inf; - break; - case VOL_VOLSLIDE: - DoS3MVolSlide(tick, flags, a, inf); - return 1; - case VOL_PITCHSLIDEDN: - if (a->main.period) - DoS3MSlideDn(tick, a, inf); - break; - case VOL_PITCHSLIDEUP: - if (a->main.period) - DoS3MSlideUp(tick, a, inf); - break; - case VOL_PORTAMENTO: - DoITToneSlide(tick, a, inf); - break; - case VOL_VIBRATO: - DoITVibrato(tick, a, inf); - break; - } - - return 0; -} - -/*========== UltraTracker effects */ - -static int DoULTEffect9(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UWORD offset=UniGetWord(); - - if (offset) - a->ultoffset=offset; - - a->main.start=a->ultoffset<<2; - if ((a->main.s)&&(a->main.start>a->main.s->length)) - a->main.start=a->main.s->flags&(SF_LOOP|SF_BIDI)? - a->main.s->loopstart:a->main.s->length; - - return 0; -} - -/*========== OctaMED effects */ - -static int DoMEDSpeed(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UWORD speed=UniGetWord(); - - mod->bpm=speed; - - return 0; -} - -static int DoMEDEffectF1(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - DoEEffects(tick, flags, a, mod, channel, 0x90|(mod->sngspd/2)); - - return 0; -} - -static int DoMEDEffectF2(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - DoEEffects(tick, flags, a, mod, channel, 0xd0|(mod->sngspd/2)); - - return 0; -} - -static int DoMEDEffectF3(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - DoEEffects(tick, flags, a, mod, channel, 0x90|(mod->sngspd/3)); - - return 0; -} - -/*========== Oktalyzer effects */ - -static int DoOktArp(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UBYTE dat, dat2; - - dat2 = UniGetByte(); /* arpeggio style */ - dat = UniGetByte(); - if (!tick) { - if (!dat && (flags & UF_ARPMEM)) - dat=a->arpmem; - else - a->arpmem=dat; - } - if (a->main.period) - DoArpeggio(tick, flags, a, dat2); - - return 0; -} - -static int DoXMEffectZ(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - Player_SetSynchroValue(UniGetByte()); - return 0; -} - -/*========== General player functions */ - -static int DoNothing(UWORD tick, UWORD flags, MP_CONTROL *a, MODULE *mod, SWORD channel) -{ - UniSkipOpcode(); - - return 0; -} - -typedef int (*effect_func) (UWORD, UWORD, MP_CONTROL *, MODULE *, SWORD); - -static effect_func effects[UNI_LAST] = { - DoNothing, /* 0 */ - DoNothing, /* UNI_NOTE */ - DoNothing, /* UNI_INSTRUMENT */ - DoPTEffect0, /* UNI_PTEFFECT0 */ - DoPTEffect1, /* UNI_PTEFFECT1 */ - DoPTEffect2, /* UNI_PTEFFECT2 */ - DoPTEffect3, /* UNI_PTEFFECT3 */ - DoPTEffect4, /* UNI_PTEFFECT4 */ - DoPTEffect5, /* UNI_PTEFFECT5 */ - DoPTEffect6, /* UNI_PTEFFECT6 */ - DoPTEffect7, /* UNI_PTEFFECT7 */ - DoPTEffect8, /* UNI_PTEFFECT8 */ - DoPTEffect9, /* UNI_PTEFFECT9 */ - DoPTEffectA, /* UNI_PTEFFECTA */ - DoPTEffectB, /* UNI_PTEFFECTB */ - DoPTEffectC, /* UNI_PTEFFECTC */ - DoPTEffectD, /* UNI_PTEFFECTD */ - DoPTEffectE, /* UNI_PTEFFECTE */ - DoPTEffectF, /* UNI_PTEFFECTF */ - DoS3MEffectA, /* UNI_S3MEFFECTA */ - DoS3MEffectD, /* UNI_S3MEFFECTD */ - DoS3MEffectE, /* UNI_S3MEFFECTE */ - DoS3MEffectF, /* UNI_S3MEFFECTF */ - DoS3MEffectI, /* UNI_S3MEFFECTI */ - DoS3MEffectQ, /* UNI_S3MEFFECTQ */ - DoS3MEffectR, /* UNI_S3MEFFECTR */ - DoS3MEffectT, /* UNI_S3MEFFECTT */ - DoS3MEffectU, /* UNI_S3MEFFECTU */ - DoKeyOff, /* UNI_KEYOFF */ - DoKeyFade, /* UNI_KEYFADE */ - DoVolEffects, /* UNI_VOLEFFECTS */ - DoPTEffect4, /* UNI_XMEFFECT4 */ - DoXMEffect6, /* UNI_XMEFFECT6 */ - DoXMEffectA, /* UNI_XMEFFECTA */ - DoXMEffectE1, /* UNI_XMEFFECTE1 */ - DoXMEffectE2, /* UNI_XMEFFECTE2 */ - DoXMEffectEA, /* UNI_XMEFFECTEA */ - DoXMEffectEB, /* UNI_XMEFFECTEB */ - DoXMEffectG, /* UNI_XMEFFECTG */ - DoXMEffectH, /* UNI_XMEFFECTH */ - DoXMEffectL, /* UNI_XMEFFECTL */ - DoXMEffectP, /* UNI_XMEFFECTP */ - DoXMEffectX1, /* UNI_XMEFFECTX1 */ - DoXMEffectX2, /* UNI_XMEFFECTX2 */ - DoITEffectG, /* UNI_ITEFFECTG */ - DoITEffectH, /* UNI_ITEFFECTH */ - DoITEffectI, /* UNI_ITEFFECTI */ - DoITEffectM, /* UNI_ITEFFECTM */ - DoITEffectN, /* UNI_ITEFFECTN */ - DoITEffectP, /* UNI_ITEFFECTP */ - DoITEffectT, /* UNI_ITEFFECTT */ - DoITEffectU, /* UNI_ITEFFECTU */ - DoITEffectW, /* UNI_ITEFFECTW */ - DoITEffectY, /* UNI_ITEFFECTY */ - DoNothing, /* UNI_ITEFFECTZ */ - DoITEffectS0, /* UNI_ITEFFECTS0 */ - DoULTEffect9, /* UNI_ULTEFFECT9 */ - DoMEDSpeed, /* UNI_MEDSPEED */ - DoMEDEffectF1, /* UNI_MEDEFFECTF1 */ - DoMEDEffectF2, /* UNI_MEDEFFECTF2 */ - DoMEDEffectF3, /* UNI_MEDEFFECTF3 */ - DoOktArp, /* UNI_OKTARP */ - DoXMEffectZ, /* UNI_XMEFFECTZ */ -}; - -static int pt_playeffects(MODULE *mod, SWORD channel, MP_CONTROL *a) -{ - UWORD tick = mod->vbtick; - UWORD flags = mod->flags; - UBYTE c; - int explicitslides = 0; - effect_func f; - - while((c=UniGetByte())) { - f = effects[c]; - if (f != DoNothing) - a->sliding = 0; - explicitslides |= f(tick, flags, a, mod, channel); - } - return explicitslides; -} - -static void DoNNAEffects(MODULE *mod, MP_CONTROL *a, UBYTE dat) -{ - int t; - MP_VOICE *aout; - - dat&=0xf; - aout=(a->slave)?a->slave:NULL; - - switch (dat) { - case 0x0: /* past note cut */ - for (t=0;tvoice[t].master==a) - mod->voice[t].main.fadevol=0; - break; - case 0x1: /* past note off */ - for (t=0;tvoice[t].master==a) { - mod->voice[t].main.keyoff|=KEY_OFF; - if ((!(mod->voice[t].venv.flg & EF_ON))|| - (mod->voice[t].venv.flg & EF_LOOP)) - mod->voice[t].main.keyoff=KEY_KILL; - } - break; - case 0x2: /* past note fade */ - for (t=0;tvoice[t].master==a) - mod->voice[t].main.keyoff|=KEY_FADE; - break; - case 0x3: /* set NNA note cut */ - a->main.nna=(a->main.nna&~NNA_MASK)|NNA_CUT; - break; - case 0x4: /* set NNA note continue */ - a->main.nna=(a->main.nna&~NNA_MASK)|NNA_CONTINUE; - break; - case 0x5: /* set NNA note off */ - a->main.nna=(a->main.nna&~NNA_MASK)|NNA_OFF; - break; - case 0x6: /* set NNA note fade */ - a->main.nna=(a->main.nna&~NNA_MASK)|NNA_FADE; - break; - case 0x7: /* disable volume envelope */ - if (aout) - aout->main.volflg&=~EF_ON; - break; - case 0x8: /* enable volume envelope */ - if (aout) - aout->main.volflg|=EF_ON; - break; - case 0x9: /* disable panning envelope */ - if (aout) - aout->main.panflg&=~EF_ON; - break; - case 0xa: /* enable panning envelope */ - if (aout) - aout->main.panflg|=EF_ON; - break; - case 0xb: /* disable pitch envelope */ - if (aout) - aout->main.pitflg&=~EF_ON; - break; - case 0xc: /* enable pitch envelope */ - if (aout) - aout->main.pitflg|=EF_ON; - break; - } -} - -void pt_UpdateVoices(MODULE *mod, int max_volume) -{ - SWORD envpan,envvol,envpit,channel; - UWORD playperiod; - SLONG vibval,vibdpt; - ULONG tmpvol; - - MP_VOICE *aout; - INSTRUMENT *i; - SAMPLE *s; - - mod->totalchn=mod->realchn=0; - for (channel=0;channelvoice[channel]; - i=aout->main.i; - s=aout->main.s; - - if (!s || !s->length) continue; - - if (aout->main.period<40) - aout->main.period=40; - else if (aout->main.period>50000) - aout->main.period=50000; - - if ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_KEYOFF)) { - Voice_Play_internal(channel,s,(aout->main.start==-1)? - ((s->flags&SF_UST_LOOP)?s->loopstart:0):aout->main.start); - aout->main.fadevol=32768; - aout->aswppos=0; - } - - envvol = 256; - envpan = PAN_CENTER; - envpit = 32; - if (i && ((aout->main.kick==KICK_NOTE)||(aout->main.kick==KICK_ENV))) { - if (aout->main.volflg & EF_ON) - envvol = StartEnvelope(&aout->venv,aout->main.volflg, - i->volpts,i->volsusbeg,i->volsusend, - i->volbeg,i->volend,i->volenv,aout->main.keyoff); - if (aout->main.panflg & EF_ON) - envpan = StartEnvelope(&aout->penv,aout->main.panflg, - i->panpts,i->pansusbeg,i->pansusend, - i->panbeg,i->panend,i->panenv,aout->main.keyoff); - if (aout->main.pitflg & EF_ON) - envpit = StartEnvelope(&aout->cenv,aout->main.pitflg, - i->pitpts,i->pitsusbeg,i->pitsusend, - i->pitbeg,i->pitend,i->pitenv,aout->main.keyoff); - - if (aout->cenv.flg & EF_ON) - aout->masterperiod=GetPeriod(mod->flags, - (UWORD)aout->main.note<<1, aout->master->speed); - } else { - if (aout->main.volflg & EF_ON) - envvol = ProcessEnvelope(aout,&aout->venv,256); - if (aout->main.panflg & EF_ON) - envpan = ProcessEnvelope(aout,&aout->penv,PAN_CENTER); - if (aout->main.pitflg & EF_ON) - envpit = ProcessEnvelope(aout,&aout->cenv,32); - } - aout->main.kick=KICK_ABSENT; - - tmpvol = aout->main.fadevol; /* max 32768 */ - tmpvol *= aout->main.chanvol; /* * max 64 */ - tmpvol *= aout->main.outvolume; /* * max 256 */ - tmpvol /= (256 * 64); /* tmpvol is max 32768 again */ - aout->totalvol = tmpvol >> 2; /* used to determine samplevolume */ - tmpvol *= envvol; /* * max 256 */ - tmpvol *= mod->volume; /* * max 128 */ - tmpvol /= (128 * 256 * 128); -#if 0 /* FIXME: Is this still needed? If so, where is initvolume? */ - tmpvol *= aout->main.initvolume; /* * max 128 */ - tmpvol /= 128; -#endif - - /* fade out */ - if (mod->sngpos>=mod->numpos) - tmpvol=0; - else - tmpvol=(tmpvol*max_volume)/128; - - if ((aout->masterchn!=-1)&& mod->control[aout->masterchn].muted) - Voice_SetVolume_internal(channel,0); - else { - Voice_SetVolume_internal(channel,tmpvol); - if ((tmpvol)&&(aout->master)&&(aout->master->slave==aout)) - mod->realchn++; - mod->totalchn++; - } - - if (aout->main.panning==PAN_SURROUND) - Voice_SetPanning_internal(channel,PAN_SURROUND); - else - if ((mod->panflag)&&(aout->penv.flg & EF_ON)) - Voice_SetPanning_internal(channel, - DoPan(envpan,aout->main.panning)); - else - Voice_SetPanning_internal(channel,aout->main.panning); - - if (aout->main.period && s->vibdepth) - switch (s->vibtype) { - case 0: - vibval=avibtab[s->avibpos&127]; - if (aout->avibpos & 0x80) vibval=-vibval; - break; - case 1: - vibval=64; - if (aout->avibpos & 0x80) vibval=-vibval; - break; - case 2: - vibval=63-(((aout->avibpos+128)&255)>>1); - break; - default: - vibval=(((aout->avibpos+128)&255)>>1)-64; - break; - } - else - vibval=0; - - if (s->vibflags & AV_IT) { - if ((aout->aswppos>>8)vibdepth) { - aout->aswppos += s->vibsweep; - vibdpt=aout->aswppos; - } else - vibdpt=s->vibdepth<<8; - vibval=(vibval*vibdpt)>>16; - if (aout->mflag) { - if (!(mod->flags&UF_LINEAR)) vibval>>=1; - aout->main.period-=vibval; - } - } else { - /* do XM style auto-vibrato */ - if (!(aout->main.keyoff & KEY_OFF)) { - if (aout->aswpposvibsweep) { - vibdpt=(aout->aswppos*s->vibdepth)/s->vibsweep; - aout->aswppos++; - } else - vibdpt=s->vibdepth; - } else { - /* keyoff -> depth becomes 0 if final depth wasn't reached or - stays at final level if depth WAS reached */ - if (aout->aswppos>=s->vibsweep) - vibdpt=s->vibdepth; - else - vibdpt=0; - } - vibval=(vibval*vibdpt)>>8; - aout->main.period-=vibval; - } - - /* update vibrato position */ - aout->avibpos=(aout->avibpos+s->vibrate)&0xff; - - /* process pitch envelope */ - playperiod=aout->main.period; - - if ((aout->main.pitflg&EF_ON)&&(envpit!=32)) { - long p1; - - envpit-=32; - if ((aout->main.note<<1)+envpit<=0) envpit=-(aout->main.note<<1); - - p1=GetPeriod(mod->flags, ((UWORD)aout->main.note<<1)+envpit, - aout->master->speed)-aout->masterperiod; - if (p1>0) { - if ((UWORD)(playperiod+p1)<=playperiod) { - p1=0; - aout->main.keyoff|=KEY_OFF; - } - } else if (p1<0) { - if ((UWORD)(playperiod+p1)>=playperiod) { - p1=0; - aout->main.keyoff|=KEY_OFF; - } - } - playperiod+=p1; - } - - if (!aout->main.fadevol) { /* check for a dead note (fadevol=0) */ - Voice_Stop_internal(channel); - mod->totalchn--; - if ((tmpvol)&&(aout->master)&&(aout->master->slave==aout)) - mod->realchn--; - } else { - Voice_SetFrequency_internal(channel, - getfrequency(mod->flags,playperiod)); - - /* if keyfade, start substracting fadeoutspeed from fadevol: */ - if ((i)&&(aout->main.keyoff&KEY_FADE)) { - if (aout->main.fadevol>=i->volfade) - aout->main.fadevol-=i->volfade; - else - aout->main.fadevol=0; - } - } - - md_bpm=mod->bpm+mod->relspd; - if (md_bpm<32) - md_bpm=32; - else if ((!(mod->flags&UF_HIGHBPM)) && md_bpm>255) - md_bpm=255; - } -} - -/* Handles new notes or instruments */ -void pt_Notes(MODULE *mod) -{ - SWORD channel; - MP_CONTROL *a; - UBYTE c,inst; - int tr,funky; /* funky is set to indicate note or instrument change */ - - for (channel=0;channelnumchn;channel++) { - a=&mod->control[channel]; - - if (mod->sngpos>=mod->numpos) { - tr=mod->numtrk; - mod->numrow=0; - } else { - tr=mod->patterns[(mod->positions[mod->sngpos]*mod->numchn)+channel]; - mod->numrow=mod->pattrows[mod->positions[mod->sngpos]]; - } - - a->row=(trnumtrk)?UniFindRow(mod->tracks[tr],mod->patpos):NULL; - a->newsamp=0; - if (!mod->vbtick) a->main.notedelay=0; - - if (!a->row) continue; - UniSetRow(a->row); - funky=0; - - while((c=UniGetByte())) - switch (c) { - case UNI_NOTE: - funky|=1; - a->oldnote=a->anote,a->anote=UniGetByte(); - a->main.kick =KICK_NOTE; - a->main.start=-1; - a->sliding=0; - - /* retrig tremolo and vibrato waves ? */ - if (!(a->wavecontrol & 0x80)) a->trmpos=0; - if (!(a->wavecontrol & 0x08)) a->vibpos=0; - if (!a->panbwave) a->panbpos=0; - break; - case UNI_INSTRUMENT: - inst=UniGetByte(); - if (inst>=mod->numins) break; /* safety valve */ - funky|=2; - a->main.i=(mod->flags & UF_INST)?&mod->instruments[inst]:NULL; - a->retrig=0; - a->s3mtremor=0; - a->ultoffset=0; - a->main.sample=inst; - break; - default: - UniSkipOpcode(); - break; - } - - if (funky) { - INSTRUMENT *i; - SAMPLE *s; - - if ((i=a->main.i)) { - if (i->samplenumber[a->anote] >= mod->numsmp) continue; - s=&mod->samples[i->samplenumber[a->anote]]; - a->main.note=i->samplenote[a->anote]; - } else { - a->main.note=a->anote; - s=&mod->samples[a->main.sample]; - } - - if (a->main.s!=s) { - a->main.s=s; - a->newsamp=a->main.period; - } - - /* channel or instrument determined panning ? */ - a->main.panning=mod->panning[channel]; - if (s->flags & SF_OWNPAN) - a->main.panning=s->panning; - else if ((i)&&(i->flags & IF_OWNPAN)) - a->main.panning=i->panning; - - a->main.handle=s->handle; - a->speed=s->speed; - - if (i) { - if ((mod->panflag)&&(i->flags & IF_PITCHPAN) - &&(a->main.panning!=PAN_SURROUND)){ - a->main.panning+= - ((a->anote-i->pitpancenter)*i->pitpansep)/8; - if (a->main.panningmain.panning=PAN_LEFT; - else if (a->main.panning>PAN_RIGHT) - a->main.panning=PAN_RIGHT; - } - a->main.pitflg=i->pitflg; - a->main.volflg=i->volflg; - a->main.panflg=i->panflg; - a->main.nna=i->nnatype; - a->dca=i->dca; - a->dct=i->dct; - } else { - a->main.pitflg=a->main.volflg=a->main.panflg=0; - a->main.nna=a->dca=0; - a->dct=DCT_OFF; - } - - if (funky&2) /* instrument change */ { - /* IT random volume variations: 0:8 bit fixed, and one bit for - sign. */ - a->volume=a->tmpvolume=s->volume; - if ((s)&&(i)) { - if (i->rvolvar) { - a->volume=a->tmpvolume=s->volume+ - ((s->volume*((SLONG)i->rvolvar*(SLONG)getrandom(512) - ))/25600); - if (a->volume<0) - a->volume=a->tmpvolume=0; - else if (a->volume>64) - a->volume=a->tmpvolume=64; - } - if ((mod->panflag)&&(a->main.panning!=PAN_SURROUND)) { - a->main.panning+=((a->main.panning*((SLONG)i->rpanvar* - (SLONG)getrandom(512)))/25600); - if (a->main.panningmain.panning=PAN_LEFT; - else if (a->main.panning>PAN_RIGHT) - a->main.panning=PAN_RIGHT; - } - } - } - - a->wantedperiod=a->tmpperiod= - GetPeriod(mod->flags, (UWORD)a->main.note<<1,a->speed); - a->main.keyoff=KEY_KICK; - } - } -} - -/* Handles effects */ -void pt_EffectsPass1(MODULE *mod) -{ - SWORD channel; - MP_CONTROL *a; - MP_VOICE *aout; - int explicitslides; - - for (channel=0;channelnumchn;channel++) { - a=&mod->control[channel]; - - if ((aout=a->slave)) { - a->main.fadevol=aout->main.fadevol; - a->main.period=aout->main.period; - if (a->main.kick==KICK_KEYOFF) - a->main.keyoff=aout->main.keyoff; - } - - if (!a->row) continue; - UniSetRow(a->row); - - a->ownper=a->ownvol=0; - explicitslides = pt_playeffects(mod, channel, a); - - /* continue volume slide if necessary for XM and IT */ - if (mod->flags&UF_BGSLIDES) { - if (!explicitslides && a->sliding) - DoS3MVolSlide(mod->vbtick, mod->flags, a, 0); - else if (a->tmpvolume) - a->sliding = explicitslides; - } - - if (!a->ownper) - a->main.period=a->tmpperiod; - if (!a->ownvol) - a->volume=a->tmpvolume; - - if (a->main.s) { - if (a->main.i) - a->main.outvolume= - (a->volume*a->main.s->globvol*a->main.i->globvol)>>10; - else - a->main.outvolume=(a->volume*a->main.s->globvol)>>4; - if (a->main.outvolume>256) - a->main.outvolume=256; - else if (a->main.outvolume<0) - a->main.outvolume=0; - } - } -} - -/* NNA management */ -void pt_NNA(MODULE *mod) -{ - SWORD channel; - MP_CONTROL *a; - - for (channel=0;channelnumchn;channel++) { - a=&mod->control[channel]; - - if (a->main.kick==KICK_NOTE) { - BOOL kill=0; - - if (a->slave) { - MP_VOICE *aout; - - aout=a->slave; - if (aout->main.nna & NNA_MASK) { - /* Make sure the old MP_VOICE channel knows it has no - master now ! */ - a->slave=NULL; - /* assume the channel is taken by NNA */ - aout->mflag=0; - - switch (aout->main.nna) { - case NNA_CONTINUE: /* continue note, do nothing */ - break; - case NNA_OFF: /* note off */ - aout->main.keyoff|=KEY_OFF; - if ((!(aout->main.volflg & EF_ON))|| - (aout->main.volflg & EF_LOOP)) - aout->main.keyoff=KEY_KILL; - break; - case NNA_FADE: - aout->main.keyoff |= KEY_FADE; - break; - } - } - } - - if (a->dct!=DCT_OFF) { - int t; - - for (t=0;tvoice[t].masterchn==channel)&& - (a->main.sample==mod->voice[t].main.sample)) { - kill=0; - switch (a->dct) { - case DCT_NOTE: - if (a->main.note==mod->voice[t].main.note) - kill=1; - break; - case DCT_SAMPLE: - if (a->main.handle==mod->voice[t].main.handle) - kill=1; - break; - case DCT_INST: - kill=1; - break; - } - if (kill) - switch (a->dca) { - case DCA_CUT: - mod->voice[t].main.fadevol=0; - break; - case DCA_OFF: - mod->voice[t].main.keyoff|=KEY_OFF; - if ((!(mod->voice[t].main.volflg&EF_ON))|| - (mod->voice[t].main.volflg&EF_LOOP)) - mod->voice[t].main.keyoff=KEY_KILL; - break; - case DCA_FADE: - mod->voice[t].main.keyoff|=KEY_FADE; - break; - } - } - } - } /* if (a->main.kick==KICK_NOTE) */ - } -} - -/* Setup module and NNA voices */ -void pt_SetupVoices(MODULE *mod) -{ - SWORD channel; - MP_CONTROL *a; - MP_VOICE *aout; - - for (channel=0;channelnumchn;channel++) { - a=&mod->control[channel]; - - if (a->main.notedelay) continue; - if (a->main.kick==KICK_NOTE) { - /* if no channel was cut above, find an empty or quiet channel - here */ - if (mod->flags&UF_NNA) { - if (!a->slave) { - int newchn; - - if ((newchn=MP_FindEmptyChannel(mod))!=-1) - a->slave=&mod->voice[a->slavechn=newchn]; - } - } else - a->slave=&mod->voice[a->slavechn=channel]; - - /* assign parts of MP_VOICE only done for a KICK_NOTE */ - if ((aout=a->slave)) { - if (aout->mflag && aout->master) aout->master->slave=NULL; - aout->master=a; - a->slave=aout; - aout->masterchn=channel; - aout->mflag=1; - } - } else - aout=a->slave; - - if (aout) - aout->main=a->main; - a->main.kick=KICK_ABSENT; - } -} - -/* second effect pass */ -void pt_EffectsPass2(MODULE *mod) -{ - SWORD channel; - MP_CONTROL *a; - UBYTE c; - - for (channel=0;channelnumchn;channel++) { - a=&mod->control[channel]; - - if (!a->row) continue; - UniSetRow(a->row); - - while((c=UniGetByte())) - if (c==UNI_ITEFFECTS0) { - c=UniGetByte(); - if ((c>>4)==SS_S7EFFECTS) - DoNNAEffects(mod, a, c&0xf); - } else - UniSkipOpcode(); - } -} - -void Player_HandleTick(void) -{ - SWORD channel; - int max_volume; - -#if 0 - /* don't handle the very first ticks, this allows the other hardware to - settle down so we don't loose any starting notes */ - if (isfirst) { - isfirst--; - return; - } -#endif - - if ((!pf)||(pf->forbid)||(pf->sngpos>=pf->numpos)) return; - - /* update time counter (sngtime is in milliseconds (in fact 2^-10)) */ - pf->sngremainder+=(1<<9)*5; /* thus 2.5*(1<<10), since fps=0.4xtempo */ - pf->sngtime+=pf->sngremainder/pf->bpm; - pf->sngremainder%=pf->bpm; - - if (++pf->vbtick>=pf->sngspd) { - if (pf->pat_repcrazy) - pf->pat_repcrazy=0; /* play 2 times row 0 */ - else - pf->patpos++; - pf->vbtick=0; - - /* process pattern-delay. pf->patdly2 is the counter and pf->patdly is - the command memory. */ - if (pf->patdly) - pf->patdly2=pf->patdly,pf->patdly=0; - if (pf->patdly2) { - /* patterndelay active */ - if (--pf->patdly2) - /* so turn back pf->patpos by 1 */ - if (pf->patpos) pf->patpos--; - } - - /* do we have to get a new patternpointer ? (when pf->patpos reaches the - pattern size, or when a patternbreak is active) */ - if (((pf->patpos>=pf->numrow)&&(pf->numrow>0))&&(!pf->posjmp)) - pf->posjmp=3; - - if (pf->posjmp) { - pf->patpos=pf->numrow?(pf->patbrk%pf->numrow):0; - pf->pat_repcrazy=0; - pf->sngpos+=(pf->posjmp-2); - for (channel=0;channelnumchn;channel++) - pf->control[channel].pat_reppos=-1; - - pf->patbrk=pf->posjmp=0; - /* handle the "---" (end of song) pattern since it can occur - *inside* the module in some formats */ - if ((pf->sngpos>=pf->numpos)|| - (pf->positions[pf->sngpos]==LAST_PATTERN)) { - if (!pf->wrap) return; - if (!(pf->sngpos=pf->reppos)) { - pf->volume=pf->initvolume>128?128:pf->initvolume; - if(pf->initspeed!=0) - pf->sngspd=pf->initspeed<32?pf->initspeed:32; - else - pf->sngspd=6; - pf->bpm=pf->inittempo<32?32:pf->inittempo; - } - } - if (pf->sngpos<0) pf->sngpos=pf->numpos-1; - } - - if (!pf->patdly2) - pt_Notes(pf); - } - - /* Fade global volume if enabled and we're playing the last pattern */ - if (((pf->sngpos==pf->numpos-1)|| - (pf->positions[pf->sngpos+1]==LAST_PATTERN))&& - (pf->fadeout)) - max_volume=pf->numrow?((pf->numrow-pf->patpos)*128)/pf->numrow:0; - else - max_volume=128; - - pt_EffectsPass1(pf); - if (pf->flags&UF_NNA) - pt_NNA(pf); - pt_SetupVoices(pf); - pt_EffectsPass2(pf); - - /* now set up the actual hardware channel playback information */ - pt_UpdateVoices(pf, max_volume); -} - -static void Player_Init_internal(MODULE* mod) -{ - int t; - - for (t=0;tnumchn;t++) { - mod->control[t].main.chanvol=mod->chanvol[t]; - mod->control[t].main.panning=mod->panning[t]; - } - - mod->sngtime=0; - mod->sngremainder=0; - - mod->pat_repcrazy=0; - mod->sngpos=0; - if(mod->initspeed!=0) - mod->sngspd=mod->initspeed<32?mod->initspeed:32; - else - mod->sngspd=6; - mod->volume=mod->initvolume>128?128:mod->initvolume; - - mod->vbtick=mod->sngspd; - mod->patdly=0; - mod->patdly2=0; - mod->bpm=mod->inittempo<32?32:mod->inittempo; - mod->realchn=0; - - mod->patpos=0; - mod->posjmp=2; /* make sure the player fetches the first note */ - mod->numrow=-1; - mod->patbrk=0; -} - -BOOL Player_Init(MODULE* mod) -{ - mod->extspd=1; - mod->panflag=1; - mod->wrap=0; - mod->loop=1; - mod->fadeout=0; - - mod->relspd=0; - - /* make sure the player doesn't start with garbage */ - if (!(mod->control=(MP_CONTROL*)_mm_calloc(mod->numchn,sizeof(MP_CONTROL)))) - return 1; - if (!(mod->voice=(MP_VOICE*)_mm_calloc(md_sngchn,sizeof(MP_VOICE)))) - return 1; - - Player_Init_internal(mod); - return 0; -} - -void Player_Exit_internal(MODULE* mod) -{ - if (!mod) - return; - - /* Stop playback if necessary */ - if (mod==pf) { - Player_Stop_internal(); - pf=NULL; - } - - if (mod->control) - free(mod->control); - if (mod->voice) - free(mod->voice); - mod->control=NULL; - mod->voice=NULL; -} - -void Player_Exit(MODULE* mod) -{ - MUTEX_LOCK(vars); - Player_Exit_internal(mod); - MUTEX_UNLOCK(vars); -} - -MIKMODAPI void Player_SetVolume(SWORD volume) -{ - MUTEX_LOCK(vars); - if (pf) - pf->volume=pf->initvolume=(volume<0)?0:(volume>128)?128:volume; - MUTEX_UNLOCK(vars); -} - -MIKMODAPI MODULE* Player_GetModule(void) -{ - MODULE* result; - - MUTEX_LOCK(vars); - result=pf; - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI void Player_Start(MODULE *mod) -{ - int t; - - if (!mod) - return; - - if (!MikMod_Active()) - MikMod_EnableOutput(); - - mod->forbid=0; - - MUTEX_LOCK(vars); - if (pf!=mod) { - /* new song is being started, so completely stop out the old one. */ - if (pf) pf->forbid=1; - for (t=0;tforbid=1; - pf=NULL; -} - -MIKMODAPI void Player_Stop(void) -{ - MUTEX_LOCK(vars); - Player_Stop_internal(); - MUTEX_UNLOCK(vars); -} - -MIKMODAPI BOOL Player_Active(void) -{ - BOOL result=0; - - MUTEX_LOCK(vars); - if (pf) - result=(!(pf->sngpos>=pf->numpos)); - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI void Player_NextPosition(void) -{ - MUTEX_LOCK(vars); - if (pf) { - int t; - - pf->forbid=1; - pf->posjmp=3; - pf->patbrk=0; - pf->vbtick=pf->sngspd; - - for (t=0;tvoice[t].main.i=NULL; - pf->voice[t].main.s=NULL; - } - for (t=0;tnumchn;t++) { - pf->control[t].main.i=NULL; - pf->control[t].main.s=NULL; - } - pf->forbid=0; - } - MUTEX_UNLOCK(vars); -} - -MIKMODAPI void Player_PrevPosition(void) -{ - MUTEX_LOCK(vars); - if (pf) { - int t; - - pf->forbid=1; - pf->posjmp=1; - pf->patbrk=0; - pf->vbtick=pf->sngspd; - - for (t=0;tvoice[t].main.i=NULL; - pf->voice[t].main.s=NULL; - } - for (t=0;tnumchn;t++) { - pf->control[t].main.i=NULL; - pf->control[t].main.s=NULL; - } - pf->forbid=0; - } - MUTEX_UNLOCK(vars); -} - -MIKMODAPI void Player_SetPosition(UWORD pos) -{ - MUTEX_LOCK(vars); - if (pf) { - int t; - - pf->forbid=1; - if (pos>=pf->numpos) pos=pf->numpos; - pf->posjmp=2; - pf->patbrk=0; - pf->sngpos=pos; - pf->vbtick=pf->sngspd; - - for (t=0;tvoice[t].main.i=NULL; - pf->voice[t].main.s=NULL; - } - for (t=0;tnumchn;t++) { - pf->control[t].main.i=NULL; - pf->control[t].main.s=NULL; - } - pf->forbid=0; - - if (!pos) - Player_Init_internal(pf); - } - MUTEX_UNLOCK(vars); -} - -static void Player_Unmute_internal(SLONG arg1,va_list ap) -{ - SLONG t,arg2,arg3=0; - - if (pf) { - switch (arg1) { - case MUTE_INCLUSIVE: - if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))|| - (arg2>arg3)||(arg3>=pf->numchn)) - return; - for (;arg2numchn && arg2<=arg3;arg2++) - pf->control[arg2].muted=0; - break; - case MUTE_EXCLUSIVE: - if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))|| - (arg2>arg3)||(arg3>=pf->numchn)) - return; - for (t=0;tnumchn;t++) { - if ((t>=arg2) && (t<=arg3)) - continue; - pf->control[t].muted=0; - } - break; - default: - if (arg1numchn) pf->control[arg1].muted=0; - break; - } - } -} - -MIKMODAPI void Player_Unmute(SLONG arg1, ...) -{ - va_list args; - - va_start(args,arg1); - MUTEX_LOCK(vars); - Player_Unmute_internal(arg1,args); - MUTEX_UNLOCK(vars); - va_end(args); -} - -static void Player_Mute_internal(SLONG arg1,va_list ap) -{ - SLONG t,arg2,arg3=0; - - if (pf) { - switch (arg1) { - case MUTE_INCLUSIVE: - if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))|| - (arg2>arg3)||(arg3>=pf->numchn)) - return; - for (;arg2numchn && arg2<=arg3;arg2++) - pf->control[arg2].muted=1; - break; - case MUTE_EXCLUSIVE: - if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))|| - (arg2>arg3)||(arg3>=pf->numchn)) - return; - for (t=0;tnumchn;t++) { - if ((t>=arg2) && (t<=arg3)) - continue; - pf->control[t].muted=1; - } - break; - default: - if (arg1numchn) - pf->control[arg1].muted=1; - break; - } - } -} - -MIKMODAPI void Player_Mute(SLONG arg1,...) -{ - va_list args; - - va_start(args,arg1); - MUTEX_LOCK(vars); - Player_Mute_internal(arg1,args); - MUTEX_UNLOCK(vars); - va_end(args); -} - -static void Player_ToggleMute_internal(SLONG arg1,va_list ap) -{ - SLONG arg2,arg3=0; - ULONG t; - - if (pf) { - switch (arg1) { - case MUTE_INCLUSIVE: - if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))|| - (arg2>arg3)||(arg3>=pf->numchn)) - return; - for (;arg2numchn && arg2<=arg3;arg2++) - pf->control[arg2].muted=1-pf->control[arg2].muted; - break; - case MUTE_EXCLUSIVE: - if (((!(arg2=va_arg(ap,SLONG)))&&(!(arg3=va_arg(ap,SLONG))))|| - (arg2>arg3)||(arg3>=pf->numchn)) - return; - for (t=0;tnumchn;t++) { - if ((t>=arg2) && (t<=arg3)) - continue; - pf->control[t].muted=1-pf->control[t].muted; - } - break; - default: - if (arg1numchn) - pf->control[arg1].muted=1-pf->control[arg1].muted; - break; - } - } -} - -MIKMODAPI void Player_ToggleMute(SLONG arg1,...) -{ - va_list args; - - va_start(args,arg1); - MUTEX_LOCK(vars); - Player_ToggleMute_internal(arg1,args); - MUTEX_UNLOCK(vars); - va_end(args); -} - -MIKMODAPI BOOL Player_Muted(UBYTE chan) -{ - BOOL result=1; - - MUTEX_LOCK(vars); - if (pf) - result=(channumchn)?pf->control[chan].muted:1; - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI int Player_GetChannelVoice(UBYTE chan) -{ - int result=0; - - MUTEX_LOCK(vars); - if (pf) - result=(channumchn)?pf->control[chan].slavechn:-1; - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI UWORD Player_GetChannelPeriod(UBYTE chan) -{ - UWORD result=0; - - MUTEX_LOCK(vars); - if (pf) - result=(channumchn)?pf->control[chan].main.period:0; - MUTEX_UNLOCK(vars); - - return result; -} - -BOOL Player_Paused_internal(void) -{ - return pf?pf->forbid:1; -} - -MIKMODAPI BOOL Player_Paused(void) -{ - BOOL result; - - MUTEX_LOCK(vars); - result=Player_Paused_internal(); - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI void Player_TogglePause(void) -{ - MUTEX_LOCK(vars); - if (pf) - pf->forbid=1-pf->forbid; - MUTEX_UNLOCK(vars); -} - -MIKMODAPI void Player_SetSpeed(UWORD speed) -{ - MUTEX_LOCK(vars); - if (pf) - pf->sngspd=speed?(speed<32?speed:32):1; - MUTEX_UNLOCK(vars); -} - -MIKMODAPI void Player_SetTempo(UWORD tempo) -{ - if (tempo<32) tempo=32; - MUTEX_LOCK(vars); - if (pf) { - if ((!(pf->flags&UF_HIGHBPM))&&(tempo>255)) tempo=255; - pf->bpm=tempo; - } - MUTEX_UNLOCK(vars); -} - - -/* ex:set ts=4: */ diff --git a/mikmod/munitrk.c b/mikmod/munitrk.c deleted file mode 100644 index 9bce10f8..00000000 --- a/mikmod/munitrk.c +++ /dev/null @@ -1,305 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - All routines dealing with the manipulation of UNITRK streams - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "mikmod_internals.h" - - -/* Unibuffer chunk size */ -#define BUFPAGE 128 - -UWORD unioperands[UNI_LAST]={ - 0, /* not used */ - 1, /* UNI_NOTE */ - 1, /* UNI_INSTRUMENT */ - 1, /* UNI_PTEFFECT0 */ - 1, /* UNI_PTEFFECT1 */ - 1, /* UNI_PTEFFECT2 */ - 1, /* UNI_PTEFFECT3 */ - 1, /* UNI_PTEFFECT4 */ - 1, /* UNI_PTEFFECT5 */ - 1, /* UNI_PTEFFECT6 */ - 1, /* UNI_PTEFFECT7 */ - 1, /* UNI_PTEFFECT8 */ - 1, /* UNI_PTEFFECT9 */ - 1, /* UNI_PTEFFECTA */ - 1, /* UNI_PTEFFECTB */ - 1, /* UNI_PTEFFECTC */ - 1, /* UNI_PTEFFECTD */ - 1, /* UNI_PTEFFECTE */ - 1, /* UNI_PTEFFECTF */ - 1, /* UNI_S3MEFFECTA */ - 1, /* UNI_S3MEFFECTD */ - 1, /* UNI_S3MEFFECTE */ - 1, /* UNI_S3MEFFECTF */ - 1, /* UNI_S3MEFFECTI */ - 1, /* UNI_S3MEFFECTQ */ - 1, /* UNI_S3MEFFECTR */ - 1, /* UNI_S3MEFFECTT */ - 1, /* UNI_S3MEFFECTU */ - 0, /* UNI_KEYOFF */ - 1, /* UNI_KEYFADE */ - 2, /* UNI_VOLEFFECTS */ - 1, /* UNI_XMEFFECT4 */ - 1, /* UNI_XMEFFECT6 */ - 1, /* UNI_XMEFFECTA */ - 1, /* UNI_XMEFFECTE1 */ - 1, /* UNI_XMEFFECTE2 */ - 1, /* UNI_XMEFFECTEA */ - 1, /* UNI_XMEFFECTEB */ - 1, /* UNI_XMEFFECTG */ - 1, /* UNI_XMEFFECTH */ - 1, /* UNI_XMEFFECTL */ - 1, /* UNI_XMEFFECTP */ - 1, /* UNI_XMEFFECTX1 */ - 1, /* UNI_XMEFFECTX2 */ - 1, /* UNI_ITEFFECTG */ - 1, /* UNI_ITEFFECTH */ - 1, /* UNI_ITEFFECTI */ - 1, /* UNI_ITEFFECTM */ - 1, /* UNI_ITEFFECTN */ - 1, /* UNI_ITEFFECTP */ - 1, /* UNI_ITEFFECTT */ - 1, /* UNI_ITEFFECTU */ - 1, /* UNI_ITEFFECTW */ - 1, /* UNI_ITEFFECTY */ - 2, /* UNI_ITEFFECTZ */ - 1, /* UNI_ITEFFECTS0 */ - 2, /* UNI_ULTEFFECT9 */ - 2, /* UNI_MEDSPEED */ - 0, /* UNI_MEDEFFECTF1 */ - 0, /* UNI_MEDEFFECTF2 */ - 0, /* UNI_MEDEFFECTF3 */ - 2, /* UNI_OKTARP */ - 1 /* UNI_XMEFFECTZ */ -}; - -/* Sparse description of the internal module format - ------------------------------------------------ - - A UNITRK stream is an array of bytes representing a single track of a pattern. -It's made up of 'repeat/length' bytes, opcodes and operands (sort of a assembly -language): - -rrrlllll -[REP/LEN][OPCODE][OPERAND][OPCODE][OPERAND] [REP/LEN][OPCODE][OPERAND].. -^ ^ ^ -|-------ROWS 0 - 0+REP of a track---------| |-------ROWS xx - xx+REP of a track... - - The rep/len byte contains the number of bytes in the current row, _including_ -the length byte itself (So the LENGTH byte of row 0 in the previous example -would have a value of 5). This makes it easy to search through a stream for a -particular row. A track is concluded by a 0-value length byte. - - The upper 3 bits of the rep/len byte contain the number of times -1 this row -is repeated for this track. (so a value of 7 means this row is repeated 8 times) - - Opcodes can range from 1 to 255 but currently only opcodes 1 to 62 are being -used. Each opcode can have a different number of operands. You can find the -number of operands to a particular opcode by using the opcode as an index into -the 'unioperands' table. - -*/ - -/*========== Reading routines */ - -static UBYTE *rowstart; /* startadress of a row */ -static UBYTE *rowend; /* endaddress of a row (exclusive) */ -static UBYTE *rowpc; /* current unimod(tm) programcounter */ - -static UBYTE lastbyte; /* for UniSkipOpcode() */ - -void UniSetRow(UBYTE* t) -{ - rowstart = t; - rowpc = rowstart; - rowend = t?rowstart+(*(rowpc++)&0x1f):t; -} - -UBYTE UniGetByte(void) -{ - return lastbyte = (rowpc end of track.. */ - l = (c>>5)+1; /* extract repeat value */ - if(l>row) break; /* reached wanted row? -> return pointer */ - row -= l; /* haven't reached row yet.. update row */ - t += c&0x1f; /* point t to the next row */ - } - return t; -} - -/*========== Writing routines */ - -static UBYTE *unibuf; /* pointer to the temporary unitrk buffer */ -static UWORD unimax; /* buffer size */ - -static UWORD unipc; /* buffer cursor */ -static UWORD unitt; /* current row index */ -static UWORD lastp; /* previous row index */ - -/* Resets index-pointers to create a new track. */ -void UniReset(void) -{ - unitt = 0; /* reset index to rep/len byte */ - unipc = 1; /* first opcode will be written to index 1 */ - lastp = 0; /* no previous row yet */ - unibuf[0] = 0; /* clear rep/len byte */ -} - -/* Expands the buffer */ -static BOOL UniExpand(int wanted) -{ - if ((unipc+wanted)>=unimax) { - UBYTE *newbuf; - - /* Expand the buffer by BUFPAGE bytes */ - newbuf=(UBYTE*)realloc(unibuf,(unimax+BUFPAGE)*sizeof(UBYTE)); - - /* Check if realloc succeeded */ - if(newbuf) { - unibuf = newbuf; - unimax+=BUFPAGE; - return 1; - } else - return 0; - } - return 1; -} - -/* Appends one byte of data to the current row of a track. */ -void UniWriteByte(UBYTE data) -{ - if (UniExpand(1)) - /* write byte to current position and update */ - unibuf[unipc++]=data; -} - -void UniWriteWord(UWORD data) -{ - if (UniExpand(2)) { - unibuf[unipc++]=data>>8; - unibuf[unipc++]=data&0xff; - } -} - -static BOOL MyCmp(UBYTE* a,UBYTE* b,UWORD l) -{ - UWORD t; - - for(t=0;t>5)+1; /* repeat of previous row */ - l = (unibuf[lastp]&0x1f); /* length of previous row */ - - len = unipc-unitt; /* length of current row */ - - /* Now, check if the previous and the current row are identical.. when they - are, just increase the repeat field of the previous row */ - if(n<8 && len==l && MyCmp(&unibuf[lastp+1],&unibuf[unitt+1],len-1)) { - unibuf[lastp]+=0x20; - unipc = unitt+1; - } else { - if (UniExpand(unitt-unipc)) { - /* current and previous row aren't equal... update the pointers */ - unibuf[unitt] = len; - lastp = unitt; - unitt = unipc++; - } - } -} - -/* Terminates the current unitrk stream and returns a pointer to a copy of the - stream. */ -UBYTE* UniDup(void) -{ - UBYTE *d; - - if (!UniExpand(unitt-unipc)) return NULL; - unibuf[unitt] = 0; - - if(!(d=(UBYTE *)_mm_malloc(unipc))) return NULL; - memcpy(d,unibuf,unipc); - - return d; -} - -BOOL UniInit(void) -{ - unimax = BUFPAGE; - - if(!(unibuf=(UBYTE*)_mm_malloc(unimax*sizeof(UBYTE)))) return 0; - return 1; -} - -void UniCleanup(void) -{ - if(unibuf) free(unibuf); - unibuf = NULL; -} - -/* ex:set ts=4: */ diff --git a/mikmod/mwav.c b/mikmod/mwav.c deleted file mode 100644 index f8427400..00000000 --- a/mikmod/mwav.c +++ /dev/null @@ -1,198 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - WAV sample loader - -==============================================================================*/ - -/* - FIXME: Stereo .WAV files are not yet supported as samples. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include - -#include "mikmod_internals.h" - -#ifdef SUNOS -extern int fprintf(FILE *, const char *, ...); -#endif - -typedef struct WAV { - CHAR rID[4]; - ULONG rLen; - CHAR wID[4]; - CHAR fID[4]; - ULONG fLen; - UWORD wFormatTag; - UWORD nChannels; - ULONG nSamplesPerSec; - ULONG nAvgBytesPerSec; - UWORD nBlockAlign; - UWORD nFormatSpecific; -} WAV; - -SAMPLE* Sample_LoadGeneric_internal(MREADER* reader) -{ - SAMPLE *si=NULL; - WAV wh; - BOOL have_fmt=0; - - /* read wav header */ - _mm_read_string(wh.rID,4,reader); - wh.rLen = _mm_read_I_ULONG(reader); - _mm_read_string(wh.wID,4,reader); - - /* check for correct header */ - if(_mm_eof(reader)|| memcmp(wh.rID,"RIFF",4) || memcmp(wh.wID,"WAVE",4)) { - _mm_errno = MMERR_UNKNOWN_WAVE_TYPE; - return NULL; - } - - /* scan all RIFF blocks until we find the sample data */ - for(;;) { - CHAR dID[4]; - ULONG len,start; - - _mm_read_string(dID,4,reader); - len = _mm_read_I_ULONG(reader); - /* truncated file ? */ - if (_mm_eof(reader)) { - _mm_errno=MMERR_UNKNOWN_WAVE_TYPE; - return NULL; - } - start = _mm_ftell(reader); - - /* sample format block - should be present only once and before a data block */ - if(!memcmp(dID,"fmt ",4)) { - wh.wFormatTag = _mm_read_I_UWORD(reader); - wh.nChannels = _mm_read_I_UWORD(reader); - wh.nSamplesPerSec = _mm_read_I_ULONG(reader); - wh.nAvgBytesPerSec = _mm_read_I_ULONG(reader); - wh.nBlockAlign = _mm_read_I_UWORD(reader); - wh.nFormatSpecific = _mm_read_I_UWORD(reader); - -#ifdef MIKMOD_DEBUG - fprintf(stderr,"\rwavloader : wFormatTag=%04x blockalign=%04x nFormatSpc=%04x\n", - wh.wFormatTag,wh.nBlockAlign,wh.nFormatSpecific); -#endif - - if((have_fmt)||(wh.nChannels>1)) { - _mm_errno=MMERR_UNKNOWN_WAVE_TYPE; - return NULL; - } - have_fmt=1; - } else - /* sample data block - should be present only once and after a format block */ - if(!memcmp(dID,"data",4)) { - if(!have_fmt) { - _mm_errno=MMERR_UNKNOWN_WAVE_TYPE; - return NULL; - } - if(!(si=(SAMPLE*)_mm_malloc(sizeof(SAMPLE)))) return NULL; - si->speed = wh.nSamplesPerSec/wh.nChannels; - si->volume = 64; - si->length = len; - if(wh.nBlockAlign == 2) { - si->flags = SF_16BITS | SF_SIGNED; - si->length >>= 1; - } - si->inflags = si->flags; - SL_RegisterSample(si,MD_SNDFX,reader); - SL_LoadSamples(); - - /* skip any other remaining blocks - so in case of repeated sample - fragments, we'll return the first anyway instead of an error */ - break; - } - /* onto next block */ - _mm_fseek(reader,start+len,SEEK_SET); - if (_mm_eof(reader)) - break; - } - - return si; -} - -MIKMODAPI SAMPLE* Sample_LoadGeneric(MREADER* reader) -{ - SAMPLE* result; - - MUTEX_LOCK(vars); - result=Sample_LoadGeneric_internal(reader); - MUTEX_UNLOCK(vars); - - return result; -} - -MIKMODAPI SAMPLE* Sample_LoadFP(FILE *fp) -{ - SAMPLE* result=NULL; - MREADER* reader; - - if((reader=_mm_new_file_reader(fp))) { - result=Sample_LoadGeneric(reader); - _mm_delete_file_reader(reader); - } - return result; -} - -MIKMODAPI SAMPLE* Sample_Load(CHAR* filename) -{ - FILE *fp; - SAMPLE *si=NULL; - - if(!(md_mode & DMODE_SOFT_SNDFX)) return NULL; - if((fp=_mm_fopen(filename,"rb"))) { - si = Sample_LoadFP(fp); - _mm_fclose(fp); - } - return si; -} - -MIKMODAPI void Sample_Free(SAMPLE* si) -{ - if(si) { - MD_SampleUnload(si->handle); - free(si); - } -} - -void Sample_Free_internal(SAMPLE *si) -{ - MUTEX_LOCK(vars); - Sample_Free(si); - MUTEX_UNLOCK(vars); -} - -/* ex:set ts=4: */ diff --git a/mikmod/npertab.c b/mikmod/npertab.c deleted file mode 100644 index c6659e81..00000000 --- a/mikmod/npertab.c +++ /dev/null @@ -1,48 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - MOD format period table. Used by both the MOD and M15 (15-inst mod) Loaders. - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mikmod_internals.h" - -UWORD npertab[7 * OCTAVE] = { - /* Octaves 6 -> 0 */ - /* C C# D D# E F F# G G# A A# B */ - 0x6b0,0x650,0x5f4,0x5a0,0x54c,0x500,0x4b8,0x474,0x434,0x3f8,0x3c0,0x38a, - 0x358,0x328,0x2fa,0x2d0,0x2a6,0x280,0x25c,0x23a,0x21a,0x1fc,0x1e0,0x1c5, - 0x1ac,0x194,0x17d,0x168,0x153,0x140,0x12e,0x11d,0x10d,0x0fe,0x0f0,0x0e2, - 0x0d6,0x0ca,0x0be,0x0b4,0x0aa,0x0a0,0x097,0x08f,0x087,0x07f,0x078,0x071, - 0x06b,0x065,0x05f,0x05a,0x055,0x050,0x04b,0x047,0x043,0x03f,0x03c,0x038, - 0x035,0x032,0x02f,0x02d,0x02a,0x028,0x025,0x023,0x021,0x01f,0x01e,0x01c, - 0x01b,0x019,0x018,0x016,0x015,0x014,0x013,0x012,0x011,0x010,0x00f,0x00e -}; - -/* ex:set ts=4: */ - diff --git a/mikmod/sloader.c b/mikmod/sloader.c deleted file mode 100644 index d1a89432..00000000 --- a/mikmod/sloader.c +++ /dev/null @@ -1,520 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001 Miodrag Vallat and others - see file AUTHORS - for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Routines for loading samples. The sample loader utilizes the routines - provided by the "registered" sample loader. - -==============================================================================*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#include "mikmod_internals.h" - -static int sl_rlength; -static SWORD sl_old; -static SWORD *sl_buffer=NULL; -static SAMPLOAD *musiclist=NULL,*sndfxlist=NULL; - -/* size of the loader buffer in words */ -#define SLBUFSIZE 2048 - -/* IT-Compressed status structure */ -typedef struct ITPACK { - UWORD bits; /* current number of bits */ - UWORD bufbits; /* bits in buffer */ - SWORD last; /* last output */ - UBYTE buf; /* bit buffer */ -} ITPACK; - -BOOL SL_Init(SAMPLOAD* s) -{ - if(!sl_buffer) - if(!(sl_buffer=_mm_malloc(SLBUFSIZE*sizeof(SWORD)))) return 0; - - sl_rlength = s->length; - if(s->infmt & SF_16BITS) sl_rlength>>=1; - sl_old = 0; - - return 1; -} - -void SL_Exit(SAMPLOAD *s) -{ - if(sl_rlength>0) _mm_fseek(s->reader,sl_rlength,SEEK_CUR); - if(sl_buffer) { - free(sl_buffer); - sl_buffer=NULL; - } -} - -/* unpack a 8bit IT packed sample */ -static BOOL read_itcompr8(ITPACK* status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt) -{ - SWORD *dest=sl_buffer,*end=sl_buffer+count; - UWORD x,y,needbits,havebits,new_count=0; - UWORD bits = status->bits; - UWORD bufbits = status->bufbits; - SBYTE last = status->last; - UBYTE buf = status->buf; - - while (dest>=y; - bufbits-=y; - needbits-=y; - havebits+=y; - } - if (new_count) { - new_count = 0; - if (++x >= bits) - x++; - bits = x; - continue; - } - if (bits<7) { - if (x==(1<<(bits-1))) { - new_count = 1; - continue; - } - } - else if (bits<9) { - y = (0xff >> (9-bits)) - 4; - if ((x>y)&&(x<=y+8)) { - if ((x-=y)>=bits) - x++; - bits = x; - continue; - } - } - else if (bits<10) { - if (x>=0x100) { - bits=x-0x100+1; - continue; - } - } else { - /* error in compressed data... */ - _mm_errno=MMERR_ITPACK_INVALID_DATA; - return 0; - } - - if (bits<8) /* extend sign */ - x = ((SBYTE)(x <<(8-bits))) >> (8-bits); - *(dest++)= (last+=x) << 8; /* convert to 16 bit */ - } - status->bits = bits; - status->bufbits = bufbits; - status->last = last; - status->buf = buf; - return dest-sl_buffer; -} - -/* unpack a 16bit IT packed sample */ -static BOOL read_itcompr16(ITPACK *status,MREADER *reader,SWORD *sl_buffer,UWORD count,UWORD* incnt) -{ - SWORD *dest=sl_buffer,*end=sl_buffer+count; - SLONG x,y,needbits,havebits,new_count=0; - UWORD bits = status->bits; - UWORD bufbits = status->bufbits; - SWORD last = status->last; - UBYTE buf = status->buf; - - while (dest>=y; - bufbits-=y; - needbits-=y; - havebits+=y; - } - if (new_count) { - new_count = 0; - if (++x >= bits) - x++; - bits = x; - continue; - } - if (bits<7) { - if (x==(1<<(bits-1))) { - new_count=1; - continue; - } - } - else if (bits<17) { - y=(0xffff>>(17-bits))-8; - if ((x>y)&&(x<=y+16)) { - if ((x-=y)>=bits) - x++; - bits = x; - continue; - } - } - else if (bits<18) { - if (x>=0x10000) { - bits=x-0x10000+1; - continue; - } - } else { - /* error in compressed data... */ - _mm_errno=MMERR_ITPACK_INVALID_DATA; - return 0; - } - - if (bits<16) /* extend sign */ - x = ((SWORD)(x<<(16-bits)))>>(16-bits); - *(dest++)=(last+=x); - } - status->bits = bits; - status->bufbits = bufbits; - status->last = last; - status->buf = buf; - return dest-sl_buffer; -} - -static BOOL SL_LoadInternal(void* buffer,UWORD infmt,UWORD outfmt,int scalefactor,ULONG length,MREADER* reader,BOOL dither) -{ - SBYTE *bptr = (SBYTE*)buffer; - SWORD *wptr = (SWORD*)buffer; - int stodo,t,u; - - int result,c_block=0; /* compression bytes until next block */ - ITPACK status; - UWORD incnt; - - memset(&status, 0, sizeof(status)); - while(length) { - stodo=(lengthRead(reader,sl_buffer,sizeof(SBYTE)*stodo); - src = (SBYTE*)sl_buffer; - dest = sl_buffer; - src += stodo;dest += stodo; - - for(t=0;t>1; - length-=2; - } - stodo = idx; - } - } - - if(outfmt & SF_16BITS) { - for(t=0;t>8; - } - } - return 0; -} - -BOOL SL_Load(void* buffer,SAMPLOAD *smp,ULONG length) -{ - return SL_LoadInternal(buffer,smp->infmt,smp->outfmt,smp->scalefactor, - length,smp->reader,0); -} - -/* Registers a sample for loading when SL_LoadSamples() is called. */ -SAMPLOAD* SL_RegisterSample(SAMPLE* s,int type,MREADER* reader) -{ - SAMPLOAD *news,**samplist,*cruise; - - if(type==MD_MUSIC) { - samplist = &musiclist; - cruise = musiclist; - } else - if (type==MD_SNDFX) { - samplist = &sndfxlist; - cruise = sndfxlist; - } else - return NULL; - - /* Allocate and add structure to the END of the list */ - if(!(news=(SAMPLOAD*)_mm_malloc(sizeof(SAMPLOAD)))) return NULL; - - if(cruise) { - while(cruise->next) cruise=cruise->next; - cruise->next = news; - } else - *samplist = news; - - news->infmt = s->flags & SF_FORMATMASK; - news->outfmt = news->infmt; - news->reader = reader; - news->sample = s; - news->length = s->length; - news->loopstart = s->loopstart; - news->loopend = s->loopend; - - return news; -} - -static void FreeSampleList(SAMPLOAD* s) -{ - SAMPLOAD *old; - - while(s) { - old = s; - s = s->next; - free(old); - } -} - -/* Returns the total amount of memory required by the samplelist queue. */ -static ULONG SampleTotal(SAMPLOAD* samplist,int type) -{ - int total = 0; - - while(samplist) { - samplist->sample->flags= - (samplist->sample->flags&~SF_FORMATMASK)|samplist->outfmt; - total += MD_SampleLength(type,samplist->sample); - samplist=samplist->next; - } - - return total; -} - -static ULONG RealSpeed(SAMPLOAD *s) -{ - return(s->sample->speed/(s->scalefactor?s->scalefactor:1)); -} - -static BOOL DitherSamples(SAMPLOAD* samplist,int type) -{ - SAMPLOAD *c2smp=NULL; - ULONG maxsize, speed; - SAMPLOAD *s; - - if(!samplist) return 0; - - if((maxsize=MD_SampleSpace(type)*1024)) - while(SampleTotal(samplist,type)>maxsize) { - /* First Pass - check for any 16 bit samples */ - s = samplist; - while(s) { - if(s->outfmt & SF_16BITS) { - SL_Sample16to8(s); - break; - } - s=s->next; - } - /* Second pass (if no 16bits found above) is to take the sample with - the highest speed and dither it by half. */ - if(!s) { - s = samplist; - speed = 0; - while(s) { - if((s->sample->length) && (RealSpeed(s)>speed)) { - speed=RealSpeed(s); - c2smp=s; - } - s=s->next; - } - if (c2smp) - SL_HalveSample(c2smp,2); - } - } - - /* Samples dithered, now load them ! */ - s = samplist; - while(s) { - /* sample has to be loaded ? -> increase number of samples, allocate - memory and load sample. */ - if(s->sample->length) { - if(s->sample->seekpos) - _mm_fseek(s->reader, s->sample->seekpos, SEEK_SET); - - /* Call the sample load routine of the driver module. It has to - return a 'handle' (>=0) that identifies the sample. */ - s->sample->handle = MD_SampleLoad(s, type); - s->sample->flags = (s->sample->flags & ~SF_FORMATMASK) | s->outfmt; - if(s->sample->handle<0) { - FreeSampleList(samplist); - if(_mm_errorhandler) _mm_errorhandler(); - return 1; - } - } - s = s->next; - } - - FreeSampleList(samplist); - return 0; -} - -BOOL SL_LoadSamples(void) -{ - BOOL ok; - - _mm_critical = 0; - - if((!musiclist)&&(!sndfxlist)) return 0; - ok=DitherSamples(musiclist,MD_MUSIC)||DitherSamples(sndfxlist,MD_SNDFX); - musiclist=sndfxlist=NULL; - - return ok; -} - -void SL_Sample16to8(SAMPLOAD* s) -{ - s->outfmt &= ~SF_16BITS; - s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt; -} - -void SL_Sample8to16(SAMPLOAD* s) -{ - s->outfmt |= SF_16BITS; - s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt; -} - -void SL_SampleSigned(SAMPLOAD* s) -{ - s->outfmt |= SF_SIGNED; - s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt; -} - -void SL_SampleUnsigned(SAMPLOAD* s) -{ - s->outfmt &= ~SF_SIGNED; - s->sample->flags = (s->sample->flags&~SF_FORMATMASK) | s->outfmt; -} - -void SL_HalveSample(SAMPLOAD* s,int factor) -{ - s->scalefactor=factor>0?factor:2; - - s->sample->divfactor = s->scalefactor; - s->sample->length = s->length / s->scalefactor; - s->sample->loopstart = s->loopstart / s->scalefactor; - s->sample->loopend = s->loopend / s->scalefactor; -} - - -/* ex:set ts=4: */ diff --git a/mikmod/virtch.c b/mikmod/virtch.c deleted file mode 100644 index 0ef117cf..00000000 --- a/mikmod/virtch.c +++ /dev/null @@ -1,942 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999, 2000, 2001, 2002 Miodrag Vallat and others - see file - AUTHORS for complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - Sample mixing routines, using a 32 bits mixing buffer. - -==============================================================================*/ - -/* - - Optional features include: - (a) 4-step reverb (for 16 bit output only) - (b) Interpolation of sample data during mixing - (c) Dolby Surround Sound -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -#include "mikmod_internals.h" - -/* - Constant definitions - ==================== - - BITSHIFT - Controls the maximum volume of the sound output. All data is shifted - right by BITSHIFT after being mixed. Higher values result in quieter - sound and less chance of distortion. - - REVERBERATION - Controls the duration of the reverb. Larger values represent a shorter - reverb loop. Smaller values extend the reverb but can result in more of - an echo-ish sound. - -*/ - -#define BITSHIFT 9 -#define REVERBERATION 110000L - -#define FRACBITS 11 -#define FRACMASK ((1L< sample has to be restarted */ - UBYTE active; /* =1 -> sample is playing */ - UWORD flags; /* 16/8 bits looping/one-shot */ - SWORD handle; /* identifies the sample */ - ULONG start; /* start index */ - ULONG size; /* samplesize */ - ULONG reppos; /* loop start */ - ULONG repend; /* loop end */ - ULONG frq; /* current frequency */ - int vol; /* current volume */ - int pan; /* current panning position */ - - int rampvol; - int lvolsel,rvolsel; /* Volume factor in range 0-255 */ - int oldlvol,oldrvol; - - SLONGLONG current; /* current index in the sample */ - SLONGLONG increment; /* increment value */ -} VINFO; - -static SWORD **Samples; -static VINFO *vinf=NULL,*vnf; -static long tickleft,samplesthatfit,vc_memory=0; -static int vc_softchn; -static SLONGLONG idxsize,idxlpos,idxlend; -static SLONG *vc_tickbuf=NULL; -static UWORD vc_mode; - -/* Reverb control variables */ - -static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8; -static ULONG RVRindex; - -/* For Mono or Left Channel */ -static SLONG *RVbufL1=NULL,*RVbufL2=NULL,*RVbufL3=NULL,*RVbufL4=NULL, - *RVbufL5=NULL,*RVbufL6=NULL,*RVbufL7=NULL,*RVbufL8=NULL; - -/* For Stereo only (Right Channel) */ -static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL, - *RVbufR5=NULL,*RVbufR6=NULL,*RVbufR7=NULL,*RVbufR8=NULL; - -#ifdef NATIVE_64BIT_INT -#define NATIVE SLONGLONG -#else -#define NATIVE SLONG -#endif - -/*========== 32 bit sample mixers - only for 32 bit platforms */ -#ifndef NATIVE_64BIT_INT - -static SLONG Mix32MonoNormal(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) -{ - SWORD sample; - SLONG lvolsel = vnf->lvolsel; - - while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; - - *dest++ += lvolsel * sample; - } - return index; -} - -static SLONG Mix32StereoNormal(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) -{ - SWORD sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - - while(todo--) { - sample=srce[index >> FRACBITS]; - index += increment; - - *dest++ += lvolsel * sample; - *dest++ += rvolsel * sample; - } - return index; -} - -static SLONG Mix32SurroundNormal(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) -{ - SWORD sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - - if (lvolsel>=rvolsel) { - while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; - - *dest++ += lvolsel*sample; - *dest++ -= lvolsel*sample; - } - } else { - while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; - - *dest++ -= rvolsel*sample; - *dest++ += rvolsel*sample; - } - } - return index; -} - -static SLONG Mix32MonoInterp(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) -{ - SLONG sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rampvol = vnf->rampvol; - - if (rampvol) { - SLONG oldlvol = vnf->oldlvol - lvolsel; - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) - * sample >> CLICK_SHIFT; - if (!--rampvol) - break; - } - vnf->rampvol = rampvol; - if (todo < 0) - return index; - } - - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += lvolsel * sample; - } - return index; -} - -static SLONG Mix32StereoInterp(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) -{ - SLONG sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - SLONG rampvol = vnf->rampvol; - - if (rampvol) { - SLONG oldlvol = vnf->oldlvol - lvolsel; - SLONG oldrvol = vnf->oldrvol - rvolsel; - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) - * sample >> CLICK_SHIFT; - *dest++ += ((rvolsel << CLICK_SHIFT) + oldrvol * rampvol) - * sample >> CLICK_SHIFT; - if (!--rampvol) - break; - } - vnf->rampvol = rampvol; - if (todo < 0) - return index; - } - - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += lvolsel * sample; - *dest++ += rvolsel * sample; - } - return index; -} - -static SLONG Mix32SurroundInterp(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) -{ - SLONG sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - SLONG rampvol = vnf->rampvol; - SLONG oldvol, vol; - - if (lvolsel >= rvolsel) { - vol = lvolsel; - oldvol = vnf->oldlvol; - } else { - vol = rvolsel; - oldvol = vnf->oldrvol; - } - - if (rampvol) { - oldvol -= vol; - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - sample=((vol << CLICK_SHIFT) + oldvol * rampvol) - * sample >> CLICK_SHIFT; - *dest++ += sample; - *dest++ -= sample; - - if (!--rampvol) - break; - } - vnf->rampvol = rampvol; - if (todo < 0) - return index; - } - - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += vol*sample; - *dest++ -= vol*sample; - } - return index; -} -#endif - -/*========== 64 bit sample mixers - all platforms */ - -static SLONGLONG MixMonoNormal(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) -{ - SWORD sample; - SLONG lvolsel = vnf->lvolsel; - - while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; - - *dest++ += lvolsel * sample; - } - return index; -} - -static SLONGLONG MixStereoNormal(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) -{ - SWORD sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - - while(todo--) { - sample=srce[index >> FRACBITS]; - index += increment; - - *dest++ += lvolsel * sample; - *dest++ += rvolsel * sample; - } - return index; -} - -static SLONGLONG MixSurroundNormal(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) -{ - SWORD sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - - if(vnf->lvolsel>=vnf->rvolsel) { - while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; - - *dest++ += lvolsel*sample; - *dest++ -= lvolsel*sample; - } - } else { - while(todo--) { - sample = srce[index >> FRACBITS]; - index += increment; - - *dest++ -= rvolsel*sample; - *dest++ += rvolsel*sample; - } - } - return index; -} - -static SLONGLONG MixMonoInterp(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) -{ - SLONG sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rampvol = vnf->rampvol; - - if (rampvol) { - SLONG oldlvol = vnf->oldlvol - lvolsel; - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += ((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) - * sample >> CLICK_SHIFT; - if (!--rampvol) - break; - } - vnf->rampvol = rampvol; - if (todo < 0) - return index; - } - - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += lvolsel * sample; - } - return index; -} - -static SLONGLONG MixStereoInterp(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) -{ - SLONG sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - SLONG rampvol = vnf->rampvol; - - if (rampvol) { - SLONG oldlvol = vnf->oldlvol - lvolsel; - SLONG oldrvol = vnf->oldrvol - rvolsel; - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ +=((lvolsel << CLICK_SHIFT) + oldlvol * rampvol) - * sample >> CLICK_SHIFT; - *dest++ +=((rvolsel << CLICK_SHIFT) + oldrvol * rampvol) - * sample >> CLICK_SHIFT; - if (!--rampvol) - break; - } - vnf->rampvol = rampvol; - if (todo < 0) - return index; - } - - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += lvolsel * sample; - *dest++ += rvolsel * sample; - } - return index; -} - -static SLONGLONG MixSurroundInterp(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) -{ - SLONG sample; - SLONG lvolsel = vnf->lvolsel; - SLONG rvolsel = vnf->rvolsel; - SLONG rampvol = vnf->rampvol; - SLONG oldvol, vol; - - if (lvolsel >= rvolsel) { - vol = lvolsel; - oldvol = vnf->oldlvol; - } else { - vol = rvolsel; - oldvol = vnf->oldrvol; - } - - if (rampvol) { - oldvol -= vol; - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - sample=((vol << CLICK_SHIFT) + oldvol * rampvol) - * sample >> CLICK_SHIFT; - *dest++ += sample; - *dest++ -= sample; - if (!--rampvol) - break; - } - vnf->rampvol = rampvol; - if (todo < 0) - return index; - } - - while(todo--) { - sample=(SLONG)srce[index>>FRACBITS]+ - ((SLONG)(srce[(index>>FRACBITS)+1]-srce[index>>FRACBITS]) - *(index&FRACMASK)>>FRACBITS); - index += increment; - - *dest++ += vol*sample; - *dest++ -= vol*sample; - } - return index; -} - -static void (*MixReverb)(SLONG* srce,NATIVE count); - -/* Reverb macros */ -#define COMPUTE_LOC(n) loc##n = RVRindex % RVc##n -#define COMPUTE_LECHO(n) RVbufL##n [loc##n ]=speedup+((ReverbPct*RVbufL##n [loc##n ])>>7) -#define COMPUTE_RECHO(n) RVbufR##n [loc##n ]=speedup+((ReverbPct*RVbufR##n [loc##n ])>>7) - -static void MixReverb_Normal(SLONG* srce,NATIVE count) -{ - unsigned int speedup; - int ReverbPct; - unsigned int loc1,loc2,loc3,loc4; - unsigned int loc5,loc6,loc7,loc8; - - ReverbPct=58+(md_reverb<<2); - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - while(count--) { - /* Compute the left channel echo buffers */ - speedup = *srce >> 3; - - COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4); - COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8); - - /* Prepare to compute actual finalized data */ - RVRindex++; - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - /* left channel */ - *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ - RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; - } -} - -static void MixReverb_Stereo(SLONG* srce,NATIVE count) -{ - unsigned int speedup; - int ReverbPct; - unsigned int loc1, loc2, loc3, loc4; - unsigned int loc5, loc6, loc7, loc8; - - ReverbPct = 92+(md_reverb<<1); - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - while(count--) { - /* Compute the left channel echo buffers */ - speedup = *srce >> 3; - - COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4); - COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8); - - /* Compute the right channel echo buffers */ - speedup = srce[1] >> 3; - - COMPUTE_RECHO(1); COMPUTE_RECHO(2); COMPUTE_RECHO(3); COMPUTE_RECHO(4); - COMPUTE_RECHO(5); COMPUTE_RECHO(6); COMPUTE_RECHO(7); COMPUTE_RECHO(8); - - /* Prepare to compute actual finalized data */ - RVRindex++; - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - /* left channel then right channel */ - *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ - RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; - - *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+ - RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; - } -} - -/* Mixing macros */ -#define EXTRACT_SAMPLE(var,size) var=*srce++>>(BITSHIFT+16-size) -#define CHECK_SAMPLE(var,bound) var=(var>=bound)?bound-1:(var<-bound)?-bound:var -#define PUT_SAMPLE(var) *dste++=var - -static void Mix32To16(SWORD* dste,SLONG* srce,NATIVE count) -{ - SLONG x1,x2,x3,x4; - int remain; - - remain=count&3; - for(count>>=2;count;count--) { - EXTRACT_SAMPLE(x1,16); EXTRACT_SAMPLE(x2,16); - EXTRACT_SAMPLE(x3,16); EXTRACT_SAMPLE(x4,16); - - CHECK_SAMPLE(x1,32768); CHECK_SAMPLE(x2,32768); - CHECK_SAMPLE(x3,32768); CHECK_SAMPLE(x4,32768); - - PUT_SAMPLE(x1); PUT_SAMPLE(x2); PUT_SAMPLE(x3); PUT_SAMPLE(x4); - } - while(remain--) { - EXTRACT_SAMPLE(x1,16); - CHECK_SAMPLE(x1,32768); - PUT_SAMPLE(x1); - } -} - -static void Mix32To8(SBYTE* dste,SLONG* srce,NATIVE count) -{ - SWORD x1,x2,x3,x4; - int remain; - - remain=count&3; - for(count>>=2;count;count--) { - EXTRACT_SAMPLE(x1,8); EXTRACT_SAMPLE(x2,8); - EXTRACT_SAMPLE(x3,8); EXTRACT_SAMPLE(x4,8); - - CHECK_SAMPLE(x1,128); CHECK_SAMPLE(x2,128); - CHECK_SAMPLE(x3,128); CHECK_SAMPLE(x4,128); - - PUT_SAMPLE(x1+128); PUT_SAMPLE(x2+128); - PUT_SAMPLE(x3+128); PUT_SAMPLE(x4+128); - } - while(remain--) { - EXTRACT_SAMPLE(x1,8); - CHECK_SAMPLE(x1,128); - PUT_SAMPLE(x1+128); - } -} - -static void AddChannel(SLONG* ptr,NATIVE todo) -{ - SLONGLONG end,done; - SWORD *s; - - if(!(s=Samples[vnf->handle])) { - vnf->current = vnf->active = 0; - return; - } - - /* update the 'current' index so the sample loops, or stops playing if it - reached the end of the sample */ - while(todo>0) { - SLONGLONG endpos; - if(vnf->flags & SF_REVERSE) { - /* The sample is playing in reverse */ - if((vnf->flags&SF_LOOP)&&(vnf->currentflags & SF_BIDI) { - /* sample is doing bidirectional loops, so 'bounce' the - current index against the idxlpos */ - vnf->current = idxlpos+(idxlpos-vnf->current); - vnf->flags &= ~SF_REVERSE; - vnf->increment = -vnf->increment; - } else - /* normal backwards looping, so set the current position to - loopend index */ - vnf->current=idxlend-(idxlpos-vnf->current); - } else { - /* the sample is not looping, so check if it reached index 0 */ - if(vnf->current < 0) { - /* playing index reached 0, so stop playing this sample */ - vnf->current = vnf->active = 0; - break; - } - } - } else { - /* The sample is playing forward */ - if((vnf->flags & SF_LOOP) && - (vnf->current >= idxlend)) { - /* the sample is looping, check the loopend index */ - if(vnf->flags & SF_BIDI) { - /* sample is doing bidirectional loops, so 'bounce' the - current index against the idxlend */ - vnf->flags |= SF_REVERSE; - vnf->increment = -vnf->increment; - vnf->current = idxlend-(vnf->current-idxlend); - } else - /* normal backwards looping, so set the current position - to loopend index */ - vnf->current=idxlpos+(vnf->current-idxlend); - } else { - /* sample is not looping, so check if it reached the last - position */ - if(vnf->current >= idxsize) { - /* yes, so stop playing this sample */ - vnf->current = vnf->active = 0; - break; - } - } - } - - end=(vnf->flags&SF_REVERSE)?(vnf->flags&SF_LOOP)?idxlpos:0: - (vnf->flags&SF_LOOP)?idxlend:idxsize; - - /* if the sample is not blocked... */ - if((end==vnf->current)||(!vnf->increment)) - done=0; - else { - done=MIN((end-vnf->current)/vnf->increment+1,todo); - if(done<0) done=0; - } - - if(!done) { - vnf->active = 0; - break; - } - - endpos=vnf->current+done*vnf->increment; - - if(vnf->vol) { -#ifndef NATIVE_64BIT_INT - /* use the 32 bit mixers as often as we can (they're much faster) */ - if((vnf->current<0x7fffffff)&&(endpos<0x7fffffff)) { - if((md_mode & DMODE_INTERP)) { - if(vc_mode & DMODE_STEREO) { - if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) - vnf->current=Mix32SurroundInterp - (s,ptr,vnf->current,vnf->increment,done); - else - vnf->current=Mix32StereoInterp - (s,ptr,vnf->current,vnf->increment,done); - } else - vnf->current=Mix32MonoInterp - (s,ptr,vnf->current,vnf->increment,done); - } else if(vc_mode & DMODE_STEREO) { - if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) - vnf->current=Mix32SurroundNormal - (s,ptr,vnf->current,vnf->increment,done); - else - vnf->current=Mix32StereoNormal - (s,ptr,vnf->current,vnf->increment,done); - } else - vnf->current=Mix32MonoNormal - (s,ptr,vnf->current,vnf->increment,done); - } else -#endif - { - if((md_mode & DMODE_INTERP)) { - if(vc_mode & DMODE_STEREO) { - if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) - vnf->current=MixSurroundInterp - (s,ptr,vnf->current,vnf->increment,done); - else - vnf->current=MixStereoInterp - (s,ptr,vnf->current,vnf->increment,done); - } else - vnf->current=MixMonoInterp - (s,ptr,vnf->current,vnf->increment,done); - } else if(vc_mode & DMODE_STEREO) { - if((vnf->pan==PAN_SURROUND)&&(md_mode&DMODE_SURROUND)) - vnf->current=MixSurroundNormal - (s,ptr,vnf->current,vnf->increment,done); - else - vnf->current=MixStereoNormal - (s,ptr,vnf->current,vnf->increment,done); - } else - vnf->current=MixMonoNormal - (s,ptr,vnf->current,vnf->increment,done); - } - - } else - /* update sample position */ - vnf->current=endpos; - - todo-=done; -#if 1 - if ( vc_mode & DMODE_STEREO ) - ptr += done*2; - else - ptr += done; -#else - ptr +=(vc_mode & DMODE_STEREO)?(done<<1):done; -#endif - } -} - -#define _IN_VIRTCH_ -#include "virtch_common.c" -#undef _IN_VIRTCH_ - -void VC1_WriteSamples(SBYTE* buf,ULONG todo) -{ - int left,portion=0,count; - SBYTE *buffer; - int t, pan, vol; - - while(todo) { - if(!tickleft) { - if(vc_mode & DMODE_SOFT_MUSIC) md_player(); - tickleft=(md_mixfreq*125L)/(md_bpm*50L); - } - left = MIN(tickleft, todo); - buffer = buf; - tickleft -= left; - todo -= left; - buf += samples2bytes(left); - - while(left) { - portion = MIN(left, samplesthatfit); - count = (vc_mode & DMODE_STEREO)?(portion<<1):portion; - memset(vc_tickbuf, 0, count<<2); - for(t=0;tkick) { - vnf->current=((SLONGLONG)vnf->start)<kick =0; - vnf->active =1; - } - - if(!vnf->frq) vnf->active = 0; - - if(vnf->active) { - vnf->increment=((SLONGLONG)(vnf->frq<flags&SF_REVERSE) vnf->increment=-vnf->increment; - vol = vnf->vol; pan = vnf->pan; - - vnf->oldlvol=vnf->lvolsel;vnf->oldrvol=vnf->rvolsel; - if(vc_mode & DMODE_STEREO) { - if(pan != PAN_SURROUND) { - vnf->lvolsel=(vol*(PAN_RIGHT-pan))>>8; - vnf->rvolsel=(vol*pan)>>8; - } else - vnf->lvolsel=vnf->rvolsel=vol/2; - } else - vnf->lvolsel=vol; - - idxsize = (vnf->size)? ((SLONGLONG)vnf->size << FRACBITS)-1 : 0; - idxlend = (vnf->repend)? ((SLONGLONG)vnf->repend << FRACBITS)-1 : 0; - idxlpos = (SLONGLONG)vnf->reppos << FRACBITS; - AddChannel(vc_tickbuf, portion); - } - } - - if(md_reverb) { - if(md_reverb>15) md_reverb=15; - MixReverb(vc_tickbuf, portion); - } - - if(vc_mode & DMODE_16BITS) - Mix32To16((SWORD*) buffer, vc_tickbuf, count); - else - Mix32To8((SBYTE*) buffer, vc_tickbuf, count); - - buffer += samples2bytes(portion); - left -= portion; - } - } -} - -BOOL VC1_Init(void) -{ - VC_SetupPointers(); - - if (md_mode&DMODE_HQMIXER) - return VC2_Init(); - - if(!(Samples=(SWORD**)_mm_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) { - _mm_errno = MMERR_INITIALIZING_MIXER; - return 1; - } - if(!vc_tickbuf) - if(!(vc_tickbuf=(SLONG*)_mm_malloc((TICKLSIZE+32)*sizeof(SLONG)))) { - _mm_errno = MMERR_INITIALIZING_MIXER; - return 1; - } - - MixReverb=(md_mode&DMODE_STEREO)?MixReverb_Stereo:MixReverb_Normal; - vc_mode = md_mode; - return 0; -} - -BOOL VC1_PlayStart(void) -{ - samplesthatfit=TICKLSIZE; - if(vc_mode & DMODE_STEREO) samplesthatfit >>= 1; - tickleft = 0; - - RVc1 = (5000L * md_mixfreq) / REVERBERATION; - RVc2 = (5078L * md_mixfreq) / REVERBERATION; - RVc3 = (5313L * md_mixfreq) / REVERBERATION; - RVc4 = (5703L * md_mixfreq) / REVERBERATION; - RVc5 = (6250L * md_mixfreq) / REVERBERATION; - RVc6 = (6953L * md_mixfreq) / REVERBERATION; - RVc7 = (7813L * md_mixfreq) / REVERBERATION; - RVc8 = (8828L * md_mixfreq) / REVERBERATION; - - if(!(RVbufL1=(SLONG*)_mm_calloc((RVc1+1),sizeof(SLONG)))) return 1; - if(!(RVbufL2=(SLONG*)_mm_calloc((RVc2+1),sizeof(SLONG)))) return 1; - if(!(RVbufL3=(SLONG*)_mm_calloc((RVc3+1),sizeof(SLONG)))) return 1; - if(!(RVbufL4=(SLONG*)_mm_calloc((RVc4+1),sizeof(SLONG)))) return 1; - if(!(RVbufL5=(SLONG*)_mm_calloc((RVc5+1),sizeof(SLONG)))) return 1; - if(!(RVbufL6=(SLONG*)_mm_calloc((RVc6+1),sizeof(SLONG)))) return 1; - if(!(RVbufL7=(SLONG*)_mm_calloc((RVc7+1),sizeof(SLONG)))) return 1; - if(!(RVbufL8=(SLONG*)_mm_calloc((RVc8+1),sizeof(SLONG)))) return 1; - - if(!(RVbufR1=(SLONG*)_mm_calloc((RVc1+1),sizeof(SLONG)))) return 1; - if(!(RVbufR2=(SLONG*)_mm_calloc((RVc2+1),sizeof(SLONG)))) return 1; - if(!(RVbufR3=(SLONG*)_mm_calloc((RVc3+1),sizeof(SLONG)))) return 1; - if(!(RVbufR4=(SLONG*)_mm_calloc((RVc4+1),sizeof(SLONG)))) return 1; - if(!(RVbufR5=(SLONG*)_mm_calloc((RVc5+1),sizeof(SLONG)))) return 1; - if(!(RVbufR6=(SLONG*)_mm_calloc((RVc6+1),sizeof(SLONG)))) return 1; - if(!(RVbufR7=(SLONG*)_mm_calloc((RVc7+1),sizeof(SLONG)))) return 1; - if(!(RVbufR8=(SLONG*)_mm_calloc((RVc8+1),sizeof(SLONG)))) return 1; - - RVRindex = 0; - return 0; -} - -void VC1_PlayStop(void) -{ - if(RVbufL1) free(RVbufL1); - if(RVbufL2) free(RVbufL2); - if(RVbufL3) free(RVbufL3); - if(RVbufL4) free(RVbufL4); - if(RVbufL5) free(RVbufL5); - if(RVbufL6) free(RVbufL6); - if(RVbufL7) free(RVbufL7); - if(RVbufL8) free(RVbufL8); - RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; - if(RVbufR1) free(RVbufR1); - if(RVbufR2) free(RVbufR2); - if(RVbufR3) free(RVbufR3); - if(RVbufR4) free(RVbufR4); - if(RVbufR5) free(RVbufR5); - if(RVbufR6) free(RVbufR6); - if(RVbufR7) free(RVbufR7); - if(RVbufR8) free(RVbufR8); - RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; -} - -BOOL VC1_SetNumVoices(void) -{ - int t; - - if(!(vc_softchn=md_softchn)) return 0; - - if(vinf) free(vinf); - if(!(vinf= _mm_calloc(sizeof(VINFO),vc_softchn))) return 1; - - for(t=0;t -#endif -#include - -#include "mikmod_internals.h" - -#ifdef macintosh -#define NO_64BIT_MIXER -#endif -/* - Constant Definitions - ==================== - - MAXVOL_FACTOR (was BITSHIFT in virtch.c) - Controls the maximum volume of the output data. All mixed data is - divided by this number after mixing, so larger numbers result in - quieter mixing. Smaller numbers will increase the likeliness of - distortion on loud modules. - - REVERBERATION - Larger numbers result in shorter reverb duration. Longer reverb - durations can cause unwanted static and make the reverb sound more - like a crappy echo. - - SAMPLING_SHIFT - Specified the shift multiplier which controls by how much the mixing - rate is multiplied while mixing. Higher values can improve quality by - smoothing the sound and reducing pops and clicks. Note, this is a shift - value, so a value of 2 becomes a mixing-rate multiplier of 4, and a - value of 3 = 8, etc. - - FRACBITS - The number of bits per integer devoted to the fractional part of the - number. Generally, this number should not be changed for any reason. - - !!! IMPORTANT !!! All values below MUST ALWAYS be greater than 0 - -*/ - -#define MAXVOL_FACTOR (1<<9) -#define REVERBERATION 11000L - -#define SAMPLING_SHIFT 2 -#define SAMPLING_FACTOR (1UL< sample has to be restarted */ - UBYTE active; /* =1 -> sample is playing */ - UWORD flags; /* 16/8 bits looping/one-shot */ - SWORD handle; /* identifies the sample */ - ULONG start; /* start index */ - ULONG size; /* samplesize */ - ULONG reppos; /* loop start */ - ULONG repend; /* loop end */ - ULONG frq; /* current frequency */ - int vol; /* current volume */ - int pan; /* current panning position */ - - int click; - int rampvol; - SLONG lastvalL,lastvalR; - int lvolsel,rvolsel; /* Volume factor in range 0-255 */ - int oldlvol,oldrvol; - - SLONGLONG current; /* current index in the sample */ - SLONGLONG increment; /* increment value */ -} VINFO; - -static SWORD **Samples; -static VINFO *vinf=NULL,*vnf; -static long tickleft,samplesthatfit,vc_memory=0; -static int vc_softchn; -static SLONGLONG idxsize,idxlpos,idxlend; -static SLONG *vc_tickbuf=NULL; -static UWORD vc_mode; - -/* Reverb control variables */ - -static int RVc1, RVc2, RVc3, RVc4, RVc5, RVc6, RVc7, RVc8; -static ULONG RVRindex; - -/* For Mono or Left Channel */ -static SLONG *RVbufL1=NULL,*RVbufL2=NULL,*RVbufL3=NULL,*RVbufL4=NULL, - *RVbufL5=NULL,*RVbufL6=NULL,*RVbufL7=NULL,*RVbufL8=NULL; - -/* For Stereo only (Right Channel) */ -static SLONG *RVbufR1=NULL,*RVbufR2=NULL,*RVbufR3=NULL,*RVbufR4=NULL, - *RVbufR5=NULL,*RVbufR6=NULL,*RVbufR7=NULL,*RVbufR8=NULL; - -#ifdef NATIVE_64BIT_INT -#define NATIVE SLONGLONG -#else -#define NATIVE SLONG -#endif - -/*========== 32 bit sample mixers - only for 32 bit platforms */ -#ifndef NATIVE_64BIT_INT - -static SLONG Mix32MonoNormal(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,SLONG todo) -{ - SWORD sample=0; - SLONG i,f; - - while(todo--) { - i=index>>FRACBITS,f=index&FRACMASK; - sample=(((SLONG)(srce[i]*(FRACMASK+1L-f)) + - ((SLONG)srce[i+1]*f)) >> FRACBITS); - index+=increment; - - if(vnf->rampvol) { - *dest++ += (long)( - ( ( (SLONG)(vnf->oldlvol*vnf->rampvol) + - (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * - (SLONG)sample ) >> CLICK_SHIFT ); - vnf->rampvol--; - } else - if(vnf->click) { - *dest++ += (long)( - ( ( ((SLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONG)sample ) + - (vnf->lastvalL*vnf->click) ) >> CLICK_SHIFT ); - vnf->click--; - } else - *dest++ +=vnf->lvolsel*sample; - } - vnf->lastvalL=vnf->lvolsel * sample; - - return index; -} - -static SLONG Mix32StereoNormal(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,ULONG todo) -{ - SWORD sample=0; - SLONG i,f; - - while(todo--) { - i=index>>FRACBITS,f=index&FRACMASK; - sample=((((SLONG)srce[i]*(FRACMASK+1L-f)) + - ((SLONG)srce[i+1] * f)) >> FRACBITS); - index += increment; - - if(vnf->rampvol) { - *dest++ += (long)( - ( ( ((SLONG)vnf->oldlvol*vnf->rampvol) + - (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) - ) * (SLONG)sample ) >> CLICK_SHIFT ); - *dest++ += (long)( - ( ( ((SLONG)vnf->oldrvol*vnf->rampvol) + - (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol)) - ) * (SLONG)sample ) >> CLICK_SHIFT ); - vnf->rampvol--; - } else - if(vnf->click) { - *dest++ += (long)( - ( ( (SLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONG)sample ) + (vnf->lastvalL * vnf->click) ) - >> CLICK_SHIFT ); - *dest++ += (long)( - ( ( ((SLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONG)sample ) + (vnf->lastvalR * vnf->click) ) - >> CLICK_SHIFT ); - vnf->click--; - } else { - *dest++ +=vnf->lvolsel*sample; - *dest++ +=vnf->rvolsel*sample; - } - } - vnf->lastvalL=vnf->lvolsel*sample; - vnf->lastvalR=vnf->rvolsel*sample; - - return index; -} - -static SLONG Mix32StereoSurround(SWORD* srce,SLONG* dest,SLONG index,SLONG increment,ULONG todo) -{ - SWORD sample=0; - long whoop; - SLONG i, f; - - while(todo--) { - i=index>>FRACBITS,f=index&FRACMASK; - sample=((((SLONG)srce[i]*(FRACMASK+1L-f)) + - ((SLONG)srce[i+1]*f)) >> FRACBITS); - index+=increment; - - if(vnf->rampvol) { - whoop=(long)( - ( ( (SLONG)(vnf->oldlvol*vnf->rampvol) + - (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * - (SLONG)sample) >> CLICK_SHIFT ); - *dest++ +=whoop; - *dest++ -=whoop; - vnf->rampvol--; - } else - if(vnf->click) { - whoop = (long)( - ( ( ((SLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONG)sample) + - (vnf->lastvalL * vnf->click) ) >> CLICK_SHIFT ); - *dest++ +=whoop; - *dest++ -=whoop; - vnf->click--; - } else { - *dest++ +=vnf->lvolsel*sample; - *dest++ -=vnf->lvolsel*sample; - } - } - vnf->lastvalL=vnf->lvolsel*sample; - vnf->lastvalR=vnf->lvolsel*sample; - - return index; -} -#endif - -/*========== 64 bit mixers */ - -#ifndef NO_64BIT_MIXER - -static SLONGLONG MixMonoNormal(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,SLONG todo) -{ - SWORD sample=0; - SLONGLONG i,f; - - while(todo--) { - i=index>>FRACBITS,f=index&FRACMASK; - sample=(((SLONGLONG)(srce[i]*(FRACMASK+1L-f)) + - ((SLONGLONG)srce[i+1]*f)) >> FRACBITS); - index+=increment; - - if(vnf->rampvol) { - *dest++ += (long)( - ( ( (SLONGLONG)(vnf->oldlvol*vnf->rampvol) + - (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * - (SLONGLONG)sample ) >> CLICK_SHIFT ); - vnf->rampvol--; - } else - if(vnf->click) { - *dest++ += (long)( - ( ( ((SLONGLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONGLONG)sample ) + - (vnf->lastvalL*vnf->click) ) >> CLICK_SHIFT ); - vnf->click--; - } else - *dest++ +=vnf->lvolsel*sample; - } - vnf->lastvalL=vnf->lvolsel * sample; - - return index; -} - -static SLONGLONG MixStereoNormal(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,ULONG todo) -{ - SWORD sample=0; - SLONGLONG i,f; - - while(todo--) { - i=index>>FRACBITS,f=index&FRACMASK; - sample=((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + - ((SLONGLONG)srce[i+1] * f)) >> FRACBITS); - index += increment; - - if(vnf->rampvol) { - *dest++ += (long)( - ( ( ((SLONGLONG)vnf->oldlvol*vnf->rampvol) + - (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) - ) * (SLONGLONG)sample ) >> CLICK_SHIFT ); - *dest++ += (long)( - ( ( ((SLONGLONG)vnf->oldrvol*vnf->rampvol) + - (vnf->rvolsel*(CLICK_BUFFER-vnf->rampvol)) - ) * (SLONGLONG)sample ) >> CLICK_SHIFT ); - vnf->rampvol--; - } else - if(vnf->click) { - *dest++ += (long)( - ( ( (SLONGLONG)(vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONGLONG)sample ) + (vnf->lastvalL * vnf->click) ) - >> CLICK_SHIFT ); - *dest++ += (long)( - ( ( ((SLONGLONG)vnf->rvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONGLONG)sample ) + (vnf->lastvalR * vnf->click) ) - >> CLICK_SHIFT ); - vnf->click--; - } else { - *dest++ +=vnf->lvolsel*sample; - *dest++ +=vnf->rvolsel*sample; - } - } - vnf->lastvalL=vnf->lvolsel*sample; - vnf->lastvalR=vnf->rvolsel*sample; - - return index; -} - -static SLONGLONG MixStereoSurround(SWORD* srce,SLONG* dest,SLONGLONG index,SLONGLONG increment,ULONG todo) -{ - SWORD sample=0; - long whoop; - SLONGLONG i, f; - - while(todo--) { - i=index>>FRACBITS,f=index&FRACMASK; - sample=((((SLONGLONG)srce[i]*(FRACMASK+1L-f)) + - ((SLONGLONG)srce[i+1]*f)) >> FRACBITS); - index+=increment; - - if(vnf->rampvol) { - whoop=(long)( - ( ( (SLONGLONG)(vnf->oldlvol*vnf->rampvol) + - (vnf->lvolsel*(CLICK_BUFFER-vnf->rampvol)) ) * - (SLONGLONG)sample) >> CLICK_SHIFT ); - *dest++ +=whoop; - *dest++ -=whoop; - vnf->rampvol--; - } else - if(vnf->click) { - whoop = (long)( - ( ( ((SLONGLONG)vnf->lvolsel*(CLICK_BUFFER-vnf->click)) * - (SLONGLONG)sample) + - (vnf->lastvalL * vnf->click) ) >> CLICK_SHIFT ); - *dest++ +=whoop; - *dest++ -=whoop; - vnf->click--; - } else { - *dest++ +=vnf->lvolsel*sample; - *dest++ -=vnf->lvolsel*sample; - } - } - vnf->lastvalL=vnf->lvolsel*sample; - vnf->lastvalR=vnf->lvolsel*sample; - - return index; -} - -#endif /* NO_64BIT_MIXER */ - -static void(*Mix32to16)(SWORD* dste,SLONG* srce,NATIVE count); -static void(*Mix32to8)(SBYTE* dste,SLONG* srce,NATIVE count); -static void(*MixReverb)(SLONG* srce,NATIVE count); - -/* Reverb macros */ -#define COMPUTE_LOC(n) loc##n = RVRindex % RVc##n -#define COMPUTE_LECHO(n) RVbufL##n [loc##n ]=speedup+((ReverbPct*RVbufL##n [loc##n ])>>7) -#define COMPUTE_RECHO(n) RVbufR##n [loc##n ]=speedup+((ReverbPct*RVbufR##n [loc##n ])>>7) - -static void MixReverb_Normal(SLONG* srce,NATIVE count) -{ - NATIVE speedup; - int ReverbPct; - unsigned int loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8; - - ReverbPct=58+(md_reverb*4); - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - while(count--) { - /* Compute the left channel echo buffers */ - speedup = *srce >> 3; - - COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4); - COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8); - - /* Prepare to compute actual finalized data */ - RVRindex++; - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - /* left channel */ - *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ - RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; - } -} - -static void MixReverb_Stereo(SLONG *srce,NATIVE count) -{ - NATIVE speedup; - int ReverbPct; - unsigned int loc1,loc2,loc3,loc4,loc5,loc6,loc7,loc8; - - ReverbPct=58+(md_reverb*4); - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - while(count--) { - /* Compute the left channel echo buffers */ - speedup = *srce >> 3; - - COMPUTE_LECHO(1); COMPUTE_LECHO(2); COMPUTE_LECHO(3); COMPUTE_LECHO(4); - COMPUTE_LECHO(5); COMPUTE_LECHO(6); COMPUTE_LECHO(7); COMPUTE_LECHO(8); - - /* Compute the right channel echo buffers */ - speedup = srce[1] >> 3; - - COMPUTE_RECHO(1); COMPUTE_RECHO(2); COMPUTE_RECHO(3); COMPUTE_RECHO(4); - COMPUTE_RECHO(5); COMPUTE_RECHO(6); COMPUTE_RECHO(7); COMPUTE_RECHO(8); - - /* Prepare to compute actual finalized data */ - RVRindex++; - - COMPUTE_LOC(1); COMPUTE_LOC(2); COMPUTE_LOC(3); COMPUTE_LOC(4); - COMPUTE_LOC(5); COMPUTE_LOC(6); COMPUTE_LOC(7); COMPUTE_LOC(8); - - /* left channel */ - *srce++ +=RVbufL1[loc1]-RVbufL2[loc2]+RVbufL3[loc3]-RVbufL4[loc4]+ - RVbufL5[loc5]-RVbufL6[loc6]+RVbufL7[loc7]-RVbufL8[loc8]; - - /* right channel */ - *srce++ +=RVbufR1[loc1]-RVbufR2[loc2]+RVbufR3[loc3]-RVbufR4[loc4]+ - RVbufR5[loc5]-RVbufR6[loc6]+RVbufR7[loc7]-RVbufR8[loc8]; - } -} - -/* Mixing macros */ -#define EXTRACT_SAMPLE(var,attenuation) var=*srce++/(MAXVOL_FACTOR*attenuation) -#define CHECK_SAMPLE(var,bound) var=(var>=bound)?bound-1:(var<-bound)?-bound:var - -static void Mix32To16_Normal(SWORD* dste,SLONG* srce,NATIVE count) -{ - NATIVE x1,x2,tmpx; - int i; - - for(count/=SAMPLING_FACTOR;count;count--) { - tmpx=0; - - for(i=SAMPLING_FACTOR/2;i;i--) { - EXTRACT_SAMPLE(x1,1); EXTRACT_SAMPLE(x2,1); - - CHECK_SAMPLE(x1,32768); CHECK_SAMPLE(x2,32768); - - tmpx+=x1+x2; - } - *dste++ =tmpx/SAMPLING_FACTOR; - } -} - -static void Mix32To16_Stereo(SWORD* dste,SLONG* srce,NATIVE count) -{ - NATIVE x1,x2,x3,x4,tmpx,tmpy; - int i; - - for(count/=SAMPLING_FACTOR;count;count--) { - tmpx=tmpy=0; - - for(i=SAMPLING_FACTOR/2;i;i--) { - EXTRACT_SAMPLE(x1,1); EXTRACT_SAMPLE(x2,1); - EXTRACT_SAMPLE(x3,1); EXTRACT_SAMPLE(x4,1); - - CHECK_SAMPLE(x1,32768); CHECK_SAMPLE(x2,32768); - CHECK_SAMPLE(x3,32768); CHECK_SAMPLE(x4,32768); - - tmpx+=x1+x3; - tmpy+=x2+x4; - } - *dste++ =tmpx/SAMPLING_FACTOR; - *dste++ =tmpy/SAMPLING_FACTOR; - } -} - -static void Mix32To8_Normal(SBYTE* dste,SLONG* srce,NATIVE count) -{ - NATIVE x1,x2,tmpx; - int i; - - for(count/=SAMPLING_FACTOR;count;count--) { - tmpx = 0; - - for(i=SAMPLING_FACTOR/2;i;i--) { - EXTRACT_SAMPLE(x1,256); EXTRACT_SAMPLE(x2,256); - - CHECK_SAMPLE(x1,128); CHECK_SAMPLE(x2,128); - - tmpx+=x1+x2; - } - *dste++ =(tmpx/SAMPLING_FACTOR)+128; - } -} - -static void Mix32To8_Stereo(SBYTE* dste,SLONG* srce,NATIVE count) -{ - NATIVE x1,x2,x3,x4,tmpx,tmpy; - int i; - - for(count/=SAMPLING_FACTOR;count;count--) { - tmpx=tmpy=0; - - for(i=SAMPLING_FACTOR/2;i;i--) { - EXTRACT_SAMPLE(x1,256); EXTRACT_SAMPLE(x2,256); - EXTRACT_SAMPLE(x3,256); EXTRACT_SAMPLE(x4,256); - - CHECK_SAMPLE(x1,128); CHECK_SAMPLE(x2,128); - CHECK_SAMPLE(x3,128); CHECK_SAMPLE(x4,128); - - tmpx+=x1+x3; - tmpy+=x2+x4; - } - *dste++ =(tmpx/SAMPLING_FACTOR)+128; - *dste++ =(tmpy/SAMPLING_FACTOR)+128; - } -} - -static void AddChannel(SLONG* ptr,NATIVE todo) -{ - SLONGLONG end,done; - SWORD *s; - - if(!(s=Samples[vnf->handle])) { - vnf->current = vnf->active = 0; - vnf->lastvalL = vnf->lastvalR = 0; - return; - } - - /* update the 'current' index so the sample loops, or stops playing if it - reached the end of the sample */ - while(todo>0) { - SLONGLONG endpos; - - if(vnf->flags & SF_REVERSE) { - /* The sample is playing in reverse */ - if((vnf->flags&SF_LOOP)&&(vnf->currentflags & SF_BIDI) { - /* sample is doing bidirectional loops, so 'bounce' the - current index against the idxlpos */ - vnf->current = idxlpos+(idxlpos-vnf->current); - vnf->flags &= ~SF_REVERSE; - vnf->increment = -vnf->increment; - } else - /* normal backwards looping, so set the current position to - loopend index */ - vnf->current=idxlend-(idxlpos-vnf->current); - } else { - /* the sample is not looping, so check if it reached index 0 */ - if(vnf->current < 0) { - /* playing index reached 0, so stop playing this sample */ - vnf->current = vnf->active = 0; - break; - } - } - } else { - /* The sample is playing forward */ - if((vnf->flags & SF_LOOP) && - (vnf->current >= idxlend)) { - /* the sample is looping, check the loopend index */ - if(vnf->flags & SF_BIDI) { - /* sample is doing bidirectional loops, so 'bounce' the - current index against the idxlend */ - vnf->flags |= SF_REVERSE; - vnf->increment = -vnf->increment; - vnf->current = idxlend-(vnf->current-idxlend); - } else - /* normal backwards looping, so set the current position - to loopend index */ - vnf->current=idxlpos+(vnf->current-idxlend); - } else { - /* sample is not looping, so check if it reached the last - position */ - if(vnf->current >= idxsize) { - /* yes, so stop playing this sample */ - vnf->current = vnf->active = 0; - break; - } - } - } - - end=(vnf->flags&SF_REVERSE)?(vnf->flags&SF_LOOP)?idxlpos:0: - (vnf->flags&SF_LOOP)?idxlend:idxsize; - - /* if the sample is not blocked... */ - if((end==vnf->current)||(!vnf->increment)) - done=0; - else { - done=MIN((end-vnf->current)/vnf->increment+1,todo); - if(done<0) done=0; - } - - if(!done) { - vnf->active = 0; - break; - } - - endpos=vnf->current+done*vnf->increment; - - if(vnf->vol || vnf->rampvol) { -#ifndef NATIVE_64BIT_INT - /* use the 32 bit mixers as often as we can (they're much faster) */ - if((vnf->current<0x7fffffff)&&(endpos<0x7fffffff)) { - if(vc_mode & DMODE_STEREO) { - if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND)) - vnf->current=Mix32StereoSurround - (s,ptr,vnf->current,vnf->increment,done); - else - vnf->current=Mix32StereoNormal - (s,ptr,vnf->current,vnf->increment,done); - } else - vnf->current=Mix32MonoNormal - (s,ptr,vnf->current,vnf->increment,done); - } else -#endif -#ifdef NO_64BIT_MIXER - /* Uh oh, the 64-bit mixers don't compile... */; -#else - { - if(vc_mode & DMODE_STEREO) { - if((vnf->pan==PAN_SURROUND)&&(vc_mode&DMODE_SURROUND)) - vnf->current=MixStereoSurround - (s,ptr,vnf->current,vnf->increment,done); - else - vnf->current=MixStereoNormal - (s,ptr,vnf->current,vnf->increment,done); - } else - vnf->current=MixMonoNormal - (s,ptr,vnf->current,vnf->increment,done); - } -#endif - } else { - vnf->lastvalL = vnf->lastvalR = 0; - /* update sample position */ - vnf->current=endpos; - } - - todo -= done; -#if 1 - if ( vc_mode & DMODE_STEREO ) { - ptr += done*2; - } else { - ptr += done; - } -#else - ptr +=(vc_mode & DMODE_STEREO)?(done<<1):done; -#endif - } -} - -#define _IN_VIRTCH_ - -#define VC1_SilenceBytes VC2_SilenceBytes -#define VC1_WriteSamples VC2_WriteSamples -#define VC1_WriteBytes VC2_WriteBytes -#define VC1_Exit VC2_Exit -#define VC1_VoiceSetVolume VC2_VoiceSetVolume -#define VC1_VoiceGetVolume VC2_VoiceGetVolume -#define VC1_VoiceSetPanning VC2_VoiceSetPanning -#define VC1_VoiceGetPanning VC2_VoiceGetPanning -#define VC1_VoiceSetFrequency VC2_VoiceSetFrequency -#define VC1_VoiceGetFrequency VC2_VoiceGetFrequency -#define VC1_VoicePlay VC2_VoicePlay -#define VC1_VoiceStop VC2_VoiceStop -#define VC1_VoiceStopped VC2_VoiceStopped -#define VC1_VoiceGetPosition VC2_VoiceGetPosition -#define VC1_SampleUnload VC2_SampleUnload -#define VC1_SampleLoad VC2_SampleLoad -#define VC1_SampleSpace VC2_SampleSpace -#define VC1_SampleLength VC2_SampleLength -#define VC1_VoiceRealVolume VC2_VoiceRealVolume - -#include "virtch_common.c" -#undef _IN_VIRTCH_ - -void VC2_WriteSamples(SBYTE* buf,ULONG todo) -{ - int left,portion=0; - SBYTE *buffer; - int t,pan,vol; - - todo*=SAMPLING_FACTOR; - - while(todo) { - if(!tickleft) { - if(vc_mode & DMODE_SOFT_MUSIC) md_player(); - tickleft=(md_mixfreq*125L*SAMPLING_FACTOR)/(md_bpm*50L); - tickleft&=~(SAMPLING_FACTOR-1); - } - left = MIN(tickleft, todo); - buffer = buf; - tickleft -= left; - todo -= left; - buf += samples2bytes(left)/SAMPLING_FACTOR; - - while(left) { - portion = MIN(left, samplesthatfit); - memset(vc_tickbuf,0,portion<<((vc_mode&DMODE_STEREO)?3:2)); - for(t=0;tkick) { - vnf->current=((SLONGLONG)(vnf->start))<kick = 0; - vnf->active = 1; - vnf->click = CLICK_BUFFER; - vnf->rampvol = 0; - } - - if(!vnf->frq) vnf->active = 0; - - if(vnf->active) { - vnf->increment=((SLONGLONG)(vnf->frq)<<(FRACBITS-SAMPLING_SHIFT)) - /md_mixfreq; - if(vnf->flags&SF_REVERSE) vnf->increment=-vnf->increment; - vol = vnf->vol; pan = vnf->pan; - - vnf->oldlvol=vnf->lvolsel;vnf->oldrvol=vnf->rvolsel; - if(vc_mode & DMODE_STEREO) { - if(pan!=PAN_SURROUND) { - vnf->lvolsel=(vol*(PAN_RIGHT-pan))>>8; - vnf->rvolsel=(vol*pan)>>8; - } else { - vnf->lvolsel=vnf->rvolsel=(vol * 256L) / 480; - } - } else - vnf->lvolsel=vol; - - idxsize=(vnf->size)?((SLONGLONG)(vnf->size)<repend)?((SLONGLONG)(vnf->repend)<reppos)<15) md_reverb=15; - MixReverb(vc_tickbuf,portion); - } - - if(vc_mode & DMODE_16BITS) - Mix32to16((SWORD*)buffer,vc_tickbuf,portion); - else - Mix32to8((SBYTE*)buffer,vc_tickbuf,portion); - - buffer += samples2bytes(portion) / SAMPLING_FACTOR; - left -= portion; - } - } -} - -BOOL VC2_Init(void) -{ - VC_SetupPointers(); - - if (!(md_mode&DMODE_HQMIXER)) - return VC1_Init(); - - if(!(Samples=(SWORD**)_mm_calloc(MAXSAMPLEHANDLES,sizeof(SWORD*)))) { - _mm_errno = MMERR_INITIALIZING_MIXER; - return 1; - } - if(!vc_tickbuf) - if(!(vc_tickbuf=(SLONG*)_mm_malloc((TICKLSIZE+32)*sizeof(SLONG)))) { - _mm_errno = MMERR_INITIALIZING_MIXER; - return 1; - } - - if(md_mode & DMODE_STEREO) { - Mix32to16 = Mix32To16_Stereo; - Mix32to8 = Mix32To8_Stereo; - MixReverb = MixReverb_Stereo; - } else { - Mix32to16 = Mix32To16_Normal; - Mix32to8 = Mix32To8_Normal; - MixReverb = MixReverb_Normal; - } - md_mode |= DMODE_INTERP; - vc_mode = md_mode; - return 0; -} - -BOOL VC2_PlayStart(void) -{ - md_mode|=DMODE_INTERP; - - samplesthatfit = TICKLSIZE; - if(vc_mode & DMODE_STEREO) samplesthatfit >>= 1; - tickleft = 0; - - RVc1 = (5000L * md_mixfreq) / (REVERBERATION * 10); - RVc2 = (5078L * md_mixfreq) / (REVERBERATION * 10); - RVc3 = (5313L * md_mixfreq) / (REVERBERATION * 10); - RVc4 = (5703L * md_mixfreq) / (REVERBERATION * 10); - RVc5 = (6250L * md_mixfreq) / (REVERBERATION * 10); - RVc6 = (6953L * md_mixfreq) / (REVERBERATION * 10); - RVc7 = (7813L * md_mixfreq) / (REVERBERATION * 10); - RVc8 = (8828L * md_mixfreq) / (REVERBERATION * 10); - - if(!(RVbufL1=(SLONG*)_mm_calloc((RVc1+1),sizeof(SLONG)))) return 1; - if(!(RVbufL2=(SLONG*)_mm_calloc((RVc2+1),sizeof(SLONG)))) return 1; - if(!(RVbufL3=(SLONG*)_mm_calloc((RVc3+1),sizeof(SLONG)))) return 1; - if(!(RVbufL4=(SLONG*)_mm_calloc((RVc4+1),sizeof(SLONG)))) return 1; - if(!(RVbufL5=(SLONG*)_mm_calloc((RVc5+1),sizeof(SLONG)))) return 1; - if(!(RVbufL6=(SLONG*)_mm_calloc((RVc6+1),sizeof(SLONG)))) return 1; - if(!(RVbufL7=(SLONG*)_mm_calloc((RVc7+1),sizeof(SLONG)))) return 1; - if(!(RVbufL8=(SLONG*)_mm_calloc((RVc8+1),sizeof(SLONG)))) return 1; - - if(!(RVbufR1=(SLONG*)_mm_calloc((RVc1+1),sizeof(SLONG)))) return 1; - if(!(RVbufR2=(SLONG*)_mm_calloc((RVc2+1),sizeof(SLONG)))) return 1; - if(!(RVbufR3=(SLONG*)_mm_calloc((RVc3+1),sizeof(SLONG)))) return 1; - if(!(RVbufR4=(SLONG*)_mm_calloc((RVc4+1),sizeof(SLONG)))) return 1; - if(!(RVbufR5=(SLONG*)_mm_calloc((RVc5+1),sizeof(SLONG)))) return 1; - if(!(RVbufR6=(SLONG*)_mm_calloc((RVc6+1),sizeof(SLONG)))) return 1; - if(!(RVbufR7=(SLONG*)_mm_calloc((RVc7+1),sizeof(SLONG)))) return 1; - if(!(RVbufR8=(SLONG*)_mm_calloc((RVc8+1),sizeof(SLONG)))) return 1; - - RVRindex = 0; - return 0; -} - -void VC2_PlayStop(void) -{ - if(RVbufL1) free(RVbufL1); - if(RVbufL2) free(RVbufL2); - if(RVbufL3) free(RVbufL3); - if(RVbufL4) free(RVbufL4); - if(RVbufL5) free(RVbufL5); - if(RVbufL6) free(RVbufL6); - if(RVbufL7) free(RVbufL7); - if(RVbufL8) free(RVbufL8); - if(RVbufR1) free(RVbufR1); - if(RVbufR2) free(RVbufR2); - if(RVbufR3) free(RVbufR3); - if(RVbufR4) free(RVbufR4); - if(RVbufR5) free(RVbufR5); - if(RVbufR6) free(RVbufR6); - if(RVbufR7) free(RVbufR7); - if(RVbufR8) free(RVbufR8); - - RVbufL1=RVbufL2=RVbufL3=RVbufL4=RVbufL5=RVbufL6=RVbufL7=RVbufL8=NULL; - RVbufR1=RVbufR2=RVbufR3=RVbufR4=RVbufR5=RVbufR6=RVbufR7=RVbufR8=NULL; -} - -BOOL VC2_SetNumVoices(void) -{ - int t; - - md_mode|=DMODE_INTERP; - - if(!(vc_softchn=md_softchn)) return 0; - - if(vinf) free(vinf); - if(!(vinf=_mm_calloc(sizeof(VINFO),vc_softchn))) return 1; - - for(t=0;t>= 1; - if(vc_mode & DMODE_STEREO) bytes >>= 1; - return bytes; -} - -/* Fill the buffer with 'todo' bytes of silence (it depends on the mixing mode - how the buffer is filled) */ -ULONG VC1_SilenceBytes(SBYTE* buf,ULONG todo) -{ - todo=samples2bytes(bytes2samples(todo)); - - /* clear the buffer to zero (16 bits signed) or 0x80 (8 bits unsigned) */ - if(vc_mode & DMODE_16BITS) - memset(buf,0,todo); - else - memset(buf,0x80,todo); - - return todo; -} - -void VC1_WriteSamples(SBYTE*,ULONG); - -/* Writes 'todo' mixed SBYTES (!!) to 'buf'. It returns the number of SBYTES - actually written to 'buf' (which is rounded to number of samples that fit - into 'todo' bytes). */ -ULONG VC1_WriteBytes(SBYTE* buf,ULONG todo) -{ - if(!vc_softchn) - return VC1_SilenceBytes(buf,todo); - - todo = bytes2samples(todo); - VC1_WriteSamples(buf,todo); - - return samples2bytes(todo); -} - -void VC1_Exit(void) -{ - if(vc_tickbuf) free(vc_tickbuf); - if(vinf) free(vinf); - if(Samples) free(Samples); - - vc_tickbuf = NULL; - vinf = NULL; - Samples = NULL; - - VC_SetupPointers(); -} - -UWORD VC1_VoiceGetVolume(UBYTE voice) -{ - return vinf[voice].vol; -} - -ULONG VC1_VoiceGetPanning(UBYTE voice) -{ - return vinf[voice].pan; -} - -void VC1_VoiceSetFrequency(UBYTE voice,ULONG frq) -{ - vinf[voice].frq=frq; -} - -ULONG VC1_VoiceGetFrequency(UBYTE voice) -{ - return vinf[voice].frq; -} - -void VC1_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags) -{ - vinf[voice].flags = flags; - vinf[voice].handle = handle; - vinf[voice].start = start; - vinf[voice].size = size; - vinf[voice].reppos = reppos; - vinf[voice].repend = repend; - vinf[voice].kick = 1; -} - -void VC1_VoiceStop(UBYTE voice) -{ - vinf[voice].active = 0; -} - -BOOL VC1_VoiceStopped(UBYTE voice) -{ - return(vinf[voice].active==0); -} - -SLONG VC1_VoiceGetPosition(UBYTE voice) -{ - return(vinf[voice].current>>FRACBITS); -} - -void VC1_VoiceSetVolume(UBYTE voice,UWORD vol) -{ - /* protect against clicks if volume variation is too high */ - if(abs((int)vinf[voice].vol-(int)vol)>32) - vinf[voice].rampvol=CLICK_BUFFER; - vinf[voice].vol=vol; -} - -void VC1_VoiceSetPanning(UBYTE voice,ULONG pan) -{ - /* protect against clicks if panning variation is too high */ - if(abs((int)vinf[voice].pan-(int)pan)>48) - vinf[voice].rampvol=CLICK_BUFFER; - vinf[voice].pan=pan; -} - -/*========== External mixer interface */ - -void VC1_SampleUnload(SWORD handle) -{ - if (Samples && handlesample; - int handle; - ULONG t, length,loopstart,loopend; - - if(type==MD_HARDWARE) return -1; - - /* Find empty slot to put sample address in */ - for(handle=0;handleloopend > s->length) - s->loopend = s->length; - if (s->loopstart >= s->loopend) - s->flags &= ~SF_LOOP; - - length = s->length; - loopstart = s->loopstart; - loopend = s->loopend; - - /* Fix loops */ - if (((loopend-loopstart)>2) && (loopstart > loopend) && (loopstart>length)) - { - loopstart /= 2; - } - - SL_SampleSigned(sload); - SL_Sample8to16(sload); - - if(!(Samples[handle]=(SWORD*)_mm_malloc((length+20)<<1))) { - _mm_errno = MMERR_SAMPLE_TOO_BIG; - return -1; - } - - /* read sample into buffer */ - if (SL_Load(Samples[handle],sload,length)) - return -1; - - /* Unclick sample */ - if(s->flags & SF_LOOP) { - if(s->flags & SF_BIDI) - for(t=0;t<16;t++) - Samples[handle][loopend+t]=Samples[handle][(loopend-t)-1]; - else - for(t=0;t<16;t++) - Samples[handle][loopend+t]=Samples[handle][t+loopstart]; - } else - for(t=0;t<16;t++) - Samples[handle][t+length]=0; - - return handle; -} - -ULONG VC1_SampleSpace(int type) -{ - return vc_memory; -} - -ULONG VC1_SampleLength(int type,SAMPLE* s) -{ - if (!s) return 0; - - return (s->length*((s->flags&SF_16BITS)?2:1))+16; -} - -ULONG VC1_VoiceRealVolume(UBYTE voice) -{ - ULONG i,s,size; - int k,j; - SWORD *smp; - SLONG t; - - t = vinf[voice].current>>FRACBITS; - if(!vinf[voice].active) return 0; - - s = vinf[voice].handle; - size = vinf[voice].size; - - i=64; t-=64; k=0; j=0; - if(i>size) i = size; - if(t<0) t = 0; - if(t+i > size) t = size-i; - - i &= ~1; /* make sure it's EVEN. */ - - smp = &Samples[s][t]; - for(;i;i--,smp++) { - if(k<*smp) k = *smp; - if(j>*smp) j = *smp; - } - return abs(k-j); -} - -#endif - -#endif - -/* ex:set ts=4: */ diff --git a/music.c b/music.c index db039cd1..c345baa0 100644 --- a/music.c +++ b/music.c @@ -1199,37 +1199,13 @@ int Mix_SetMusicCMD(const char *command) int Mix_SetSynchroValue(int i) { - if ( music_playing && ! music_stopped ) { - switch (music_playing->type) { -#ifdef MOD_MUSIC - case MUS_MOD: - return MOD_SetSynchroValue(i); - break; -#endif - default: - return(-1); - break; - } - return(-1); - } + /* Not supported by any players at this time */ return(-1); } int Mix_GetSynchroValue(void) { - if ( music_playing && ! music_stopped ) { - switch (music_playing->type) { -#ifdef MOD_MUSIC - case MUS_MOD: - return MOD_GetSynchroValue(); - break; -#endif - default: - return(-1); - break; - } - return(-1); - } + /* Not supported by any players at this time */ return(-1); } diff --git a/music_mod.c b/music_mod.c index 549ac6ce..6544ca7b 100644 --- a/music_mod.c +++ b/music_mod.c @@ -27,25 +27,11 @@ /* This file supports MOD tracker music streams */ #include "SDL_mixer.h" -/*#include "dynamic_mod.h"*/ +#include "dynamic_mod.h" #include "music_mod.h" #include "mikmod.h" -#if defined(LIBMIKMOD_VERSION) /* libmikmod 3.1.8 */ -#define UNIMOD MODULE -#define MikMod_Init() MikMod_Init(NULL) -#define MikMod_LoadSong(a,b) Player_Load(a,b,0) -#ifndef LIBMIKMOD_MUSIC -#define MikMod_LoadSongRW(a,b) Player_LoadRW(a,b,0) -#endif -#define MikMod_FreeSong Player_Free - extern int MikMod_errno; -#else /* old MikMod 3.0.3 */ -#define MikMod_strerror(x) _mm_errmsg[x]) -#define MikMod_errno _mm_errno -#endif - #define SDL_SURROUND #ifdef SDL_SURROUND #define MAX_OUTPUT_CHANNELS 6 @@ -60,14 +46,16 @@ static Uint16 current_output_format; static int music_swap8; static int music_swap16; -/* Initialize the Ogg Vorbis player, with the given mixer settings +/* Initialize the MOD player, with the given mixer settings This function returns 0, or -1 if there was an error. */ int MOD_init(SDL_AudioSpec *mixerfmt) { -#ifdef LIBMIKMOD_MUSIC CHAR *list; -#endif + + if ( Mix_InitMOD() < 0 ) { + return NULL; + } /* Set the MikMod music format */ music_swap8 = 0; @@ -79,7 +67,7 @@ int MOD_init(SDL_AudioSpec *mixerfmt) if ( mixerfmt->format == AUDIO_S8 ) { music_swap8 = 1; } - md_mode = 0; + *mikmod.md_mode = 0; } break; @@ -93,7 +81,7 @@ int MOD_init(SDL_AudioSpec *mixerfmt) #endif music_swap16 = 1; } - md_mode = DMODE_16BITS; + *mikmod.md_mode = DMODE_16BITS; } break; @@ -109,32 +97,31 @@ int MOD_init(SDL_AudioSpec *mixerfmt) Mix_SetError("Hardware uses more channels than mixerfmt"); return -1; } - md_mode |= DMODE_STEREO; + *mikmod.md_mode |= DMODE_STEREO; } - md_mixfreq = mixerfmt->freq; - md_device = 0; - md_volume = 96; - md_musicvolume = 128; - md_sndfxvolume = 128; - md_pansep = 128; - md_reverb = 0; - md_mode |= DMODE_HQMIXER|DMODE_SOFT_MUSIC|DMODE_SURROUND; -#ifdef LIBMIKMOD_MUSIC - list = MikMod_InfoDriver(); + *mikmod.md_mixfreq = mixerfmt->freq; + *mikmod.md_device = 0; + *mikmod.md_volume = 96; + *mikmod.md_musicvolume = 128; + *mikmod.md_sndfxvolume = 128; + *mikmod.md_pansep = 128; + *mikmod.md_reverb = 0; + *mikmod.md_mode |= DMODE_HQMIXER|DMODE_SOFT_MUSIC|DMODE_SURROUND; + + list = mikmod.MikMod_InfoDriver(); if ( list ) free(list); else -#endif - MikMod_RegisterDriver(&drv_nos); -#ifdef LIBMIKMOD_MUSIC - list = MikMod_InfoLoader(); + mikmod.MikMod_RegisterDriver(mikmod.drv_nos); + + list = mikmod.MikMod_InfoLoader(); if ( list ) free(list); else -#endif - MikMod_RegisterAllLoaders(); - if ( MikMod_Init() ) { - Mix_SetError("%s", MikMod_strerror(MikMod_errno)); + mikmod.MikMod_RegisterAllLoaders(); + + if ( mikmod.MikMod_Init(NULL) ) { + Mix_SetError("%s", mikmod.MikMod_strerror(*mikmod.MikMod_errno)); return -1; } @@ -144,17 +131,14 @@ int MOD_init(SDL_AudioSpec *mixerfmt) /* Uninitialize the music players */ void MOD_exit(void) { - MikMod_Exit(); -#ifndef LIBMIKMOD_MUSIC - MikMod_UnregisterAllLoaders(); - MikMod_UnregisterAllDrivers(); -#endif + mikmod.MikMod_Exit(); + Mix_QuitMOD(); } /* Set the volume for a MOD stream */ void MOD_setvolume(MODULE *music, int volume) { - Player_SetVolume((SWORD)volume); + mikmod.Player_SetVolume((SWORD)volume); } /* Load a MOD stream from the given file */ @@ -172,7 +156,6 @@ MODULE *MOD_new(const char *file) } -#ifdef LIBMIKMOD_MUSIC typedef struct { MREADER mr; @@ -183,42 +166,37 @@ typedef struct BOOL LMM_Seek(struct MREADER *mr,long to,int dir) { - int at; - LMM_MREADER* lmmmr=(LMM_MREADER*)mr; - if(dir==SEEK_SET) - to+=lmmmr->offset; - at=SDL_RWseek(lmmmr->rw, to, dir); - return atoffset; + LMM_MREADER* lmmmr = (LMM_MREADER*)mr; + if ( dir == SEEK_SET ) { + to += lmmmr->offset; + } + return (SDL_RWseek(lmmmr->rw, to, dir) < lmmmr->offset); } long LMM_Tell(struct MREADER *mr) { - int at; - LMM_MREADER* lmmmr=(LMM_MREADER*)mr; - at=SDL_RWtell(lmmmr->rw)-lmmmr->offset; - return at; + LMM_MREADER* lmmmr = (LMM_MREADER*)mr; + return SDL_RWtell(lmmmr->rw) - lmmmr->offset; } BOOL LMM_Read(struct MREADER *mr,void *buf,size_t sz) { - int got; - LMM_MREADER* lmmmr=(LMM_MREADER*)mr; - got=SDL_RWread(lmmmr->rw, buf, sz, 1); - return got; + LMM_MREADER* lmmmr = (LMM_MREADER*)mr; + return SDL_RWread(lmmmr->rw, buf, sz, 1); } int LMM_Get(struct MREADER *mr) { unsigned char c; - int i=EOF; - LMM_MREADER* lmmmr=(LMM_MREADER*)mr; - if(SDL_RWread(lmmmr->rw,&c,1,1)) - i=c; - return i; + LMM_MREADER* lmmmr = (LMM_MREADER*)mr; + if ( SDL_RWread(lmmmr->rw, &c, 1, 1) ) { + return c; + } + return EOF; } BOOL LMM_Eof(struct MREADER *mr) { int offset; - LMM_MREADER* lmmmr=(LMM_MREADER*)mr; - offset=LMM_Tell(mr); - return offset>=lmmmr->eof; + LMM_MREADER* lmmmr = (LMM_MREADER*)mr; + offset = LMM_Tell(mr); + return offset >= lmmmr->eof; } MODULE *MikMod_LoadSongRW(SDL_RWops *rw, int maxchan) { @@ -228,23 +206,22 @@ MODULE *MikMod_LoadSongRW(SDL_RWops *rw, int maxchan) 0, 0 }; - MODULE *m; + lmmmr.offset = SDL_RWtell(rw); + SDL_RWseek(rw, 0, SEEK_END); + lmmmr.eof = SDL_RWtell(rw); + SDL_RWseek(rw, lmmmr.offset, SEEK_SET); lmmmr.rw = rw; - lmmmr.offset=SDL_RWtell(rw); - SDL_RWseek(rw,0,SEEK_END); - lmmmr.eof=SDL_RWtell(rw); - SDL_RWseek(rw,lmmmr.offset,SEEK_SET); - m=Player_LoadGeneric((MREADER*)&lmmmr,maxchan,0); - return m; + return mikmod.Player_LoadGeneric((MREADER*)&lmmmr, maxchan, 0); } -#endif /* Load a MOD stream from an SDL_RWops object */ MODULE *MOD_new_RW(SDL_RWops *rw) { - MODULE *module = MikMod_LoadSongRW(rw,64); + MODULE *module; + + module = MikMod_LoadSongRW(rw,64); if (!module) { - Mix_SetError("%s", MikMod_strerror(MikMod_errno)); + Mix_SetError("%s", mikmod.MikMod_strerror(*mikmod.MikMod_errno)); return NULL; } @@ -263,13 +240,13 @@ to query the status of the song or set trigger actions. Hum. */ /* Start playback of a given MOD stream */ void MOD_play(MODULE *music) { - Player_Start(music); + mikmod.Player_Start(music); } /* Return non-zero if a stream is currently playing */ int MOD_playing(MODULE *music) { - return Player_Active(); + return mikmod.Player_Active(); } /* Play some of a stream previously started with MOD_play() */ @@ -280,7 +257,7 @@ int MOD_playAudio(MODULE *music, Uint8 *stream, int len) int i; Uint8 *src, *dst; - VC_WriteBytes((SBYTE *)stream, small_len); + mikmod.VC_WriteBytes((SBYTE *)stream, small_len); /* and extend to len by copying channels */ src = stream + small_len; dst = stream + len; @@ -322,7 +299,7 @@ int MOD_playAudio(MODULE *music, Uint8 *stream, int len) break; } } else { - VC_WriteBytes((SBYTE *)stream, len); + mikmod.VC_WriteBytes((SBYTE *)stream, len); } if ( music_swap8 ) { Uint8 *dst; @@ -351,53 +328,19 @@ int MOD_playAudio(MODULE *music, Uint8 *stream, int len) /* Stop playback of a stream previously started with MOD_play() */ void MOD_stop(MODULE *music) { - Player_Stop(); + mikmod.Player_Stop(); } /* Close the given MOD stream */ void MOD_delete(MODULE *music) { - MikMod_FreeSong(music); + mikmod.Player_Free(music); } /* Jump (seek) to a given position (time is in seconds) */ void MOD_jump_to_time(MODULE *music, double time) { - Player_SetPosition((UWORD)time); -} - -#ifdef LIBMIKMOD_MUSIC -static int _pl_synchro_value; -void Player_SetSynchroValue(int i) -{ - fprintf(stderr,"SDL_mixer: Player_SetSynchroValue is not supported.\n"); - _pl_synchro_value = i; -} - -int Player_GetSynchroValue(void) -{ - fprintf(stderr,"SDL_mixer: Player_GetSynchroValue is not supported.\n"); - return _pl_synchro_value; -} -#endif - -/* Set the MOD synchronization value */ -int MOD_SetSynchroValue(int i) -{ - if ( ! Player_Active() ) { - return(-1); - } - Player_SetSynchroValue(i); - return 0; -} - -/* Get the MOD synchronization value */ -int MOD_GetSynchroValue(void) -{ - if ( ! Player_Active() ) { - return(-1); - } - return Player_GetSynchroValue(); + mikmod.Player_SetPosition((UWORD)time); } #endif /* MOD_MUSIC */ diff --git a/music_mod.h b/music_mod.h index d7c79e01..3d96db21 100644 --- a/music_mod.h +++ b/music_mod.h @@ -63,10 +63,4 @@ extern void MOD_delete(struct MODULE *music); /* Jump (seek) to a given position (time is in seconds) */ extern void MOD_jump_to_time(struct MODULE *music, double time); -/* Set the MOD synchronization value */ -extern int MOD_SetSynchroValue(int i); - -/* Get the MOD synchronization value */ -extern int MOD_GetSynchroValue(void); - #endif /* MOD_MUSIC */