adplug-2.2.1+dfsg3/ 0000755 0001750 0001750 00000000000 11540422213 013256 5 ustar gregoa gregoa adplug-2.2.1+dfsg3/Makefile.am 0000644 0001750 0001750 00000000265 10406217645 015330 0 ustar gregoa gregoa SUBDIRS = src doc adplugdb test
EXTRA_DIST = adplug.spec adplug.qpg BUGS adplug.pc.in
AUTOMAKE_OPTIONS = dist-bzip2
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = adplug.pc
adplug-2.2.1+dfsg3/depcomp 0000755 0001750 0001750 00000044267 11356523226 014663 0 ustar gregoa gregoa #! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2009-04-28.21; # UTC
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
# Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva .
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to .
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u="sed s,\\\\\\\\,/,g"
depmode=msvisualcpp
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
# Add `dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mechanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
adplug-2.2.1+dfsg3/missing 0000755 0001750 0001750 00000026233 11356523225 014675 0 ustar gregoa gregoa #! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2009-04-28.21; # UTC
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
# 2008, 2009 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard , 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case $1 in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
autom4te touch the output file, or create a stub one
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
\`g' are ignored when checking the name.
Send bug reports to ."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# normalize program name to check for.
program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program). This is about non-GNU programs, so use $1 not
# $program.
case $1 in
lex*|yacc*)
# Not GNU programs, they don't have --version.
;;
tar*)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case $program in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case $f in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te*)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison*|yacc*)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if test ! -f y.tab.h; then
echo >y.tab.h
fi
if test ! -f y.tab.c; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex*|flex*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if test $# -ne 1; then
eval LASTARG="\${$#}"
case $LASTARG in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if test -f "$SRCFILE"; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if test ! -f lex.yy.c; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit $?
fi
;;
makeinfo*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n "$sed_output"`
test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '
/^@setfilename/{
s/.* \([^ ]*\) *$/\1/
p
q
}' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar*)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case $firstarg in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case $firstarg in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:
adplug-2.2.1+dfsg3/Makefile.in 0000644 0001750 0001750 00000057506 11356523226 015353 0 ustar gregoa gregoa # Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/adplug.pc.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
TODO config.guess config.sub depcomp install-sh ltmain.sh \
missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES = adplug.pc
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-dvi-recursive install-exec-recursive \
install-html-recursive install-info-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
DATA = $(pkgconfig_DATA)
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
distdir dist dist-all distcheck
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d "$(distdir)" \
|| { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr "$(distdir)"; }; }
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETOPT_SOURCES = @GETOPT_SOURCES@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libbinio_CFLAGS = @libbinio_CFLAGS@
libbinio_LIBS = @libbinio_LIBS@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = src doc adplugdb test
EXTRA_DIST = adplug.spec adplug.qpg BUGS adplug.pc.in
AUTOMAKE_OPTIONS = dist-bzip2
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = adplug.pc
all: all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
adplug.pc: $(top_builddir)/config.status $(srcdir)/adplug.pc.in
cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
install-pkgconfigDATA: $(pkgconfig_DATA)
@$(NORMAL_INSTALL)
test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
$(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
done
uninstall-pkgconfigDATA:
@$(NORMAL_UNINSTALL)
@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
$(RECURSIVE_CLEAN_TARGETS):
@fail= failcom='exit 1'; \
for f in x $$MAKEFLAGS; do \
case $$f in \
*=* | --[!k]*);; \
*k*) failcom='fail=yes';; \
esac; \
done; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-lzma: distdir
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
$(am__remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
$(am__remove_distdir)
dist-tarZ: distdir
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lzma*) \
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@$(am__cd) '$(distuninstallcheck_dir)' \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(DATA)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool \
distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am: install-pkgconfigDATA
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-pkgconfigDATA
.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
install-am install-strip tags-recursive
.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
all all-am am--refresh check check-am clean clean-generic \
clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
distcheck distclean distclean-generic distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-recursive uninstall uninstall-am \
uninstall-pkgconfigDATA
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
adplug-2.2.1+dfsg3/AUTHORS 0000644 0001750 0001750 00000005223 11315604776 014350 0 ustar gregoa gregoa AdPlug is copyright (C) 1999 - 2008 Simon Peter , et al.
All library code is written by Simon Peter, except the parts listed below.
Additional Credits:
-------------------
Phil Hassey :
- Player development for the following formats:
- MID: MIDI Audio File Format
- CMF: Creative Music File Format
- SCI: Sierra's AdLib Audio File Format
- LAA: LucasArts AdLib Audio File Format
Marc Winterrowd :
- M: Origin Music player development
Tatsuyuki Satoh :
- First YM3812 emulator development
Ken Silverman :
- Second YM3812 emulator development
Death Adder :
- provided many file format specifications
- moral support ;)
Mamiya :
- support for .SAT (early Surprise! Adlib Tracker) files
Akintunde Omitowoju :
- ROL: AdLib Visual Composer player development
Nikita V. Kalaganov :
- Player development:
- XAD: shell player and custom module formats
- Protracker loader development:
- SNG: Faust Music Creator
- MAD: Mlat Adlib Tracker
- CFF: BoomTracker 4.0
- DTM: DeFy Adlib Tracker
- Scream Tracker 3 loader development:
- DMO: Twin TrackPlayer
- XMS-Tracker detection support in AMD loader
Sjoerd van der Berg :
- DRO: DOSBox Raw OPL player development
Goetz Waschk :
- Mandrake Linux packages
- Red Hat RPM spec files
Mike Gorchak :
- QNX packages
- QNX qpg file
Tyler Montbriand :
- AMD64 (x86_64) fixes
- ROL: Added pitch handling
Borg Number One [ Borg No. One ] :
- Many thanks for the huge amount of work to find the original
author (Andras Molnar) of the LOUDNESS Sound System and managing
to get the sources from him.
Matthew Gambrell :
- Enhancements to the DRO (DOSBox Raw OPL) format
- Added dual OPL2 and OPL3 support
BSPAL ,
Palxex :
- RIX: Softstar RIX OPL Music Format player development
Torbjorn Andersson,
Johannes Schickel 'lordhoto' :
- Development of original ADL (Westwood ADL File Format) player in
ScummVM, which has been adapted for AdPlug.
Adam Nielsen :
- Fixes for CMF rhythm mode support in original player
- Added entirely new (more accurate) CMF player
- Added surround/harmonic synth
Dennis Lindroos :
- JBM: JBM Adlib Music format player development
adplug-2.2.1+dfsg3/INSTALL 0000644 0001750 0001750 00000036332 11356523226 014331 0 ustar gregoa gregoa Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.
adplug-2.2.1+dfsg3/src/ 0000755 0001750 0001750 00000000000 11356523234 014057 5 ustar gregoa gregoa adplug-2.2.1+dfsg3/src/lds.cpp 0000644 0001750 0001750 00000050126 10126327547 015354 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2004 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* lds.cpp - LOUDNESS Player by Simon Peter
*/
#include
#include "lds.h"
#include "debug.h"
// Note frequency table (16 notes / octave)
const unsigned short CldsPlayer::frequency[] = {
343, 344, 345, 347, 348, 349, 350, 352, 353, 354, 356, 357, 358,
359, 361, 362, 363, 365, 366, 367, 369, 370, 371, 373, 374, 375,
377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 391, 392, 393,
395, 396, 398, 399, 401, 402, 403, 405, 406, 408, 409, 411, 412,
414, 415, 417, 418, 420, 421, 423, 424, 426, 427, 429, 430, 432,
434, 435, 437, 438, 440, 442, 443, 445, 446, 448, 450, 451, 453,
454, 456, 458, 459, 461, 463, 464, 466, 468, 469, 471, 473, 475,
476, 478, 480, 481, 483, 485, 487, 488, 490, 492, 494, 496, 497,
499, 501, 503, 505, 506, 508, 510, 512, 514, 516, 518, 519, 521,
523, 525, 527, 529, 531, 533, 535, 537, 538, 540, 542, 544, 546,
548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, 571, 573,
575, 577, 579, 581, 583, 585, 587, 589, 591, 594, 596, 598, 600,
602, 604, 607, 609, 611, 613, 615, 618, 620, 622, 624, 627, 629,
631, 633, 636, 638, 640, 643, 645, 647, 650, 652, 654, 657, 659,
662, 664, 666, 669, 671, 674, 676, 678, 681, 683
};
// Vibrato (sine) table
const unsigned char CldsPlayer::vibtab[] = {
0, 13, 25, 37, 50, 62, 74, 86, 98, 109, 120, 131, 142, 152, 162,
171, 180, 189, 197, 205, 212, 219, 225, 231, 236, 240, 244, 247,
250, 252, 254, 255, 255, 255, 254, 252, 250, 247, 244, 240, 236,
231, 225, 219, 212, 205, 197, 189, 180, 171, 162, 152, 142, 131,
120, 109, 98, 86, 74, 62, 50, 37, 25, 13
};
// Tremolo (sine * sine) table
const unsigned char CldsPlayer::tremtab[] = {
0, 0, 1, 1, 2, 4, 5, 7, 10, 12, 15, 18, 21, 25, 29, 33, 37, 42, 47,
52, 57, 62, 67, 73, 79, 85, 90, 97, 103, 109, 115, 121, 128, 134,
140, 146, 152, 158, 165, 170, 176, 182, 188, 193, 198, 203, 208,
213, 218, 222, 226, 230, 234, 237, 240, 243, 245, 248, 250, 251,
253, 254, 254, 255, 255, 255, 254, 254, 253, 251, 250, 248, 245,
243, 240, 237, 234, 230, 226, 222, 218, 213, 208, 203, 198, 193,
188, 182, 176, 170, 165, 158, 152, 146, 140, 134, 127, 121, 115,
109, 103, 97, 90, 85, 79, 73, 67, 62, 57, 52, 47, 42, 37, 33, 29,
25, 21, 18, 15, 12, 10, 7, 5, 4, 2, 1, 1, 0
};
// 'maxsound' is maximum number of patches (instruments)
// 'maxpos' is maximum number of entries in position list (orderlist)
const unsigned short CldsPlayer::maxsound = 0x3f, CldsPlayer::maxpos = 0xff;
/*** public methods *************************************/
CldsPlayer::CldsPlayer(Copl *newopl)
: CPlayer(newopl), soundbank(0), positions(0), patterns(0)
{
}
CldsPlayer::~CldsPlayer()
{
if(soundbank) delete [] soundbank;
if(positions) delete [] positions;
if(patterns) delete [] patterns;
}
bool CldsPlayer::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f;
unsigned int i, j;
SoundBank *sb;
// file validation section (actually just an extension check)
if(!fp.extension(filename, ".lds")) return false;
f = fp.open(filename); if(!f) return false;
// file load section (header)
mode = f->readInt(1);
if(mode > 2) { fp.close(f); return false; }
speed = f->readInt(2);
tempo = f->readInt(1);
pattlen = f->readInt(1);
for(i = 0; i < 9; i++) chandelay[i] = f->readInt(1);
regbd = f->readInt(1);
// load patches
numpatch = f->readInt(2);
soundbank = new SoundBank[numpatch];
for(i = 0; i < numpatch; i++) {
sb = &soundbank[i];
sb->mod_misc = f->readInt(1); sb->mod_vol = f->readInt(1);
sb->mod_ad = f->readInt(1); sb->mod_sr = f->readInt(1);
sb->mod_wave = f->readInt(1); sb->car_misc = f->readInt(1);
sb->car_vol = f->readInt(1); sb->car_ad = f->readInt(1);
sb->car_sr = f->readInt(1); sb->car_wave = f->readInt(1);
sb->feedback = f->readInt(1); sb->keyoff = f->readInt(1);
sb->portamento = f->readInt(1); sb->glide = f->readInt(1);
sb->finetune = f->readInt(1); sb->vibrato = f->readInt(1);
sb->vibdelay = f->readInt(1); sb->mod_trem = f->readInt(1);
sb->car_trem = f->readInt(1); sb->tremwait = f->readInt(1);
sb->arpeggio = f->readInt(1);
for(j = 0; j < 12; j++) sb->arp_tab[j] = f->readInt(1);
sb->start = f->readInt(2); sb->size = f->readInt(2);
sb->fms = f->readInt(1); sb->transp = f->readInt(2);
sb->midinst = f->readInt(1); sb->midvelo = f->readInt(1);
sb->midkey = f->readInt(1); sb->midtrans = f->readInt(1);
sb->middum1 = f->readInt(1); sb->middum2 = f->readInt(1);
}
// load positions
numposi = f->readInt(2);
positions = new Position[9 * numposi];
for(i = 0; i < numposi; i++)
for(j = 0; j < 9; j++) {
/*
* patnum is a pointer inside the pattern space, but patterns are 16bit
* word fields anyway, so it ought to be an even number (hopefully) and
* we can just divide it by 2 to get our array index of 16bit words.
*/
positions[i * 9 + j].patnum = f->readInt(2) / 2;
positions[i * 9 + j].transpose = f->readInt(1);
}
AdPlug_LogWrite("CldsPlayer::load(\"%s\",fp): loading LOUDNESS file: mode = "
"%d, pattlen = %d, numpatch = %d, numposi = %d\n",
filename.c_str(), mode, pattlen, numpatch, numposi);
// load patterns
f->ignore(2); // ignore # of digital sounds (not played by this player)
patterns = new unsigned short[(fp.filesize(f) - f->pos()) / 2 + 1];
for(i = 0; !f->eof(); i++)
patterns[i] = f->readInt(2);
fp.close(f);
rewind(0);
return true;
}
bool CldsPlayer::update()
{
unsigned short comword, freq, octave, chan, tune, wibc, tremc, arpreg;
bool vbreak;
unsigned char level, regnum, comhi, comlo;
int i;
Channel *c;
if(!playing) return false;
// handle fading
if(fadeonoff)
if(fadeonoff <= 128) {
if(allvolume > fadeonoff || allvolume == 0)
allvolume -= fadeonoff;
else {
allvolume = 1;
fadeonoff = 0;
if(hardfade != 0) {
playing = false;
hardfade = 0;
for(i = 0; i < 9; i++)
channel[i].keycount = 1;
}
}
} else
if(((allvolume + (0x100 - fadeonoff)) & 0xff) <= mainvolume)
allvolume += 0x100 - fadeonoff;
else {
allvolume = mainvolume;
fadeonoff = 0;
}
// handle channel delay
for(chan = 0; chan < 9; chan++) {
c = &channel[chan];
if(c->chancheat.chandelay)
if(!(--c->chancheat.chandelay))
playsound(c->chancheat.sound, chan, c->chancheat.high);
}
// handle notes
if(!tempo_now) {
vbreak = false;
for(chan = 0; chan < 9; chan++) {
c = &channel[chan];
if(!c->packwait) {
unsigned short patnum = positions[posplay * 9 + chan].patnum;
unsigned char transpose = positions[posplay * 9 + chan].transpose;
comword = patterns[patnum + c->packpos];
comhi = comword >> 8; comlo = comword & 0xff;
if(comword)
if(comhi == 0x80)
c->packwait = comlo;
else
if(comhi >= 0x80) {
switch(comhi) {
case 0xff:
c->volcar = (((c->volcar & 0x3f) * comlo) >> 6) & 0x3f;
if(fmchip[0xc0 + chan] & 1)
c->volmod = (((c->volmod & 0x3f) * comlo) >> 6) & 0x3f;
break;
case 0xfe:
tempo = comword & 0x3f;
break;
case 0xfd:
c->nextvol = comlo;
break;
case 0xfc:
playing = false;
// in real player there's also full keyoff here, but we don't need it
break;
case 0xfb:
c->keycount = 1;
break;
case 0xfa:
vbreak = true;
jumppos = (posplay + 1) & maxpos;
break;
case 0xf9:
vbreak = true;
jumppos = comlo & maxpos;
jumping = 1;
if(jumppos < posplay) songlooped = true;
break;
case 0xf8:
c->lasttune = 0;
break;
case 0xf7:
c->vibwait = 0;
// PASCAL: c->vibspeed = ((comlo >> 4) & 15) + 2;
c->vibspeed = (comlo >> 4) + 2;
c->vibrate = (comlo & 15) + 1;
break;
case 0xf6:
c->glideto = comlo;
break;
case 0xf5:
c->finetune = comlo;
break;
case 0xf4:
if(!hardfade) {
allvolume = mainvolume = comlo;
fadeonoff = 0;
}
break;
case 0xf3:
if(!hardfade) fadeonoff = comlo;
break;
case 0xf2:
c->trmstay = comlo;
break;
case 0xf1: // panorama
case 0xf0: // progch
// MIDI commands (unhandled)
AdPlug_LogWrite("CldsPlayer(): not handling MIDI command 0x%x, "
"value = 0x%x\n", comhi);
break;
default:
if(comhi < 0xa0)
c->glideto = comhi & 0x1f;
else
AdPlug_LogWrite("CldsPlayer(): unknown command 0x%x encountered!"
" value = 0x%x\n", comhi, comlo);
break;
}
} else {
unsigned char sound;
unsigned short high;
signed char transp = transpose & 127;
/*
* Originally, in assembler code, the player first shifted
* logically left the transpose byte by 1 and then shifted
* arithmetically right the same byte to achieve the final,
* signed transpose value. Since we can't do arithmetic shifts
* in C, we just duplicate the 7th bit into the 8th one and
* discard the 8th one completely.
*/
if(transpose & 64) transp |= 128;
if(transpose & 128) {
sound = (comlo + transp) & maxsound;
high = comhi << 4;
} else {
sound = comlo & maxsound;
high = (comhi + transp) << 4;
}
/*
PASCAL:
sound = comlo & maxsound;
high = (comhi + (((transpose + 0x24) & 0xff) - 0x24)) << 4;
*/
if(!chandelay[chan])
playsound(sound, chan, high);
else {
c->chancheat.chandelay = chandelay[chan];
c->chancheat.sound = sound;
c->chancheat.high = high;
}
}
c->packpos++;
} else
c->packwait--;
}
tempo_now = tempo;
/*
The continue table is updated here, but this is only used in the
original player, which can be paused in the middle of a song and then
unpaused. Since AdPlug does all this for us automatically, we don't
have a continue table here. The continue table update code is noted
here for reference only.
if(!pattplay) {
conttab[speed & maxcont].position = posplay & 0xff;
conttab[speed & maxcont].tempo = tempo;
}
*/
pattplay++;
if(vbreak) {
pattplay = 0;
for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0;
posplay = jumppos;
} else
if(pattplay >= pattlen) {
pattplay = 0;
for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0;
posplay = (posplay + 1) & maxpos;
}
} else
tempo_now--;
// make effects
for(chan = 0; chan < 9; chan++) {
c = &channel[chan];
regnum = op_table[chan];
if(c->keycount > 0) {
if(c->keycount == 1)
setregs_adv(0xb0 + chan, 0xdf, 0);
c->keycount--;
}
// arpeggio
if(c->arp_size == 0)
arpreg = 0;
else {
arpreg = c->arp_tab[c->arp_pos] << 4;
if(arpreg == 0x800) {
if(c->arp_pos > 0) c->arp_tab[0] = c->arp_tab[c->arp_pos - 1];
c->arp_size = 1; c->arp_pos = 0;
arpreg = c->arp_tab[0] << 4;
}
if(c->arp_count == c->arp_speed) {
c->arp_pos++;
if(c->arp_pos >= c->arp_size) c->arp_pos = 0;
c->arp_count = 0;
} else
c->arp_count++;
}
// glide & portamento
if(c->lasttune && (c->lasttune != c->gototune)) {
if(c->lasttune > c->gototune) {
if(c->lasttune - c->gototune < c->portspeed)
c->lasttune = c->gototune;
else
c->lasttune -= c->portspeed;
} else {
if(c->gototune - c->lasttune < c->portspeed)
c->lasttune = c->gototune;
else
c->lasttune += c->portspeed;
}
if(arpreg >= 0x800)
arpreg = c->lasttune - (arpreg ^ 0xff0) - 16;
else
arpreg += c->lasttune;
freq = frequency[arpreg % (12 * 16)];
octave = arpreg / (12 * 16) - 1;
setregs(0xa0 + chan, freq & 0xff);
setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
} else {
// vibrato
if(!c->vibwait) {
if(c->vibrate) {
wibc = vibtab[c->vibcount & 0x3f] * c->vibrate;
if((c->vibcount & 0x40) == 0)
tune = c->lasttune + (wibc >> 8);
else
tune = c->lasttune - (wibc >> 8);
if(arpreg >= 0x800)
tune = tune - (arpreg ^ 0xff0) - 16;
else
tune += arpreg;
freq = frequency[tune % (12 * 16)];
octave = tune / (12 * 16) - 1;
setregs(0xa0 + chan, freq & 0xff);
setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
c->vibcount += c->vibspeed;
} else
if(c->arp_size != 0) { // no vibrato, just arpeggio
if(arpreg >= 0x800)
tune = c->lasttune - (arpreg ^ 0xff0) - 16;
else
tune = c->lasttune + arpreg;
freq = frequency[tune % (12 * 16)];
octave = tune / (12 * 16) - 1;
setregs(0xa0 + chan, freq & 0xff);
setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
}
} else { // no vibrato, just arpeggio
c->vibwait--;
if(c->arp_size != 0) {
if(arpreg >= 0x800)
tune = c->lasttune - (arpreg ^ 0xff0) - 16;
else
tune = c->lasttune + arpreg;
freq = frequency[tune % (12 * 16)];
octave = tune / (12 * 16) - 1;
setregs(0xa0 + chan, freq & 0xff);
setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
}
}
}
// tremolo (modulator)
if(!c->trmwait) {
if(c->trmrate) {
tremc = tremtab[c->trmcount & 0x7f] * c->trmrate;
if((tremc >> 8) <= (c->volmod & 0x3f))
level = (c->volmod & 0x3f) - (tremc >> 8);
else
level = 0;
if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
setregs_adv(0x40 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f);
else
setregs_adv(0x40 + regnum, 0xc0, level ^ 0x3f);
c->trmcount += c->trmspeed;
} else
if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
else
setregs_adv(0x40 + regnum, 0xc0, (c->volmod ^ 0x3f) & 0x3f);
} else {
c->trmwait--;
if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
}
// tremolo (carrier)
if(!c->trcwait) {
if(c->trcrate) {
tremc = tremtab[c->trccount & 0x7f] * c->trcrate;
if((tremc >> 8) <= (c->volcar & 0x3f))
level = (c->volcar & 0x3f) - (tremc >> 8);
else
level = 0;
if(allvolume != 0)
setregs_adv(0x43 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f);
else
setregs_adv(0x43 + regnum, 0xc0, level ^ 0x3f);
c->trccount += c->trcspeed;
} else
if(allvolume != 0)
setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
else
setregs_adv(0x43 + regnum, 0xc0, (c->volcar ^ 0x3f) & 0x3f);
} else {
c->trcwait--;
if(allvolume != 0)
setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
}
}
return (!playing || songlooped) ? false : true;
}
void CldsPlayer::rewind(int subsong)
{
int i;
// init all with 0
tempo_now = 3; playing = true; songlooped = false;
jumping = fadeonoff = allvolume = hardfade = pattplay = posplay = jumppos =
mainvolume = 0;
memset(channel, 0, sizeof(channel));
memset(fmchip, 0, sizeof(fmchip));
// OPL2 init
opl->init(); // Reset OPL chip
opl->write(1, 0x20);
opl->write(8, 0);
opl->write(0xbd, regbd);
for(i = 0; i < 9; i++) {
opl->write(0x20 + op_table[i], 0);
opl->write(0x23 + op_table[i], 0);
opl->write(0x40 + op_table[i], 0x3f);
opl->write(0x43 + op_table[i], 0x3f);
opl->write(0x60 + op_table[i], 0xff);
opl->write(0x63 + op_table[i], 0xff);
opl->write(0x80 + op_table[i], 0xff);
opl->write(0x83 + op_table[i], 0xff);
opl->write(0xe0 + op_table[i], 0);
opl->write(0xe3 + op_table[i], 0);
opl->write(0xa0 + i, 0);
opl->write(0xb0 + i, 0);
opl->write(0xc0 + i, 0);
}
}
/*** private methods *************************************/
void CldsPlayer::playsound(int inst_number, int channel_number, int tunehigh)
{
Channel *c = &channel[channel_number]; // current channel
SoundBank *i = &soundbank[inst_number]; // current instrument
unsigned int regnum = op_table[channel_number]; // channel's OPL2 register
unsigned char volcalc, octave;
unsigned short freq;
// set fine tune
tunehigh += ((i->finetune + c->finetune + 0x80) & 0xff) - 0x80;
// arpeggio handling
if(!i->arpeggio) {
unsigned short arpcalc = i->arp_tab[0] << 4;
if(arpcalc > 0x800)
tunehigh = tunehigh - (arpcalc ^ 0xff0) - 16;
else
tunehigh += arpcalc;
}
// glide handling
if(c->glideto != 0) {
c->gototune = tunehigh;
c->portspeed = c->glideto;
c->glideto = c->finetune = 0;
return;
}
// set modulator registers
setregs(0x20 + regnum, i->mod_misc);
volcalc = i->mod_vol;
if(!c->nextvol || !(i->feedback & 1))
c->volmod = volcalc;
else
c->volmod = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
if((i->feedback & 1) == 1 && allvolume != 0)
setregs(0x40 + regnum, ((c->volmod & 0xc0) | (((c->volmod & 0x3f) * allvolume) >> 8)) ^ 0x3f);
else
setregs(0x40 + regnum, c->volmod ^ 0x3f);
setregs(0x60 + regnum, i->mod_ad);
setregs(0x80 + regnum, i->mod_sr);
setregs(0xe0 + regnum, i->mod_wave);
// Set carrier registers
setregs(0x23 + regnum, i->car_misc);
volcalc = i->car_vol;
if(!c->nextvol)
c->volcar = volcalc;
else
c->volcar = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
if(allvolume)
setregs(0x43 + regnum, ((c->volcar & 0xc0) | (((c->volcar & 0x3f) * allvolume) >> 8)) ^ 0x3f);
else
setregs(0x43 + regnum, c->volcar ^ 0x3f);
setregs(0x63 + regnum, i->car_ad);
setregs(0x83 + regnum, i->car_sr);
setregs(0xe3 + regnum, i->car_wave);
setregs(0xc0 + channel_number, i->feedback);
setregs_adv(0xb0 + channel_number, 0xdf, 0); // key off
freq = frequency[tunehigh % (12 * 16)];
octave = tunehigh / (12 * 16) - 1;
if(!i->glide) {
if(!i->portamento || !c->lasttune) {
setregs(0xa0 + channel_number, freq & 0xff);
setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
c->lasttune = c->gototune = tunehigh;
} else {
c->gototune = tunehigh;
c->portspeed = i->portamento;
setregs_adv(0xb0 + channel_number, 0xdf, 0x20); // key on
}
} else {
setregs(0xa0 + channel_number, freq & 0xff);
setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
c->lasttune = tunehigh;
c->gototune = tunehigh + ((i->glide + 0x80) & 0xff) - 0x80; // set destination
c->portspeed = i->portamento;
}
if(!i->vibrato)
c->vibwait = c->vibspeed = c->vibrate = 0;
else {
c->vibwait = i->vibdelay;
// PASCAL: c->vibspeed = ((i->vibrato >> 4) & 15) + 1;
c->vibspeed = (i->vibrato >> 4) + 2;
c->vibrate = (i->vibrato & 15) + 1;
}
if(!(c->trmstay & 0xf0)) {
c->trmwait = (i->tremwait & 0xf0) >> 3;
// PASCAL: c->trmspeed = (i->mod_trem >> 4) & 15;
c->trmspeed = i->mod_trem >> 4;
c->trmrate = i->mod_trem & 15;
c->trmcount = 0;
}
if(!(c->trmstay & 0x0f)) {
c->trcwait = (i->tremwait & 15) << 1;
// PASCAL: c->trcspeed = (i->car_trem >> 4) & 15;
c->trcspeed = i->car_trem >> 4;
c->trcrate = i->car_trem & 15;
c->trccount = 0;
}
c->arp_size = i->arpeggio & 15;
c->arp_speed = i->arpeggio >> 4;
memcpy(c->arp_tab, i->arp_tab, 12);
c->keycount = i->keyoff;
c->nextvol = c->glideto = c->finetune = c->vibcount = c->arp_pos = c->arp_count = 0;
}
inline void CldsPlayer::setregs(unsigned char reg, unsigned char val)
{
if(fmchip[reg] == val) return;
fmchip[reg] = val;
opl->write(reg, val);
}
inline void CldsPlayer::setregs_adv(unsigned char reg, unsigned char mask,
unsigned char val)
{
setregs(reg, (fmchip[reg] & mask) | val);
}
adplug-2.2.1+dfsg3/src/adplug.cpp 0000644 0001750 0001750 00000014300 11317274465 016043 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2008 Simon Peter , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* adplug.cpp - CAdPlug utility class, by Simon Peter
*/
#include
#include
#include
#include "adplug.h"
#include "debug.h"
/***** Replayer includes *****/
#include "hsc.h"
#include "amd.h"
#include "a2m.h"
#include "imf.h"
#include "sng.h"
#include "adtrack.h"
#include "bam.h"
#include "cmf.h"
#include "d00.h"
#include "dfm.h"
#include "hsp.h"
#include "ksm.h"
#include "mad.h"
#include "mid.h"
#include "mkj.h"
#include "cff.h"
#include "dmo.h"
#include "s3m.h"
#include "dtm.h"
#include "fmc.h"
#include "mtk.h"
#include "rad.h"
#include "raw.h"
#include "sa2.h"
#include "bmf.h"
#include "flash.h"
#include "hybrid.h"
#include "hyp.h"
#include "psi.h"
#include "rat.h"
#include "lds.h"
#include "u6m.h"
#include "rol.h"
#include "xsm.h"
#include "dro.h"
#include "dro2.h"
#include "msc.h"
#include "rix.h"
#include "adl.h"
#include "jbm.h"
/***** CAdPlug *****/
// List of all players that come with the standard AdPlug distribution
const CPlayerDesc CAdPlug::allplayers[] = {
CPlayerDesc(ChscPlayer::factory, "HSC-Tracker", ".hsc\0"),
CPlayerDesc(CsngPlayer::factory, "SNGPlay", ".sng\0"),
CPlayerDesc(CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"),
CPlayerDesc(Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"),
CPlayerDesc(CadtrackLoader::factory, "Adlib Tracker", ".sng\0"),
CPlayerDesc(CamdLoader::factory, "AMUSIC", ".amd\0"),
CPlayerDesc(CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"),
CPlayerDesc(CcmfPlayer::factory, "Creative Music File", ".cmf\0"),
CPlayerDesc(Cd00Player::factory, "Packed EdLib", ".d00\0"),
CPlayerDesc(CdfmLoader::factory, "Digital-FM", ".dfm\0"),
CPlayerDesc(ChspLoader::factory, "HSC Packed", ".hsp\0"),
CPlayerDesc(CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"),
CPlayerDesc(CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"),
CPlayerDesc(CmidPlayer::factory, "MIDI", ".mid\0.sci\0.laa\0"),
CPlayerDesc(CmkjPlayer::factory, "MKJamz", ".mkj\0"),
CPlayerDesc(CcffLoader::factory, "Boomtracker", ".cff\0"),
CPlayerDesc(CdmoLoader::factory, "TwinTeam", ".dmo\0"),
CPlayerDesc(Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"),
CPlayerDesc(CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"),
CPlayerDesc(CfmcLoader::factory, "Faust Music Creator", ".sng\0"),
CPlayerDesc(CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"),
CPlayerDesc(CradLoader::factory, "Reality Adlib Tracker", ".rad\0"),
CPlayerDesc(CrawPlayer::factory, "RdosPlay RAW", ".raw\0"),
CPlayerDesc(Csa2Loader::factory, "Surprise! Adlib Tracker", ".sat\0.sa2\0"),
CPlayerDesc(CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"),
CPlayerDesc(CxadflashPlayer::factory, "Flash", ".xad\0"),
CPlayerDesc(CxadhybridPlayer::factory, "Hybrid", ".xad\0"),
CPlayerDesc(CxadhypPlayer::factory, "Hypnosis", ".xad\0"),
CPlayerDesc(CxadpsiPlayer::factory, "PSI", ".xad\0"),
CPlayerDesc(CxadratPlayer::factory, "rat", ".xad\0"),
CPlayerDesc(CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"),
CPlayerDesc(Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"),
CPlayerDesc(CrolPlayer::factory, "Adlib Visual Composer", ".rol\0"),
CPlayerDesc(CxsmPlayer::factory, "eXtra Simple Music", ".xsm\0"),
CPlayerDesc(CdroPlayer::factory, "DOSBox Raw OPL v0.1", ".dro\0"),
CPlayerDesc(Cdro2Player::factory, "DOSBox Raw OPL v2.0", ".dro\0"),
CPlayerDesc(CmscPlayer::factory, "Adlib MSC Player", ".msc\0"),
CPlayerDesc(CrixPlayer::factory, "Softstar RIX OPL Music", ".rix\0"),
CPlayerDesc(CadlPlayer::factory, "Westwood ADL", ".adl\0"),
CPlayerDesc(CjbmPlayer::factory, "JBM Adlib Music", ".jbm\0"),
CPlayerDesc()
};
const CPlayers &CAdPlug::init_players(const CPlayerDesc pd[])
{
static CPlayers initplayers;
unsigned int i;
for(i = 0; pd[i].factory; i++)
initplayers.push_back(&pd[i]);
return initplayers;
}
const CPlayers CAdPlug::players = CAdPlug::init_players(CAdPlug::allplayers);
CAdPlugDatabase *CAdPlug::database = 0;
CPlayer *CAdPlug::factory(const std::string &fn, Copl *opl, const CPlayers &pl,
const CFileProvider &fp)
{
CPlayer *p;
CPlayers::const_iterator i;
unsigned int j;
AdPlug_LogWrite("*** CAdPlug::factory(\"%s\",opl,fp) ***\n", fn.c_str());
// Try a direct hit by file extension
for(i = pl.begin(); i != pl.end(); i++)
for(j = 0; (*i)->get_extension(j); j++)
if(fp.extension(fn, (*i)->get_extension(j))) {
AdPlug_LogWrite("Trying direct hit: %s\n", (*i)->filetype.c_str());
if((p = (*i)->factory(opl))) {
if(p->load(fn, fp)) {
AdPlug_LogWrite("got it!\n");
AdPlug_LogWrite("--- CAdPlug::factory ---\n");
return p;
} else
delete p;
}
}
// Try all players, one by one
for(i = pl.begin(); i != pl.end(); i++) {
AdPlug_LogWrite("Trying: %s\n", (*i)->filetype.c_str());
if((p = (*i)->factory(opl))) {
if(p->load(fn, fp)) {
AdPlug_LogWrite("got it!\n");
AdPlug_LogWrite("--- CAdPlug::factory ---\n");
return p;
} else
delete p;
}
}
// Unknown file
AdPlug_LogWrite("End of list!\n");
AdPlug_LogWrite("--- CAdPlug::factory ---\n");
return 0;
}
void CAdPlug::set_database(CAdPlugDatabase *db)
{
database = db;
}
std::string CAdPlug::get_version()
{
return std::string(VERSION);
}
void CAdPlug::debug_output(const std::string &filename)
{
AdPlug_LogFile(filename.c_str());
AdPlug_LogWrite("CAdPlug::debug_output(\"%s\"): Redirected.\n",filename.c_str());
}
adplug-2.2.1+dfsg3/src/Makefile.am 0000644 0001750 0001750 00000002742 11317330662 016116 0 ustar gregoa gregoa lib_LTLIBRARIES = libadplug.la
libadplug_la_SOURCES = adplug.cpp emuopl.cpp fmopl.c diskopl.cpp debug.c \
debug.h fprovide.cpp player.cpp database.cpp hsc.cpp sng.cpp imf.cpp \
players.cpp protrack.cpp a2m.cpp adtrack.cpp amd.cpp bam.cpp d00.cpp dfm.cpp \
hsp.cpp ksm.cpp mad.cpp mid.cpp mkj.cpp cff.cpp dmo.cpp s3m.cpp dtm.cpp \
fmc.cpp mtk.cpp rad.cpp raw.cpp sa2.cpp xad.cpp flash.cpp bmf.cpp hybrid.cpp \
hyp.cpp psi.cpp rat.cpp u6m.cpp rol.cpp mididata.h xsm.cpp adlibemu.c dro.cpp \
lds.cpp realopl.cpp analopl.cpp temuopl.cpp msc.cpp rix.cpp adl.cpp jbm.cpp \
cmf.cpp surroundopl.cpp dro2.cpp
libadplug_la_LDFLAGS = -release @VERSION@ -version-info 0 $(libbinio_LIBS)
# -Dstricmp=strcasecmp is a hack. Throughout AdPlug, stricmp() is used to do
# caseless string comparations. UNIX libcs don't support stricmp(), but do
# support the BSD strcasecmp(), so we have to replace every occurence of
# stricmp() into strcasecmp(). stricmp() seems to be Windows, but maybe
# also POSIX...
AM_CPPFLAGS = -Dstricmp=strcasecmp $(libbinio_CFLAGS)
pkginclude_HEADERS = adplug.h emuopl.h fmopl.h silentopl.h opl.h diskopl.h \
a2m.h amd.h bam.h d00.h dfm.h hsc.h hsp.h imf.h ksm.h lds.h mid.h mkj.h \
mtk.h protrack.h rad.h raw.h s3m.h sa2.h sng.h u6m.h player.h fmc.h mad.h \
xad.h bmf.h flash.h hyp.h psi.h rat.h hybrid.h rol.h adtrack.h cff.h dtm.h \
dmo.h fprovide.h database.h players.h xsm.h adlibemu.h kemuopl.h dro.h \
realopl.h analopl.h temuopl.h msc.h rix.h adl.h jbm.h cmf.h surroundopl.h \
dro2.h
adplug-2.2.1+dfsg3/src/d00.cpp 0000644 0001750 0001750 00000040024 11025200503 015126 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2008 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* d00.c - D00 Player by Simon Peter
*
* NOTES:
* Sorry for the goto's, but the code looks so much nicer now.
* I tried it with while loops but it was just a mess. If you
* can come up with a nicer solution, just tell me.
*
* BUGS:
* Hard restart SR is sometimes wrong
*/
#include
#include
#include
#include "debug.h"
#include "d00.h"
#define HIBYTE(val) (val >> 8)
#define LOBYTE(val) (val & 0xff)
static const unsigned short notetable[12] = // D00 note table
{340,363,385,408,432,458,485,514,544,577,611,647};
static inline uint16_t LE_WORD(const uint16_t *val)
{
const uint8_t *b = (const uint8_t *)val;
return (b[1] << 8) + b[0];
}
/*** public methods *************************************/
CPlayer *Cd00Player::factory(Copl *newopl)
{
return new Cd00Player(newopl);
}
bool Cd00Player::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
d00header *checkhead;
d00header1 *ch;
unsigned long filesize;
int i,ver1=0;
char *str;
// file validation section
checkhead = new d00header;
f->readString((char *)checkhead, sizeof(d00header));
// Check for version 2-4 header
if(strncmp(checkhead->id,"JCH\x26\x02\x66",6) || checkhead->type ||
!checkhead->subsongs || checkhead->soundcard) {
// Check for version 0 or 1 header (and .d00 file extension)
delete checkhead;
if(!fp.extension(filename, ".d00")) { fp.close(f); return false; }
ch = new d00header1;
f->seek(0); f->readString((char *)ch, sizeof(d00header1));
if(ch->version > 1 || !ch->subsongs)
{ delete ch; fp.close(f); return false; }
delete ch;
ver1 = 1;
} else
delete checkhead;
AdPlug_LogWrite("Cd00Player::load(f,\"%s\"): %s format D00 file detected!\n",
filename.c_str(), ver1 ? "Old" : "New");
// load section
filesize = fp.filesize(f); f->seek(0);
filedata = new char [filesize + 1]; // 1 byte is needed for old-style DataInfo block
f->readString((char *)filedata, filesize);
fp.close(f);
if(!ver1) { // version 2 and above
header = (struct d00header *)filedata;
version = header->version;
datainfo = (char *)filedata + LE_WORD(&header->infoptr);
inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header->instptr));
seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header->seqptr));
for(i=31;i>=0;i--) // erase whitespace
if(header->songname[i] == ' ')
header->songname[i] = '\0';
else
break;
for(i=31;i>=0;i--)
if(header->author[i] == ' ')
header->author[i] = '\0';
else
break;
} else { // version 1
header1 = (struct d00header1 *)filedata;
version = header1->version;
datainfo = (char *)filedata + LE_WORD(&header1->infoptr);
inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header1->instptr));
seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header1->seqptr));
}
switch(version) {
case 0:
levpuls = 0;
spfx = 0;
header1->speed = 70; // v0 files default to 70Hz
break;
case 1:
levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header1->lpulptr));
spfx = 0;
break;
case 2:
levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header->spfxptr));
spfx = 0;
break;
case 3:
spfx = 0;
levpuls = 0;
break;
case 4:
spfx = (struct Sspfx *)((char *)filedata + LE_WORD(&header->spfxptr));
levpuls = 0;
break;
}
if((str = strstr(datainfo,"\xff\xff")))
while((*str == '\xff' || *str == ' ') && str >= datainfo) {
*str = '\0'; str--;
}
else // old-style block
memset((char *)filedata+filesize,0,1);
rewind(0);
return true;
}
bool Cd00Player::update()
{
unsigned char c,cnt,trackend=0,fx,note;
unsigned short ord,*patt,buf,fxop,pattpos;
// effect handling (timer dependant)
for(c=0;c<9;c++) {
channel[c].slideval += channel[c].slide; setfreq(c); // sliding
vibrato(c); // vibrato
if(channel[c].spfx != 0xffff) { // SpFX
if(channel[c].fxdel)
channel[c].fxdel--;
else {
channel[c].spfx = LE_WORD(&spfx[channel[c].spfx].ptr);
channel[c].fxdel = spfx[channel[c].spfx].duration;
channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff;
if(spfx[channel[c].spfx].modlev != 0xff)
channel[c].modvol = spfx[channel[c].spfx].modlev;
setinst(c);
if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency
note = spfx[channel[c].spfx].halfnote;
else // unlocked frequency
note = spfx[channel[c].spfx].halfnote + channel[c].note;
channel[c].freq = notetable[note%12] + ((note/12) << 10);
setfreq(c);
}
channel[c].modvol += spfx[channel[c].spfx].modlevadd; channel[c].modvol &= 63;
setvolume(c);
}
if(channel[c].levpuls != 0xff) { // Levelpuls
if(channel[c].frameskip)
channel[c].frameskip--;
else {
channel[c].frameskip = inst[channel[c].inst].timer;
if(channel[c].fxdel)
channel[c].fxdel--;
else {
channel[c].levpuls = levpuls[channel[c].levpuls].ptr - 1;
channel[c].fxdel = levpuls[channel[c].levpuls].duration;
if(levpuls[channel[c].levpuls].level != 0xff)
channel[c].modvol = levpuls[channel[c].levpuls].level;
}
channel[c].modvol += levpuls[channel[c].levpuls].voladd; channel[c].modvol &= 63;
setvolume(c);
}
}
}
// song handling
for(c=0;c<9;c++)
if(version < 3 ? channel[c].del : channel[c].del <= 0x7f) {
if(version == 4) // v4: hard restart SR
if(channel[c].del == inst[channel[c].inst].timer)
if(channel[c].nextnote)
opl->write(0x83 + op_table[c], inst[channel[c].inst].sr);
if(version < 3)
channel[c].del--;
else
if(channel[c].speed)
channel[c].del += channel[c].speed;
else {
channel[c].seqend = 1;
continue;
}
} else {
if(channel[c].speed) {
if(version < 3)
channel[c].del = channel[c].speed;
else {
channel[c].del &= 0x7f;
channel[c].del += channel[c].speed;
}
} else {
channel[c].seqend = 1;
continue;
}
if(channel[c].rhcnt) { // process pending REST/HOLD events
channel[c].rhcnt--;
continue;
}
readorder: // process arrangement (orderlist)
ord = LE_WORD(&channel[c].order[channel[c].ordpos]);
switch(ord) {
case 0xfffe: channel[c].seqend = 1; continue; // end of arrangement stream
case 0xffff: // jump to order
channel[c].ordpos = LE_WORD(&channel[c].order[channel[c].ordpos + 1]);
channel[c].seqend = 1;
goto readorder;
default:
if(ord >= 0x9000) { // set speed
channel[c].speed = ord & 0xff;
ord = LE_WORD(&channel[c].order[channel[c].ordpos - 1]);
channel[c].ordpos++;
} else
if(ord >= 0x8000) { // transpose track
channel[c].transpose = ord & 0xff;
if(ord & 0x100)
channel[c].transpose = -channel[c].transpose;
ord = LE_WORD(&channel[c].order[++channel[c].ordpos]);
}
patt = (unsigned short *)((char *)filedata + LE_WORD(&seqptr[ord]));
break;
}
channel[c].fxflag = 0;
readseq: // process sequence (pattern)
if(!version) // v0: always initialize rhcnt
channel[c].rhcnt = channel[c].irhcnt;
pattpos = LE_WORD(&patt[channel[c].pattpos]);
if(pattpos == 0xffff) { // pattern ended?
channel[c].pattpos = 0;
channel[c].ordpos++;
goto readorder;
}
cnt = HIBYTE(pattpos);
note = LOBYTE(pattpos);
fx = pattpos >> 12;
fxop = pattpos & 0x0fff;
channel[c].pattpos++; pattpos = LE_WORD(&patt[channel[c].pattpos]);
channel[c].nextnote = LOBYTE(pattpos) & 0x7f;
if(version ? cnt < 0x40 : !fx) { // note event
switch(note) {
case 0: // REST event
case 0x80:
if(!note || version) {
channel[c].key = 0;
setfreq(c);
}
// fall through...
case 0x7e: // HOLD event
if(version)
channel[c].rhcnt = cnt;
channel[c].nextnote = 0;
break;
default: // play note
// restart fx
if(!(channel[c].fxflag & 1))
channel[c].vibdepth = 0;
if(!(channel[c].fxflag & 2))
channel[c].slideval = channel[c].slide = 0;
if(version) { // note handling for v1 and above
if(note > 0x80) // locked note (no channel transpose)
note -= 0x80;
else // unlocked note
note += channel[c].transpose;
channel[c].note = note; // remember note for SpFX
if(channel[c].ispfx != 0xffff && cnt < 0x20) { // reset SpFX
channel[c].spfx = channel[c].ispfx;
if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000) // locked frequency
note = spfx[channel[c].spfx].halfnote;
else // unlocked frequency
note += spfx[channel[c].spfx].halfnote;
channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff;
channel[c].fxdel = spfx[channel[c].spfx].duration;
if(spfx[channel[c].spfx].modlev != 0xff)
channel[c].modvol = spfx[channel[c].spfx].modlev;
else
channel[c].modvol = inst[channel[c].inst].data[7] & 63;
}
if(channel[c].ilevpuls != 0xff && cnt < 0x20) { // reset LevelPuls
channel[c].levpuls = channel[c].ilevpuls;
channel[c].fxdel = levpuls[channel[c].levpuls].duration;
channel[c].frameskip = inst[channel[c].inst].timer;
if(levpuls[channel[c].levpuls].level != 0xff)
channel[c].modvol = levpuls[channel[c].levpuls].level;
else
channel[c].modvol = inst[channel[c].inst].data[7] & 63;
}
channel[c].freq = notetable[note%12] + ((note/12) << 10);
if(cnt < 0x20) // normal note
playnote(c);
else { // tienote
setfreq(c);
cnt -= 0x20; // make count proper
}
channel[c].rhcnt = cnt;
} else { // note handling for v0
if(cnt < 2) // unlocked note
note += channel[c].transpose;
channel[c].note = note;
channel[c].freq = notetable[note%12] + ((note/12) << 10);
if(cnt == 1) // tienote
setfreq(c);
else // normal note
playnote(c);
}
break;
}
continue; // event is complete
} else { // effect event
switch(fx) {
case 6: // Cut/Stop Voice
buf = channel[c].inst;
channel[c].inst = 0;
playnote(c);
channel[c].inst = buf;
channel[c].rhcnt = fxop;
continue; // no note follows this event
case 7: // Vibrato
channel[c].vibspeed = fxop & 0xff;
channel[c].vibdepth = fxop >> 8;
channel[c].trigger = fxop >> 9;
channel[c].fxflag |= 1;
break;
case 8: // v0: Duration
if(!version)
channel[c].irhcnt = fxop;
break;
case 9: // New Level
channel[c].vol = fxop & 63;
if(channel[c].vol + channel[c].cvol < 63) // apply channel volume
channel[c].vol += channel[c].cvol;
else
channel[c].vol = 63;
setvolume(c);
break;
case 0xb: // v4: Set SpFX
if(version == 4)
channel[c].ispfx = fxop;
break;
case 0xc: // Set Instrument
channel[c].ispfx = 0xffff;
channel[c].spfx = 0xffff;
channel[c].inst = fxop;
channel[c].modvol = inst[fxop].data[7] & 63;
if(version < 3 && version && inst[fxop].tunelev) // Set LevelPuls
channel[c].ilevpuls = inst[fxop].tunelev - 1;
else {
channel[c].ilevpuls = 0xff;
channel[c].levpuls = 0xff;
}
break;
case 0xd: // Slide up
channel[c].slide = fxop;
channel[c].fxflag |= 2;
break;
case 0xe: // Slide down
channel[c].slide = -fxop;
channel[c].fxflag |= 2;
break;
}
goto readseq; // event is incomplete, note follows
}
}
for(c=0;c<9;c++)
if(channel[c].seqend)
trackend++;
if(trackend == 9)
songend = 1;
return !songend;
}
void Cd00Player::rewind(int subsong)
{
struct Stpoin {
unsigned short ptr[9];
unsigned char volume[9],dummy[5];
} *tpoin;
int i;
if(subsong == -1) subsong = cursubsong;
if(version > 1) { // do nothing if subsong > number of subsongs
if(subsong >= header->subsongs)
return;
} else
if(subsong >= header1->subsongs)
return;
memset(channel,0,sizeof(channel));
if(version > 1)
tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header->tpoin));
else
tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header1->tpoin));
for(i=0;i<9;i++) {
if(LE_WORD(&tpoin[subsong].ptr[i])) { // track enabled
channel[i].speed = LE_WORD((unsigned short *)
((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i])));
channel[i].order = (unsigned short *)
((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i]) + 2);
} else { // track disabled
channel[i].speed = 0;
channel[i].order = 0;
}
channel[i].ispfx = 0xffff; channel[i].spfx = 0xffff; // no SpFX
channel[i].ilevpuls = 0xff; channel[i].levpuls = 0xff; // no LevelPuls
channel[i].cvol = tpoin[subsong].volume[i] & 0x7f; // our player may savely ignore bit 7
channel[i].vol = channel[i].cvol; // initialize volume
}
songend = 0;
opl->init(); opl->write(1,32); // reset OPL chip
cursubsong = subsong;
}
std::string Cd00Player::gettype()
{
char tmpstr[40];
sprintf(tmpstr,"EdLib packed (version %d)",version > 1 ? header->version : header1->version);
return std::string(tmpstr);
}
float Cd00Player::getrefresh()
{
if(version > 1)
return header->speed;
else
return header1->speed;
}
unsigned int Cd00Player::getsubsongs()
{
if(version <= 1) // return number of subsongs
return header1->subsongs;
else
return header->subsongs;
}
/*** private methods *************************************/
void Cd00Player::setvolume(unsigned char chan)
{
unsigned char op = op_table[chan];
unsigned short insnr = channel[chan].inst;
opl->write(0x43 + op,(int)(63-((63-(inst[insnr].data[2] & 63))/63.0)*(63-channel[chan].vol)) +
(inst[insnr].data[2] & 192));
if(inst[insnr].data[10] & 1)
opl->write(0x40 + op,(int)(63-((63-channel[chan].modvol)/63.0)*(63-channel[chan].vol)) +
(inst[insnr].data[7] & 192));
else
opl->write(0x40 + op,channel[chan].modvol + (inst[insnr].data[7] & 192));
}
void Cd00Player::setfreq(unsigned char chan)
{
unsigned short freq = channel[chan].freq;
if(version == 4) // v4: apply instrument finetune
freq += inst[channel[chan].inst].tunelev;
freq += channel[chan].slideval;
opl->write(0xa0 + chan, freq & 255);
if(channel[chan].key)
opl->write(0xb0 + chan, ((freq >> 8) & 31) | 32);
else
opl->write(0xb0 + chan, (freq >> 8) & 31);
}
void Cd00Player::setinst(unsigned char chan)
{
unsigned char op = op_table[chan];
unsigned short insnr = channel[chan].inst;
// set instrument data
opl->write(0x63 + op, inst[insnr].data[0]);
opl->write(0x83 + op, inst[insnr].data[1]);
opl->write(0x23 + op, inst[insnr].data[3]);
opl->write(0xe3 + op, inst[insnr].data[4]);
opl->write(0x60 + op, inst[insnr].data[5]);
opl->write(0x80 + op, inst[insnr].data[6]);
opl->write(0x20 + op, inst[insnr].data[8]);
opl->write(0xe0 + op, inst[insnr].data[9]);
if(version)
opl->write(0xc0 + chan, inst[insnr].data[10]);
else
opl->write(0xc0 + chan, (inst[insnr].data[10] << 1) + (inst[insnr].tunelev & 1));
}
void Cd00Player::playnote(unsigned char chan)
{
// set misc vars & play
opl->write(0xb0 + chan, 0); // stop old note
setinst(chan);
channel[chan].key = 1;
setfreq(chan);
setvolume(chan);
}
void Cd00Player::vibrato(unsigned char chan)
{
if(!channel[chan].vibdepth)
return;
if(channel[chan].trigger)
channel[chan].trigger--;
else {
channel[chan].trigger = channel[chan].vibdepth;
channel[chan].vibspeed = -channel[chan].vibspeed;
}
channel[chan].freq += channel[chan].vibspeed;
setfreq(chan);
}
adplug-2.2.1+dfsg3/src/hsp.h 0000644 0001750 0001750 00000002321 10126563267 015024 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2004 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* hsp.h: HSC Packed Loader by Simon Peter
*/
#ifndef H_ADPLUG_HSPLOADER
#define H_ADPLUG_HSPLOADER
#include "hsc.h"
class ChspLoader: public ChscPlayer
{
public:
static CPlayer *factory(Copl *newopl);
ChspLoader(Copl *newopl)
: ChscPlayer(newopl)
{};
bool load(const std::string &filename, const CFileProvider &fp);
};
#endif
adplug-2.2.1+dfsg3/src/rat.cpp 0000644 0001750 0001750 00000016267 10754126627 015373 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2003 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* [xad] RAT player, by Riven the Mage
*/
/*
- discovery -
file(s) : PINA.EXE
type : Experimental Connection BBStro tune
tune : by (?)Ratt/GRIF
player : by (?)Ratt/GRIF
comment : there are bug in original replayer's adlib_init(): wrong frequency registers.
*/
#include
#include "rat.h"
#include "debug.h"
const unsigned char CxadratPlayer::rat_adlib_bases[18] =
{
0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12,
0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15
};
const unsigned short CxadratPlayer::rat_notes[16] =
{
0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287,
0x000, 0x000, 0x000, 0x000 // by riven
};
CPlayer *CxadratPlayer::factory(Copl *newopl)
{
return new CxadratPlayer(newopl);
}
bool CxadratPlayer::xadplayer_load()
{
if(xad.fmt != RAT)
return false;
// load header
memcpy(&rat.hdr, &tune[0], sizeof(rat_header));
// is 'RAT'-signed ?
if (strncmp(rat.hdr.id,"RAT",3))
return false;
// is version 1.0 ?
if (rat.hdr.version != 0x10)
return false;
// load order
rat.order = &tune[0x40];
// load instruments
rat.inst = (rat_instrument *)&tune[0x140];
// load pattern data
unsigned short patseg = (rat.hdr.patseg[1] << 8) + rat.hdr.patseg[0];
unsigned char *event_ptr = &tune[patseg << 4];
for(int i=0;i> 8) | ((event.note & 0xF0) >> 2) | 0x20);
}
}
// is effect ?
if (event.fx != 0xFF)
{
rat.channel[i].fx = event.fx;
rat.channel[i].fxp = event.fxp;
}
}
// next row
rat.pattern_pos++;
// process effects
for(i=0;i= 0x40)
{
rat.pattern_pos = 0;
rat.order_pos++;
// end of module ?
if (rat.order_pos == rat.hdr.order_end)
{
rat.order_pos = rat.hdr.order_loop;
plr.looping = 1;
}
}
}
float CxadratPlayer::xadplayer_getrefresh()
{
return 60.0f;
}
std::string CxadratPlayer::xadplayer_gettype()
{
return (std::string("xad: rat player"));
}
std::string CxadratPlayer::xadplayer_gettitle()
{
return (std::string(rat.hdr.title,32));
}
unsigned int CxadratPlayer::xadplayer_getinstruments()
{
return rat.hdr.numinst;
}
/* -------- Internal Functions ---------------------------- */
unsigned char CxadratPlayer::__rat_calc_volume(unsigned char ivol, unsigned char cvol, unsigned char gvol)
{
#ifdef DEBUG
AdPlug_LogWrite("volumes: instrument %02X, channel %02X, global %02X:\n", ivol, cvol, gvol);
#endif
unsigned short vol;
vol = ivol;
vol &= 0x3F;
vol ^= 0x3F;
vol *= cvol;
vol >>= 6;
vol *= gvol;
vol >>= 6;
vol ^= 0x3F;
vol |= ivol & 0xC0;
return vol;
}
adplug-2.2.1+dfsg3/src/raw.cpp 0000644 0001750 0001750 00000005171 10754126627 015366 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* raw.c - RAW Player by Simon Peter
*/
#include
#include "raw.h"
/*** public methods *************************************/
CPlayer *CrawPlayer::factory(Copl *newopl)
{
return new CrawPlayer(newopl);
}
bool CrawPlayer::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
char id[8];
unsigned long i;
// file validation section
f->readString(id, 8);
if(strncmp(id,"RAWADATA",8)) { fp.close (f); return false; }
// load section
clock = f->readInt(2); // clock speed
length = (fp.filesize(f) - 10) / 2;
data = new Tdata [length];
for(i = 0; i < length; i++) {
data[i].param = f->readInt(1);
data[i].command = f->readInt(1);
}
fp.close(f);
rewind(0);
return true;
}
bool CrawPlayer::update()
{
bool setspeed;
if(pos >= length) return false;
if(del) {
del--;
return !songend;
}
do {
setspeed = false;
switch(data[pos].command) {
case 0: del = data[pos].param - 1; break;
case 2:
if(!data[pos].param) {
pos++;
speed = data[pos].param + (data[pos].command << 8);
setspeed = true;
} else
opl->setchip(data[pos].param - 1);
break;
case 0xff:
if(data[pos].param == 0xff) {
rewind(0); // auto-rewind song
songend = true;
return !songend;
}
break;
default:
opl->write(data[pos].command,data[pos].param);
break;
}
} while(data[pos++].command || setspeed);
return !songend;
}
void CrawPlayer::rewind(int subsong)
{
pos = del = 0; speed = clock; songend = false;
opl->init(); opl->write(1, 32); // go to 9 channel mode
}
float CrawPlayer::getrefresh()
{
return 1193180.0 / (speed ? speed : 0xffff); // timer oscillator speed / wait register = clock frequency
}
adplug-2.2.1+dfsg3/src/surroundopl.cpp 0000644 0001750 0001750 00000016676 11317330645 017176 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2010 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* surroundopl.cpp - Wrapper class to provide a surround/harmonic effect
* for another OPL emulator, by Adam Nielsen
*
* Stereo harmonic algorithm by Adam Nielsen
* Please give credit if you use this algorithm elsewhere :-)
*/
#include // for pow()
#include "surroundopl.h"
#include "debug.h"
CSurroundopl::CSurroundopl(Copl *a, Copl *b, bool use16bit)
: use16bit(use16bit),
bufsize(4096),
a(a), b(b)
{
currType = TYPE_OPL2;
this->lbuf = new short[this->bufsize];
this->rbuf = new short[this->bufsize];
};
CSurroundopl::~CSurroundopl()
{
delete[] this->rbuf;
delete[] this->lbuf;
delete a;
delete b;
}
void CSurroundopl::update(short *buf, int samples)
{
if (samples * 2 > this->bufsize) {
// Need to realloc the buffer
delete[] this->rbuf;
delete[] this->lbuf;
this->bufsize = samples * 2;
this->lbuf = new short[this->bufsize];
this->rbuf = new short[this->bufsize];
}
a->update(this->lbuf, samples);
b->update(this->rbuf, samples);
// Copy the two mono OPL buffers into the stereo buffer
for (int i = 0; i < samples; i++) {
if (this->use16bit) {
buf[i * 2] = this->lbuf[i];
buf[i * 2 + 1] = this->rbuf[i];
} else {
((char *)buf)[i * 2] = ((char *)this->lbuf)[i];
((char *)buf)[i * 2 + 1] = ((char *)this->rbuf)[i];
}
}
}
// template methods
void CSurroundopl::write(int reg, int val)
{
a->write(reg, val);
// Transpose the other channel to produce the harmonic effect
int iChannel = -1;
int iRegister = reg; // temp
int iValue = val; // temp
if ((iRegister >> 4 == 0xA) || (iRegister >> 4 == 0xB)) iChannel = iRegister & 0x0F;
// Remember the FM state, so that the harmonic effect can access
// previously assigned register values.
/*if (((iRegister >> 4 == 0xB) && (iValue & 0x20) && !(this->iFMReg[iRegister] & 0x20)) ||
(iRegister == 0xBD) && (
((iValue & 0x01) && !(this->iFMReg[0xBD] & 0x01))
)) {
this->iFMReg[iRegister] = iValue;
}*/
this->iFMReg[iRegister] = iValue;
if ((iChannel >= 0)) {// && (i == 1)) {
uint8_t iBlock = (this->iFMReg[0xB0 + iChannel] >> 2) & 0x07;
uint16_t iFNum = ((this->iFMReg[0xB0 + iChannel] & 0x03) << 8) | this->iFMReg[0xA0 + iChannel];
//double dbOriginalFreq = 50000.0 * (double)iFNum * pow(2, iBlock - 20);
double dbOriginalFreq = 49716.0 * (double)iFNum * pow(2, iBlock - 20);
uint8_t iNewBlock = iBlock;
uint16_t iNewFNum;
// Adjust the frequency and calculate the new FNum
//double dbNewFNum = (dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (50000.0 * pow(2, iNewBlock - 20));
//#define calcFNum() ((dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (50000.0 * pow(2, iNewBlock - 20)))
#define calcFNum() ((dbOriginalFreq+(dbOriginalFreq/FREQ_OFFSET)) / (49716.0 * pow(2, iNewBlock - 20)))
double dbNewFNum = calcFNum();
// Make sure it's in range for the OPL chip
if (dbNewFNum > 1023 - NEWBLOCK_LIMIT) {
// It's too high, so move up one block (octave) and recalculate
if (iNewBlock > 6) {
// Uh oh, we're already at the highest octave!
AdPlug_LogWrite("OPL WARN: FNum %d/B#%d would need block 8+ after being transposed (new FNum is %d)\n",
iFNum, iBlock, (int)dbNewFNum);
// The best we can do here is to just play the same note out of the second OPL, so at least it shouldn't
// sound *too* bad (hopefully it will just miss out on the nice harmonic.)
iNewBlock = iBlock;
iNewFNum = iFNum;
} else {
iNewBlock++;
iNewFNum = (uint16_t)calcFNum();
}
} else if (dbNewFNum < 0 + NEWBLOCK_LIMIT) {
// It's too low, so move down one block (octave) and recalculate
if (iNewBlock == 0) {
// Uh oh, we're already at the lowest octave!
AdPlug_LogWrite("OPL WARN: FNum %d/B#%d would need block -1 after being transposed (new FNum is %d)!\n",
iFNum, iBlock, (int)dbNewFNum);
// The best we can do here is to just play the same note out of the second OPL, so at least it shouldn't
// sound *too* bad (hopefully it will just miss out on the nice harmonic.)
iNewBlock = iBlock;
iNewFNum = iFNum;
} else {
iNewBlock--;
iNewFNum = (uint16_t)calcFNum();
}
} else {
// Original calculation is within range, use that
iNewFNum = (uint16_t)dbNewFNum;
}
// Sanity check
if (iNewFNum > 1023) {
// Uh oh, the new FNum is still out of range! (This shouldn't happen)
AdPlug_LogWrite("OPL ERR: Original note (FNum %d/B#%d is still out of range after change to FNum %d/B#%d!\n",
iFNum, iBlock, iNewFNum, iNewBlock);
// The best we can do here is to just play the same note out of the second OPL, so at least it shouldn't
// sound *too* bad (hopefully it will just miss out on the nice harmonic.)
iNewBlock = iBlock;
iNewFNum = iFNum;
}
if ((iRegister >= 0xB0) && (iRegister <= 0xB8)) {
// Overwrite the supplied value with the new F-Number and Block.
iValue = (iValue & ~0x1F) | (iNewBlock << 2) | ((iNewFNum >> 8) & 0x03);
this->iCurrentTweakedBlock[iChannel] = iNewBlock; // save it so we don't have to update register 0xB0 later on
this->iCurrentFNum[iChannel] = iNewFNum;
if (this->iTweakedFMReg[0xA0 + iChannel] != (iNewFNum & 0xFF)) {
// Need to write out low bits
uint8_t iAdditionalReg = 0xA0 + iChannel;
uint8_t iAdditionalValue = iNewFNum & 0xFF;
b->write(iAdditionalReg, iAdditionalValue);
this->iTweakedFMReg[iAdditionalReg] = iAdditionalValue;
}
} else if ((iRegister >= 0xA0) && (iRegister <= 0xA8)) {
// Overwrite the supplied value with the new F-Number.
iValue = iNewFNum & 0xFF;
// See if we need to update the block number, which is stored in a different register
uint8_t iNewB0Value = (this->iFMReg[0xB0 + iChannel] & ~0x1F) | (iNewBlock << 2) | ((iNewFNum >> 8) & 0x03);
if (
(iNewB0Value & 0x20) && // but only update if there's a note currently playing (otherwise we can just wait
(this->iTweakedFMReg[0xB0 + iChannel] != iNewB0Value) // until the next noteon and update it then)
) {
AdPlug_LogWrite("OPL INFO: CH%d - FNum %d/B#%d -> FNum %d/B#%d == keyon register update!\n",
iChannel, iFNum, iBlock, iNewFNum, iNewBlock);
// The note is already playing, so we need to adjust the upper bits too
uint8_t iAdditionalReg = 0xB0 + iChannel;
b->write(iAdditionalReg, iNewB0Value);
this->iTweakedFMReg[iAdditionalReg] = iNewB0Value;
} // else the note is not playing, the upper bits will be set when the note is next played
} // if (register 0xB0 or 0xA0)
} // if (a register we're interested in)
// Now write to the original register with a possibly modified value
b->write(iRegister, iValue);
this->iTweakedFMReg[iRegister] = iValue;
};
void CSurroundopl::init() {};
adplug-2.2.1+dfsg3/src/bam.h 0000644 0001750 0001750 00000003107 07615503351 014771 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2003 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* bam.h - Bob's Adlib Music Player, by Simon Peter
*/
#include "player.h"
class CbamPlayer: public CPlayer
{
public:
static CPlayer *factory(Copl *newopl);
CbamPlayer(Copl *newopl)
: CPlayer(newopl), song(0)
{ };
~CbamPlayer()
{ if(song) delete [] song; };
bool load(const std::string &filename, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh()
{ return 25.0f; };
std::string gettype()
{ return std::string("Bob's Adlib Music"); };
private:
static const unsigned short freq[];
unsigned char *song, del;
unsigned long pos, size, gosub;
bool songend, chorus;
struct {
unsigned long target;
bool defined;
unsigned char count;
} label[16];
};
adplug-2.2.1+dfsg3/src/d00.h 0000644 0001750 0001750 00000006116 10611202633 014605 0 ustar gregoa gregoa /*
* AdPlug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* d00.h - D00 Player by Simon Peter
*/
#ifndef H_D00
#define H_D00
#include "player.h"
class Cd00Player: public CPlayer
{
public:
static CPlayer *factory(Copl *newopl);
Cd00Player(Copl *newopl)
: CPlayer(newopl), filedata(0)
{ };
~Cd00Player()
{ if(filedata) delete [] filedata; };
bool load(const std::string &filename, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
std::string gettype();
std::string gettitle()
{ if(version > 1) return std::string(header->songname); else return std::string(); };
std::string getauthor()
{ if(version > 1) return std::string(header->author); else return std::string(); };
std::string getdesc()
{ if(*datainfo) return std::string(datainfo); else return std::string(); };
unsigned int getsubsongs();
protected:
#pragma pack(1)
struct d00header {
char id[6];
unsigned char type,version,speed,subsongs,soundcard;
char songname[32],author[32],dummy[32];
unsigned short tpoin,seqptr,instptr,infoptr,spfxptr,endmark;
};
struct d00header1 {
unsigned char version,speed,subsongs;
unsigned short tpoin,seqptr,instptr,infoptr,lpulptr,endmark;
};
#pragma pack()
struct {
unsigned short *order,ordpos,pattpos,del,speed,rhcnt,key,freq,inst,
spfx,ispfx,irhcnt;
signed short transpose,slide,slideval,vibspeed;
unsigned char seqend,vol,vibdepth,fxdel,modvol,cvol,levpuls,
frameskip,nextnote,note,ilevpuls,trigger,fxflag;
} channel[9];
struct Sinsts {
unsigned char data[11],tunelev,timer,sr,dummy[2];
} *inst;
struct Sspfx {
unsigned short instnr;
signed char halfnote;
unsigned char modlev;
signed char modlevadd;
unsigned char duration;
unsigned short ptr;
} *spfx;
struct Slevpuls {
unsigned char level;
signed char voladd;
unsigned char duration,ptr;
} *levpuls;
unsigned char songend,version,cursubsong;
char *datainfo;
unsigned short *seqptr;
d00header *header;
d00header1 *header1;
char *filedata;
private:
void setvolume(unsigned char chan);
void setfreq(unsigned char chan);
void setinst(unsigned char chan);
void playnote(unsigned char chan);
void vibrato(unsigned char chan);
};
#endif
adplug-2.2.1+dfsg3/src/emuopl.cpp 0000644 0001750 0001750 00000010031 10324540221 016044 0 ustar gregoa gregoa /*
* AdPlug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* emuopl.cpp - Emulated OPL, by Simon Peter
*/
#include "emuopl.h"
CEmuopl::CEmuopl(int rate, bool bit16, bool usestereo)
: use16bit(bit16), stereo(usestereo), mixbufSamples(0)
{
opl[0] = OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
opl[1] = OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
currType = TYPE_DUAL_OPL2;
init();
}
CEmuopl::~CEmuopl()
{
OPLDestroy(opl[0]); OPLDestroy(opl[1]);
if(mixbufSamples) {
delete [] mixbuf0;
delete [] mixbuf1;
}
}
void CEmuopl::update(short *buf, int samples)
{
int i;
//ensure that our mix buffers are adequately sized
if(mixbufSamples < samples) {
if(mixbufSamples) { delete[] mixbuf0; delete[] mixbuf1; }
mixbufSamples = samples;
//*2 = make room for stereo, if we need it
mixbuf0 = new short[samples*2];
mixbuf1 = new short[samples*2];
}
//data should be rendered to outbuf
//tempbuf should be used as a temporary buffer
//if we are supposed to generate 16bit output,
//then outbuf may point directly to the actual waveform output "buf"
//if we are supposed to generate 8bit output,
//then outbuf cannot point to "buf" (because there will not be enough room)
//and so it must point to a mixbuf instead--
//it will be reduced to 8bit and put in "buf" later
short *outbuf;
short *tempbuf=mixbuf0;
short *tempbuf2=mixbuf1;
if(use16bit) outbuf = buf;
else outbuf = mixbuf1;
//...there is a potentially confusing situation where mixbuf1 can be aliased.
//beware. it is a little loony.
//all of the following rendering code produces 16bit output
switch(currType) {
case TYPE_OPL2:
//for opl2 mode:
//render chip0 to the output buffer
YM3812UpdateOne(opl[0],outbuf,samples);
//if we are supposed to output stereo,
//then we need to dup the mono channel
if(stereo)
for(i=samples-1;i>=0;i--) {
outbuf[i*2] = outbuf[i];
outbuf[i*2+1] = outbuf[i];
}
break;
case TYPE_OPL3: // unsupported
break;
case TYPE_DUAL_OPL2:
//for dual opl2 mode:
//render each chip to a different tempbuffer
YM3812UpdateOne(opl[0],tempbuf2,samples);
YM3812UpdateOne(opl[1],tempbuf,samples);
//output stereo:
//then we need to interleave the two buffers
if(stereo){
//first, spread tempbuf's samples across left channel
//left channel
for(i=0;i>1) + (tempbuf2[i]>>1);
break;
}
//now reduce to 8bit if we need to
if(!use16bit)
for(i=0;i<(stereo ? samples*2 : samples);i++)
((char *)buf)[i] = (outbuf[i] >> 8) ^ 0x80;
}
void CEmuopl::write(int reg, int val)
{
switch(currType){
case TYPE_OPL2:
case TYPE_DUAL_OPL2:
OPLWrite(opl[currChip], 0, reg);
OPLWrite(opl[currChip], 1, val);
break;
case TYPE_OPL3: // unsupported
break;
}
}
void CEmuopl::init()
{
OPLResetChip(opl[0]); OPLResetChip(opl[1]);
currChip = 0;
}
void CEmuopl::settype(ChipType type)
{
currType = type;
}
adplug-2.2.1+dfsg3/src/ksm.h 0000644 0001750 0001750 00000004026 07615503353 015027 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2003 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ksm.h - KSM Player for AdPlug by Simon Peter
*/
#include "player.h"
class CksmPlayer: public CPlayer
{
public:
static CPlayer *factory(Copl *newopl);
CksmPlayer(Copl *newopl)
: CPlayer(newopl), note(0)
{ };
~CksmPlayer()
{ if(note) delete [] note; };
bool load(const std::string &filename, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh()
{ return 240.0f; };
std::string gettype()
{ return std::string("Ken Silverman's Music Format"); };
unsigned int getinstruments()
{ return 16; };
std::string getinstrument(unsigned int n);
private:
static const unsigned int adlibfreq[63];
unsigned long count,countstop,chanage[18],*note;
unsigned short numnotes;
unsigned int nownote,numchans,drumstat;
unsigned char trinst[16],trquant[16],trchan[16],trvol[16],inst[256][11],databuf[2048],chanfreq[18],chantrack[18];
char instname[256][20];
bool songend;
void loadinsts(binistream *f);
void setinst(int chan,unsigned char v0,unsigned char v1,unsigned char v2,unsigned char v3,
unsigned char v4,unsigned char v5,unsigned char v6,unsigned char v7,
unsigned char v8,unsigned char v9,unsigned char v10);
};
adplug-2.2.1+dfsg3/src/debug.h 0000644 0001750 0001750 00000002773 07547124547 015342 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2002 Simon Peter , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* debug.h - AdPlug Debug Logger
* Copyright (c) 2002 Riven the Mage
* Copyright (c) 2002 Simon Peter
*
* NOTES:
* This debug logger is used throughout AdPlug to log debug output to stderr
* (the default) or to a user-specified logfile.
*
* To use it, AdPlug has to be compiled with debug logging support enabled.
* This is done by defining the DEBUG macro with every source-file. The
* LogFile() function can be used to specify a logfile to write to.
*/
#ifndef H_DEBUG
#define H_DEBUG
extern "C"
{
void AdPlug_LogFile(const char *filename);
void AdPlug_LogWrite(const char *fmt, ...);
}
#endif
adplug-2.2.1+dfsg3/src/cff.cpp 0000644 0001750 0001750 00000025455 11025200502 015313 0 ustar gregoa gregoa /*
AdPlug - Replayer for many OPL2/OPL3 audio file formats.
Copyright (C) 1999 - 2008 Simon Peter , et al.
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.1 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 Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
cff.cpp - BoomTracker loader by Riven the Mage
*/
/*
NOTE: Conversion of slides is not 100% accurate. Original volume slides
have effect on carrier volume only. Also, original arpeggio, frequency & volume
slides use previous effect data instead of current.
*/
#include
#include
#include
#include "cff.h"
/* -------- Public Methods -------------------------------- */
CPlayer *CcffLoader::factory(Copl *newopl)
{
return new CcffLoader(newopl);
}
bool CcffLoader::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
int i,j,k,t=0;
// '' - signed ?
f->readString(header.id, 16);
header.version = f->readInt(1); header.size = f->readInt(2);
header.packed = f->readInt(1); f->readString((char *)header.reserved, 12);
if (memcmp(header.id,"""\x1A\xDE\xE0",16))
{ fp.close(f); return false; }
unsigned char *module = new unsigned char [0x10000];
// packed ?
if (header.packed)
{
cff_unpacker *unpacker = new cff_unpacker;
unsigned char *packed_module = new unsigned char [header.size + 4];
memset(packed_module,0,header.size + 4);
f->readString((char *)packed_module, header.size);
fp.close(f);
if (!unpacker->unpack(packed_module,module))
{
delete unpacker;
delete packed_module;
delete module;
return false;
}
delete unpacker;
delete packed_module;
if (memcmp(&module[0x5E1],"CUD-FM-File - SEND A POSTCARD -",31))
{
delete module;
return false;
}
}
else
{
f->readString((char *)module, header.size);
fp.close(f);
}
// init CmodPlayer
realloc_instruments(47);
realloc_order(64);
realloc_patterns(36,64,9);
init_notetable(conv_note);
init_trackord();
// load instruments
for (i=0;i<47;i++)
{
memcpy(&instruments[i],&module[i*32],sizeof(cff_instrument));
for (j=0;j<11;j++)
inst[i].data[conv_inst[j]] = instruments[i].data[j];
instruments[i].name[20] = 0;
}
// number of patterns
nop = module[0x5E0];
// load title & author
memcpy(song_title,&module[0x614],20);
memcpy(song_author,&module[0x600],20);
// load order
memcpy(order,&module[0x628],64);
// load tracks
for (i=0;ibyte0 == 0x6D)
tracks[t][k].note = 127;
else
if (event->byte0)
tracks[t][k].note = event->byte0;
if (event->byte2)
old_event_byte2[j] = event->byte2;
// convert effect
switch (event->byte1)
{
case 'I': // set instrument
tracks[t][k].inst = event->byte2 + 1;
tracks[t][k].param1 = tracks[t][k].param2 = 0;
break;
case 'H': // set tempo
tracks[t][k].command = 7;
if (event->byte2 < 16)
{
tracks[t][k].param1 = 0x07;
tracks[t][k].param2 = 0x0D;
}
break;
case 'A': // set speed
tracks[t][k].command = 19;
tracks[t][k].param1 = event->byte2 >> 4;
tracks[t][k].param2 = event->byte2 & 15;
break;
case 'L': // pattern break
tracks[t][k].command = 13;
tracks[t][k].param1 = event->byte2 >> 4;
tracks[t][k].param2 = event->byte2 & 15;
break;
case 'K': // order jump
tracks[t][k].command = 11;
tracks[t][k].param1 = event->byte2 >> 4;
tracks[t][k].param2 = event->byte2 & 15;
break;
case 'M': // set vibrato/tremolo
tracks[t][k].command = 27;
tracks[t][k].param1 = event->byte2 >> 4;
tracks[t][k].param2 = event->byte2 & 15;
break;
case 'C': // set modulator volume
tracks[t][k].command = 21;
tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
tracks[t][k].param2 = (0x3F - event->byte2) & 15;
break;
case 'G': // set carrier volume
tracks[t][k].command = 22;
tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
tracks[t][k].param2 = (0x3F - event->byte2) & 15;
break;
case 'B': // set carrier waveform
tracks[t][k].command = 25;
tracks[t][k].param1 = event->byte2;
tracks[t][k].param2 = 0x0F;
break;
case 'E': // fine frequency slide down
tracks[t][k].command = 24;
tracks[t][k].param1 = old_event_byte2[j] >> 4;
tracks[t][k].param2 = old_event_byte2[j] & 15;
break;
case 'F': // fine frequency slide up
tracks[t][k].command = 23;
tracks[t][k].param1 = old_event_byte2[j] >> 4;
tracks[t][k].param2 = old_event_byte2[j] & 15;
break;
case 'D': // fine volume slide
tracks[t][k].command = 14;
if (old_event_byte2[j] & 15)
{
// slide down
tracks[t][k].param1 = 5;
tracks[t][k].param2 = old_event_byte2[j] & 15;
}
else
{
// slide up
tracks[t][k].param1 = 4;
tracks[t][k].param2 = old_event_byte2[j] >> 4;
}
break;
case 'J': // arpeggio
tracks[t][k].param1 = old_event_byte2[j] >> 4;
tracks[t][k].param2 = old_event_byte2[j] & 15;
break;
}
}
t++;
}
}
delete [] module;
// order loop
restartpos = 0;
// order length
for (i=0;i<64;i++)
{
if (order[i] >= 0x80)
{
length = i;
break;
}
}
// default tempo
bpm = 0x7D;
rewind(0);
return true;
}
void CcffLoader::rewind(int subsong)
{
CmodPlayer::rewind(subsong);
// default instruments
for (int i=0;i<9;i++)
{
channel[i].inst = i;
channel[i].vol1 = 63 - (inst[i].data[10] & 63);
channel[i].vol2 = 63 - (inst[i].data[9] & 63);
}
}
std::string CcffLoader::gettype()
{
if (header.packed)
return std::string("BoomTracker 4, packed");
else
return std::string("BoomTracker 4");
}
std::string CcffLoader::gettitle()
{
return std::string(song_title,20);
}
std::string CcffLoader::getauthor()
{
return std::string(song_author,20);
}
std::string CcffLoader::getinstrument(unsigned int n)
{
return std::string(instruments[n].name);
}
unsigned int CcffLoader::getinstruments()
{
return 47;
}
/* -------- Private Methods ------------------------------- */
#ifdef _WIN32
#pragma warning(disable:4244)
#pragma warning(disable:4018)
#endif
/*
Lempel-Ziv-Tyr ;-)
*/
long CcffLoader::cff_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf)
{
if (memcmp(ibuf,"YsComp""\x07""CUD1997""\x1A\x04",16))
return 0;
input = ibuf + 16;
output = obuf;
output_length = 0;
heap = (unsigned char *)malloc(0x10000);
dictionary = (unsigned char **)malloc(sizeof(unsigned char *)*0x8000);
memset(heap,0,0x10000);
memset(dictionary,0,0x8000);
cleanup();
if(!startup())
goto out;
// LZW
while (1)
{
new_code = get_code();
// 0x00: end of data
if (new_code == 0)
break;
// 0x01: end of block
if (new_code == 1)
{
cleanup();
if(!startup())
goto out;
continue;
}
// 0x02: expand code length
if (new_code == 2)
{
code_length++;
continue;
}
// 0x03: RLE
if (new_code == 3)
{
unsigned char old_code_length = code_length;
code_length = 2;
unsigned char repeat_length = get_code() + 1;
code_length = 4 << get_code();
unsigned long repeat_counter = get_code();
if(output_length + repeat_counter * repeat_length > 0x10000) {
output_length = 0;
goto out;
}
for (unsigned int i=0;i= (0x104 + dictionary_length))
{
// dictionary <- old.code.string + old.code.char
the_string[++the_string[0]] = the_string[1];
}
else
{
// dictionary <- old.code.string + new.code.char
unsigned char temp_string[256];
translate_code(new_code,temp_string);
the_string[++the_string[0]] = temp_string[1];
}
expand_dictionary(the_string);
// output <- new.code.string
translate_code(new_code,the_string);
if(output_length + the_string[0] > 0x10000) {
output_length = 0;
goto out;
}
for (int i=0;i>= code_length;
bits_left -= code_length;
return code;
}
void CcffLoader::cff_unpacker::translate_code(unsigned long code, unsigned char *string)
{
unsigned char translated_string[256];
if (code >= 0x104)
{
memcpy(translated_string,dictionary[code - 0x104],(*(dictionary[code - 0x104])) + 1);
}
else
{
translated_string[0] = 1;
translated_string[1] = (code - 4) & 0xFF;
}
memcpy(string,translated_string,256);
}
void CcffLoader::cff_unpacker::cleanup()
{
code_length = 9;
bits_buffer = 0;
bits_left = 0;
heap_length = 0;
dictionary_length = 0;
}
int CcffLoader::cff_unpacker::startup()
{
old_code = get_code();
translate_code(old_code,the_string);
if(output_length + the_string[0] > 0x10000) {
output_length = 0;
return 0;
}
for (int i=0;i= 0xF0)
return;
memcpy(&heap[heap_length],string,string[0] + 1);
dictionary[dictionary_length] = &heap[heap_length];
dictionary_length++;
heap_length += (string[0] + 1);
}
#ifdef _WIN32
#pragma warning(default:4244)
#pragma warning(default:4018)
#endif
adplug-2.2.1+dfsg3/src/lds.h 0000644 0001750 0001750 00000006415 10126075072 015014 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2004 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* lds.h - LOUDNESS Player by Simon Peter
*/
#include "player.h"
class CldsPlayer: public CPlayer
{
public:
static CPlayer *factory(Copl *newopl) { return new CldsPlayer(newopl); }
CldsPlayer(Copl *newopl);
virtual ~CldsPlayer();
bool load(const std::string &filename, const CFileProvider &fp);
virtual bool update();
virtual void rewind(int subsong = -1);
float getrefresh() { return 70.0f; }
std::string gettype() { return std::string("LOUDNESS Sound System"); }
unsigned int getorders() { return numposi; }
unsigned int getorder() { return posplay; }
unsigned int getrow() { return pattplay; }
unsigned int getspeed() { return speed; }
unsigned int getinstruments() { return numpatch; }
private:
typedef struct {
unsigned char mod_misc, mod_vol, mod_ad, mod_sr, mod_wave,
car_misc, car_vol, car_ad, car_sr, car_wave, feedback, keyoff,
portamento, glide, finetune, vibrato, vibdelay, mod_trem, car_trem,
tremwait, arpeggio, arp_tab[12];
unsigned short start, size;
unsigned char fms;
unsigned short transp;
unsigned char midinst, midvelo, midkey, midtrans, middum1, middum2;
} SoundBank;
typedef struct {
unsigned short gototune, lasttune, packpos;
unsigned char finetune, glideto, portspeed, nextvol, volmod, volcar,
vibwait, vibspeed, vibrate, trmstay, trmwait, trmspeed, trmrate, trmcount,
trcwait, trcspeed, trcrate, trccount, arp_size, arp_speed, keycount,
vibcount, arp_pos, arp_count, packwait, arp_tab[12];
struct {
unsigned char chandelay, sound;
unsigned short high;
} chancheat;
} Channel;
typedef struct {
unsigned short patnum;
unsigned char transpose;
} Position;
static const unsigned short frequency[];
static const unsigned char vibtab[], tremtab[];
static const unsigned short maxsound, maxpos;
SoundBank *soundbank;
Channel channel[9];
Position *positions;
unsigned char fmchip[0xff], jumping, fadeonoff, allvolume, hardfade,
tempo_now, pattplay, tempo, regbd, chandelay[9], mode, pattlen;
unsigned short posplay, jumppos, *patterns, speed;
bool playing, songlooped;
unsigned int numpatch, numposi, patterns_size, mainvolume;
void playsound(int inst_number, int channel_number, int tunehigh);
inline void setregs(unsigned char reg, unsigned char val);
inline void setregs_adv(unsigned char reg, unsigned char mask,
unsigned char val);
};
adplug-2.2.1+dfsg3/src/rol.cpp 0000644 0001750 0001750 00000053267 11317336422 015372 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2006 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* rol.h - ROL Player by OPLx
*
* Visit: http://tenacity.hispeed.com/aomit/oplx/
*/
#include
#include
#include "rol.h"
#include "debug.h"
int const CrolPlayer::kSizeofDataRecord = 30;
int const CrolPlayer::kMaxTickBeat = 60;
int const CrolPlayer::kSilenceNote = -12;
int const CrolPlayer::kNumMelodicVoices = 9;
int const CrolPlayer::kNumPercussiveVoices = 11;
int const CrolPlayer::kBassDrumChannel = 6;
int const CrolPlayer::kSnareDrumChannel = 7;
int const CrolPlayer::kTomtomChannel = 8;
int const CrolPlayer::kTomtomFreq = 2;//4;
int const CrolPlayer::kSnareDrumFreq = 2;//kTomtomFreq + 7;
float const CrolPlayer::kDefaultUpdateTme = 18.2f;
float const CrolPlayer::kPitchFactor = 400.0f;
static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11};
CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] =
{
340, // C
363, // C#
385, // D
408, // D#
432, // E
458, // F
485, // F#
514, // G
544, // G#
577, // A
611, // A#
647 // B
};
/*** public methods **************************************/
CPlayer *CrolPlayer::factory(Copl *newopl)
{
return new CrolPlayer(newopl);
}
//---------------------------------------------------------
CrolPlayer::CrolPlayer(Copl *newopl)
: CPlayer ( newopl )
,rol_header ( NULL )
,mNextTempoEvent ( 0 )
,mCurrTick ( 0 )
,mTimeOfLastNote ( 0 )
,mRefresh ( kDefaultUpdateTme )
,bdRegister ( 0 )
{
int n;
memset(bxRegister, 0, sizeof(bxRegister) );
memset(volumeCache, 0, sizeof(volumeCache) );
memset(freqCache, 0, sizeof(freqCache) );
for(n=0; n<11; n++)
pitchCache[n]=1.0f;
}
//---------------------------------------------------------
CrolPlayer::~CrolPlayer()
{
if( rol_header != NULL )
{
delete rol_header;
rol_header=NULL;
}
}
//---------------------------------------------------------
bool CrolPlayer::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
char *fn = new char[filename.length()+12];
int i;
std::string bnk_filename;
AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str());
strcpy(fn,filename.data());
for (i=strlen(fn)-1; i>=0; i--)
if (fn[i] == '/' || fn[i] == '\\')
break;
strcpy(fn+i+1,"standard.bnk");
bnk_filename = fn;
delete [] fn;
AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str());
rol_header = new SRolHeader;
memset( rol_header, 0, sizeof(SRolHeader) );
rol_header->version_major = f->readInt( 2 );
rol_header->version_minor = f->readInt( 2 );
// Version check
if(rol_header->version_major != 0 || rol_header->version_minor != 4) {
AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n",
rol_header->version_major, rol_header->version_minor);
AdPlug_LogWrite("--- CrolPlayer::load ---\n");
fp.close(f);
return false;
}
f->seek( 40, binio::Add );
rol_header->ticks_per_beat = f->readInt( 2 );
rol_header->beats_per_measure = f->readInt( 2 );
rol_header->edit_scale_y = f->readInt( 2 );
rol_header->edit_scale_x = f->readInt( 2 );
f->seek( 1, binio::Add );
rol_header->mode = f->readInt(1);
f->seek( 90+38+15, binio::Add );
rol_header->basic_tempo = f->readFloat( binio::Single );
load_tempo_events( f );
mTimeOfLastNote = 0;
if( load_voice_data( f, bnk_filename, fp ) != true )
{
AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n");
AdPlug_LogWrite("--- CrolPlayer::load ---\n");
fp.close( f );
return false;
}
fp.close( f );
rewind( 0 );
AdPlug_LogWrite("--- CrolPlayer::load ---\n");
return true;
}
//---------------------------------------------------------
bool CrolPlayer::update()
{
if( mNextTempoEvent < mTempoEvents.size() &&
mTempoEvents[mNextTempoEvent].time == mCurrTick )
{
SetRefresh( mTempoEvents[mNextTempoEvent].multiplier );
++mNextTempoEvent;
}
TVoiceData::iterator curr = voice_data.begin();
TVoiceData::iterator end = voice_data.end();
int voice = 0;
while( curr != end )
{
UpdateVoice( voice, *curr );
++curr;
++voice;
}
++mCurrTick;
if( mCurrTick > mTimeOfLastNote )
{
return false;
}
return true;
//return ( mCurrTick > mTimeOfLastNote ) ? false : true;
}
//---------------------------------------------------------
void CrolPlayer::rewind( int subsong )
{
TVoiceData::iterator curr = voice_data.begin();
TVoiceData::iterator end = voice_data.end();
while( curr != end )
{
CVoiceData &voice = *curr;
voice.Reset();
++curr;
}
memset(bxRegister, 0, sizeof(bxRegister) );
memset(volumeCache, 0, sizeof(volumeCache) );
bdRegister = 0;
opl->init(); // initialize to melodic by default
opl->write(1,0x20); // Enable waveform select (bit 5)
if( rol_header->mode == 0 )
{
opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5)
bdRegister = 0x20;
SetFreq( kTomtomChannel, 24 );
SetFreq( kSnareDrumChannel, 31 );
}
mNextTempoEvent = 0;
mCurrTick = 0;
SetRefresh(1.0f);
}
//---------------------------------------------------------
inline float fmin( int const a, int const b )
{
return static_cast( a < b ? a : b );
}
//---------------------------------------------------------
void CrolPlayer::SetRefresh( float const multiplier )
{
float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat);
mRefresh = (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f;
}
//---------------------------------------------------------
float CrolPlayer::getrefresh()
{
return mRefresh;
}
//---------------------------------------------------------
void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData )
{
TNoteEvents const &nEvents = voiceData.note_events;
if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd )
{
return; // no note data to process, don't bother doing anything.
}
TInstrumentEvents &iEvents = voiceData.instrument_events;
TVolumeEvents &vEvents = voiceData.volume_events;
TPitchEvents &pEvents = voiceData.pitch_events;
if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) &&
iEvents[voiceData.next_instrument_event].time == mCurrTick )
{
if( voiceData.next_instrument_event < iEvents.size() )
{
send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index );
++voiceData.next_instrument_event;
}
else
{
voiceData.mEventStatus |= CVoiceData::kES_InstrEnd;
}
}
if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) &&
vEvents[voiceData.next_volume_event].time == mCurrTick )
{
SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event];
if( voiceData.next_volume_event < vEvents.size() )
{
int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier));
SetVolume( voice, volume );
++voiceData.next_volume_event; // move to next volume event
}
else
{
voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd;
}
}
if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 )
{
if( mCurrTick != 0 )
{
++voiceData.current_note;
}
if( voiceData.current_note < nEvents.size() )
{
SNoteEvent const ¬eEvent = nEvents[voiceData.current_note];
SetNote( voice, noteEvent.number );
voiceData.current_note_duration = 0;
voiceData.mNoteDuration = noteEvent.duration;
voiceData.mForceNote = false;
}
else
{
SetNote( voice, kSilenceNote );
voiceData.mEventStatus |= CVoiceData::kES_NoteEnd;
return;
}
}
if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) &&
pEvents[voiceData.next_pitch_event].time == mCurrTick )
{
if( voiceData.next_pitch_event < pEvents.size() )
{
SetPitch(voice,pEvents[voiceData.next_pitch_event].variation);
++voiceData.next_pitch_event;
}
else
{
voiceData.mEventStatus |= CVoiceData::kES_PitchEnd;
}
}
++voiceData.current_note_duration;
}
//---------------------------------------------------------
void CrolPlayer::SetNote( int const voice, int const note )
{
if( voice < kBassDrumChannel || rol_header->mode )
{
SetNoteMelodic( voice, note );
}
else
{
SetNotePercussive( voice, note );
}
}
//---------------------------------------------------------
void CrolPlayer::SetNotePercussive( int const voice, int const note )
{
int const bit_pos = 4-voice+kBassDrumChannel;
bdRegister &= ~( 1<write( 0xbd, bdRegister );
if( note != kSilenceNote )
{
switch( voice )
{
case kTomtomChannel:
SetFreq( kSnareDrumChannel, note+7 );
case kBassDrumChannel:
SetFreq( voice, note );
break;
}
bdRegister |= 1<write( 0xbd, bdRegister );
}
}
//---------------------------------------------------------
void CrolPlayer::SetNoteMelodic( int const voice, int const note )
{
opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 );
if( note != kSilenceNote )
{
SetFreq( voice, note, true );
}
}
//---------------------------------------------------------
void CrolPlayer::SetPitch(int const voice, real32 const variation)
{
pitchCache[voice] = variation;
freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor);
opl->write(0xa0+voice,freqCache[voice] & 0xff);
}
//---------------------------------------------------------
void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn )
{
uint16 freq = kNoteTable[note%12] + ((note/12) << 10);
freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor);
freqCache[voice] = freq;
bxRegister[voice] = ((freq >> 8) & 0x1f);
opl->write( 0xa0+voice, freq & 0xff );
opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) );
}
//---------------------------------------------------------
void CrolPlayer::SetVolume( int const voice, int const volume )
{
volumeCache[voice] = (volumeCache[voice] &0xc0) | volume;
int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ?
op_table[voice]+3 : drum_table[voice-kSnareDrumChannel];
opl->write( 0x40+op_offset, volumeCache[voice] );
}
//---------------------------------------------------------
void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index )
{
SRolInstrument &instrument = ins_list[ins_index].instrument;
send_operator( voice, instrument.modulator, instrument.carrier );
}
//---------------------------------------------------------
void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier )
{
if( voice < kSnareDrumChannel || rol_header->mode )
{
int const op_offset = op_table[voice];
opl->write( 0x20+op_offset, modulator.ammulti );
opl->write( 0x40+op_offset, modulator.ksltl );
opl->write( 0x60+op_offset, modulator.ardr );
opl->write( 0x80+op_offset, modulator.slrr );
opl->write( 0xc0+voice , modulator.fbc );
opl->write( 0xe0+op_offset, modulator.waveform );
volumeCache[voice] = (carrier.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
opl->write( 0x23+op_offset, carrier.ammulti );
opl->write( 0x43+op_offset, volumeCache[voice] );
opl->write( 0x63+op_offset, carrier.ardr );
opl->write( 0x83+op_offset, carrier.slrr );
// opl->write( 0xc3+voice , carrier.fbc ); <- don't bother writing this.
opl->write( 0xe3+op_offset, carrier.waveform );
}
else
{
int const op_offset = drum_table[voice-kSnareDrumChannel];
volumeCache[voice] = (modulator.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
opl->write( 0x20+op_offset, modulator.ammulti );
opl->write( 0x40+op_offset, volumeCache[voice] );
opl->write( 0x60+op_offset, modulator.ardr );
opl->write( 0x80+op_offset, modulator.slrr );
opl->write( 0xc0+voice , modulator.fbc );
opl->write( 0xe0+op_offset, modulator.waveform );
}
}
//---------------------------------------------------------
void CrolPlayer::load_tempo_events( binistream *f )
{
int16 const num_tempo_events = f->readInt( 2 );
mTempoEvents.reserve( num_tempo_events );
for(int i=0; ireadInt( 2 );
event.multiplier = f->readFloat( binio::Single );
mTempoEvents.push_back( event );
}
}
//---------------------------------------------------------
bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp )
{
SBnkHeader bnk_header;
binistream *bnk_file = fp.open( bnk_filename.c_str() );
if( bnk_file )
{
load_bnk_info( bnk_file, bnk_header );
int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices;
voice_data.reserve( numVoices );
for(int i=0; iseek( 15, binio::Add );
int16 const time_of_last_note = f->readInt( 2 );
if( time_of_last_note != 0 )
{
TNoteEvents ¬e_events = voice.note_events;
int16 total_duration = 0;
do
{
SNoteEvent event;
event.number = f->readInt( 2 );
event.duration = f->readInt( 2 );
event.number += kSilenceNote; // adding -12
note_events.push_back( event );
total_duration += event.duration;
} while( total_duration < time_of_last_note );
if( time_of_last_note > mTimeOfLastNote )
{
mTimeOfLastNote = time_of_last_note;
}
}
f->seek( 15, binio::Add );
}
//---------------------------------------------------------
void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice,
binistream *bnk_file, SBnkHeader const &bnk_header )
{
int16 const number_of_instrument_events = f->readInt( 2 );
TInstrumentEvents &instrument_events = voice.instrument_events;
instrument_events.reserve( number_of_instrument_events );
for(int i=0; ireadInt( 2 );
f->readString( event.name, 9 );
std::string event_name = event.name;
event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name );
instrument_events.push_back( event );
f->seek( 1+2, binio::Add );
}
f->seek( 15, binio::Add );
}
//---------------------------------------------------------
void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice )
{
int16 const number_of_volume_events = f->readInt( 2 );
TVolumeEvents &volume_events = voice.volume_events;
volume_events.reserve( number_of_volume_events );
for(int i=0; ireadInt( 2 );
event.multiplier = f->readFloat( binio::Single );
volume_events.push_back( event );
}
f->seek( 15, binio::Add );
}
//---------------------------------------------------------
void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice )
{
int16 const number_of_pitch_events = f->readInt( 2 );
TPitchEvents &pitch_events = voice.pitch_events;
pitch_events.reserve( number_of_pitch_events );
for(int i=0; ireadInt( 2 );
event.variation = f->readFloat( binio::Single );
pitch_events.push_back( event );
}
}
//---------------------------------------------------------
bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header )
{
header.version_major = f->readInt(1);
header.version_minor = f->readInt(1);
f->readString( header.signature, 6 );
header.number_of_list_entries_used = f->readInt( 2 );
header.total_number_of_list_entries = f->readInt( 2 );
header.abs_offset_of_name_list = f->readInt( 4 );
header.abs_offset_of_data = f->readInt( 4 );
f->seek( header.abs_offset_of_name_list, binio::Set );
TInstrumentNames &ins_name_list = header.ins_name_list;
ins_name_list.reserve( header.number_of_list_entries_used );
for(int i=0; ireadInt( 2 );
instrument.record_used = f->readInt(1);
f->readString( instrument.name, 9 );
// printf("%s = #%d\n", instrument.name, i );
ins_name_list.push_back( instrument );
}
//std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() );
return true;
}
//---------------------------------------------------------
int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name )
{
TInstrumentNames const &ins_name_list = header.ins_name_list;
int const ins_index = get_ins_index( name );
if( ins_index != -1 )
{
return ins_index;
}
typedef TInstrumentNames::const_iterator TInsIter;
typedef std::pair TInsIterPair;
TInsIterPair range = std::equal_range( ins_name_list.begin(),
ins_name_list.end(),
name,
StringCompare() );
if( range.first != range.second )
{
int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord);
f->seek( seekOffs, binio::Set );
}
SUsedList usedIns;
usedIns.name = name;
if( range.first != range.second )
{
read_rol_instrument( f, usedIns.instrument );
}
else
{
// set up default instrument data here
memset( &usedIns.instrument, 0, sizeof(SRolInstrument) );
}
ins_list.push_back( usedIns );
return ins_list.size()-1;
}
//---------------------------------------------------------
int CrolPlayer::get_ins_index( std::string const &name ) const
{
for(unsigned int i=0; ireadInt(1);
ins.voice_number = f->readInt(1);
read_fm_operator( f, ins.modulator );
read_fm_operator( f, ins.carrier );
ins.modulator.waveform = f->readInt(1);
ins.carrier.waveform = f->readInt(1);
}
//---------------------------------------------------------
void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op )
{
SFMOperator fm_op;
fm_op.key_scale_level = f->readInt(1);
fm_op.freq_multiplier = f->readInt(1);
fm_op.feed_back = f->readInt(1);
fm_op.attack_rate = f->readInt(1);
fm_op.sustain_level = f->readInt(1);
fm_op.sustaining_sound = f->readInt(1);
fm_op.decay_rate = f->readInt(1);
fm_op.release_rate = f->readInt(1);
fm_op.output_level = f->readInt(1);
fm_op.amplitude_vibrato = f->readInt(1);
fm_op.frequency_vibrato = f->readInt(1);
fm_op.envelope_scaling = f->readInt(1);
fm_op.fm_type = f->readInt(1);
opl2_op.ammulti = fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op.sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op.freq_multiplier;
opl2_op.ksltl = fm_op.key_scale_level << 6 | fm_op.output_level;
opl2_op.ardr = fm_op.attack_rate << 4 | fm_op.decay_rate;
opl2_op.slrr = fm_op.sustain_level << 4 | fm_op.release_rate;
opl2_op.fbc = fm_op.feed_back << 1 | (fm_op.fm_type ^ 1);
}
adplug-2.2.1+dfsg3/src/kemuopl.h 0000644 0001750 0001750 00000003155 10324236534 015706 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* kemuopl.h - Emulated OPL using Ken Silverman's emulator, by Simon Peter
*
*/
#ifndef H_ADPLUG_KEMUOPL
#define H_ADPLUG_KEMUOPL
#include "opl.h"
extern "C" {
#include "adlibemu.h"
}
class CKemuopl: public Copl
{
public:
CKemuopl(int rate, bool bit16, bool usestereo)
: use16bit(bit16), stereo(usestereo)
{
adlibinit(rate, usestereo ? 2 : 1, bit16 ? 2 : 1);
currType = TYPE_OPL2;
};
void update(short *buf, int samples)
{
if(use16bit) samples *= 2;
if(stereo) samples *= 2;
adlibgetsample(buf, samples);
}
// template methods
void write(int reg, int val)
{
if(currChip == 0)
adlib0(reg, val);
};
void init() {};
private:
bool use16bit,stereo;
};
#endif
adplug-2.2.1+dfsg3/src/realopl.h 0000644 0001750 0001750 00000004505 10324236534 015670 0 ustar gregoa gregoa /*
* AdPlug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* realopl.h - Real hardware OPL, by Simon Peter
*/
#ifndef H_ADPLUG_REALOPL
#define H_ADPLUG_REALOPL
#include "opl.h"
#define DFL_ADLIBPORT 0x388 // default adlib baseport
class CRealopl: public Copl
{
public:
CRealopl(unsigned short initport = DFL_ADLIBPORT); // initport = OPL2 hardware baseport
bool detect(); // returns true if adlib compatible board is found, else false
void setvolume(int volume); // set adlib master volume (0 - 63) 0 = loudest, 63 = softest
void setquiet(bool quiet = true); // sets the OPL2 quiet, while still writing to the registers
void setport(unsigned short port) // set new OPL2 hardware baseport
{
adlport = port;
}
void setnowrite(bool nw = true) // set hardware write status
{
nowrite = nw;
}
int getvolume() // get adlib master volume
{
return hardvol;
}
// template methods
void write(int reg, int val);
void init();
void settype(ChipType type)
{
currType = type;
}
protected:
void hardwrite(int reg, int val); // write to OPL2 hardware registers
bool harddetect(); // do real hardware detection
static const unsigned char op_table[9]; // the 9 operators as expected by the OPL2
unsigned short adlport; // adlib hardware baseport
int hardvol, oldvol; // hardware master volume
bool bequiet; // quiet status cache
char hardvols[2][22][2]; // volume cache
bool nowrite; // don't write to hardware, if true
};
#endif
adplug-2.2.1+dfsg3/src/Makefile.in 0000644 0001750 0001750 00000060541 11356523226 016133 0 ustar gregoa gregoa # Makefile.in generated by automake 1.11.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src
DIST_COMMON = $(pkginclude_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgincludedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libadplug_la_LIBADD =
am_libadplug_la_OBJECTS = adplug.lo emuopl.lo fmopl.lo diskopl.lo \
debug.lo fprovide.lo player.lo database.lo hsc.lo sng.lo \
imf.lo players.lo protrack.lo a2m.lo adtrack.lo amd.lo bam.lo \
d00.lo dfm.lo hsp.lo ksm.lo mad.lo mid.lo mkj.lo cff.lo dmo.lo \
s3m.lo dtm.lo fmc.lo mtk.lo rad.lo raw.lo sa2.lo xad.lo \
flash.lo bmf.lo hybrid.lo hyp.lo psi.lo rat.lo u6m.lo rol.lo \
xsm.lo adlibemu.lo dro.lo lds.lo realopl.lo analopl.lo \
temuopl.lo msc.lo rix.lo adl.lo jbm.lo cmf.lo surroundopl.lo \
dro2.lo
libadplug_la_OBJECTS = $(am_libadplug_la_OBJECTS)
libadplug_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libadplug_la_LDFLAGS) $(LDFLAGS) -o $@
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(libadplug_la_SOURCES)
DIST_SOURCES = $(libadplug_la_SOURCES)
HEADERS = $(pkginclude_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETOPT_SOURCES = @GETOPT_SOURCES@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libbinio_CFLAGS = @libbinio_CFLAGS@
libbinio_LIBS = @libbinio_LIBS@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libadplug.la
libadplug_la_SOURCES = adplug.cpp emuopl.cpp fmopl.c diskopl.cpp debug.c \
debug.h fprovide.cpp player.cpp database.cpp hsc.cpp sng.cpp imf.cpp \
players.cpp protrack.cpp a2m.cpp adtrack.cpp amd.cpp bam.cpp d00.cpp dfm.cpp \
hsp.cpp ksm.cpp mad.cpp mid.cpp mkj.cpp cff.cpp dmo.cpp s3m.cpp dtm.cpp \
fmc.cpp mtk.cpp rad.cpp raw.cpp sa2.cpp xad.cpp flash.cpp bmf.cpp hybrid.cpp \
hyp.cpp psi.cpp rat.cpp u6m.cpp rol.cpp mididata.h xsm.cpp adlibemu.c dro.cpp \
lds.cpp realopl.cpp analopl.cpp temuopl.cpp msc.cpp rix.cpp adl.cpp jbm.cpp \
cmf.cpp surroundopl.cpp dro2.cpp
libadplug_la_LDFLAGS = -release @VERSION@ -version-info 0 $(libbinio_LIBS)
# -Dstricmp=strcasecmp is a hack. Throughout AdPlug, stricmp() is used to do
# caseless string comparations. UNIX libcs don't support stricmp(), but do
# support the BSD strcasecmp(), so we have to replace every occurence of
# stricmp() into strcasecmp(). stricmp() seems to be Windows, but maybe
# also POSIX...
AM_CPPFLAGS = -Dstricmp=strcasecmp $(libbinio_CFLAGS)
pkginclude_HEADERS = adplug.h emuopl.h fmopl.h silentopl.h opl.h diskopl.h \
a2m.h amd.h bam.h d00.h dfm.h hsc.h hsp.h imf.h ksm.h lds.h mid.h mkj.h \
mtk.h protrack.h rad.h raw.h s3m.h sa2.h sng.h u6m.h player.h fmc.h mad.h \
xad.h bmf.h flash.h hyp.h psi.h rat.h hybrid.h rol.h adtrack.h cff.h dtm.h \
dmo.h fprovide.h database.h players.h xsm.h adlibemu.h kemuopl.h dro.h \
realopl.h analopl.h temuopl.h msc.h rix.h adl.h jbm.h cmf.h surroundopl.h \
dro2.h
all: all-am
.SUFFIXES:
.SUFFIXES: .c .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libadplug.la: $(libadplug_la_OBJECTS) $(libadplug_la_DEPENDENCIES)
$(libadplug_la_LINK) -rpath $(libdir) $(libadplug_la_OBJECTS) $(libadplug_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/a2m.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adlibemu.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adplug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adtrack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/amd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/analopl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bam.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cff.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/d00.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dfm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskopl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dro.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dro2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emuopl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flash.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmopl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fprovide.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hsc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hsp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hybrid.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hyp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jbm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ksm.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lds.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mad.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mid.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkj.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/msc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mtk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/player.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/players.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protrack.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rad.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/realopl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rol.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/s3m.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sa2.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sng.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/surroundopl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/temuopl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/u6m.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xad.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xsm.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
.cpp.o:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-pkgincludeHEADERS: $(pkginclude_HEADERS)
@$(NORMAL_INSTALL)
test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
done
uninstall-pkgincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
test -n "$$files" || exit 0; \
echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \
cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-pkgincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-pkgincludeHEADERS install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-libLTLIBRARIES uninstall-pkgincludeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
adplug-2.2.1+dfsg3/src/protrack.h 0000644 0001750 0001750 00000006750 10606235013 016055 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* protrack.h - Generic Protracker Player by Simon Peter
*/
#ifndef H_PROTRACK
#define H_PROTRACK
#include "player.h"
class CmodPlayer: public CPlayer
{
public:
CmodPlayer(Copl *newopl);
virtual ~CmodPlayer();
bool update();
void rewind(int subsong);
float getrefresh();
unsigned int getpatterns()
{ return nop; }
unsigned int getpattern()
{ return order[ord]; }
unsigned int getorders()
{ return length; }
unsigned int getorder()
{ return ord; }
unsigned int getrow()
{ return rw; }
unsigned int getspeed()
{ return speed; }
protected:
enum Flags {
Standard = 0,
Decimal = 1 << 0,
Faust = 1 << 1,
NoKeyOn = 1 << 2,
Opl3 = 1 << 3,
Tremolo = 1 << 4,
Vibrato = 1 << 5,
Percussion = 1 << 6
};
struct Instrument {
unsigned char data[11],arpstart,arpspeed,arppos,arpspdcnt,misc;
signed char slide;
} *inst;
struct Tracks {
unsigned char note,command,inst,param2,param1;
} **tracks;
unsigned char *order, *arplist, *arpcmd, initspeed;
unsigned short tempo, **trackord, bpm, nop;
unsigned long length, restartpos, activechan;
int flags, curchip;
struct Channel {
unsigned short freq,nextfreq;
unsigned char oct,vol1,vol2,inst,fx,info1,info2,key,nextoct,
note,portainfo,vibinfo1,vibinfo2,arppos,arpspdcnt;
signed char trigger;
} *channel;
void init_trackord();
bool init_specialarp();
void init_notetable(const unsigned short *newnotetable);
bool realloc_order(unsigned long len);
bool realloc_patterns(unsigned long pats, unsigned long rows, unsigned long chans);
bool realloc_instruments(unsigned long len);
void dealloc();
private:
static const unsigned short sa2_notetable[12];
static const unsigned char vibratotab[32];
unsigned char speed, del, songend, regbd;
unsigned short rows, notetable[12];
unsigned long rw, ord, nrows, npats, nchans;
void setvolume(unsigned char chan);
void setvolume_alt(unsigned char chan);
void setfreq(unsigned char chan);
void playnote(unsigned char chan);
void setnote(unsigned char chan, int note);
void slide_down(unsigned char chan, int amount);
void slide_up(unsigned char chan, int amount);
void tone_portamento(unsigned char chan, unsigned char info);
void vibrato(unsigned char chan, unsigned char speed, unsigned char depth);
void vol_up(unsigned char chan, int amount);
void vol_down(unsigned char chan, int amount);
void vol_up_alt(unsigned char chan, int amount);
void vol_down_alt(unsigned char chan, int amount);
void dealloc_patterns();
bool resolve_order();
unsigned char set_opl_chip(unsigned char chan);
};
#endif
adplug-2.2.1+dfsg3/src/analopl.cpp 0000644 0001750 0001750 00000003565 10423014507 016212 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2006 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* analopl.cpp - Spectrum analyzing hardware OPL, by Simon Peter
*/
#include "analopl.h"
CAnalopl::CAnalopl(unsigned short initport)
: CRealopl(initport)
{
for(int i = 0; i < 9; i++) {
keyregs[0][i][0] = 0;
keyregs[0][i][1] = 0;
keyregs[1][i][0] = 0;
keyregs[1][i][1] = 0;
}
}
void CAnalopl::write(int reg, int val)
{
if(nowrite) return;
if(reg >= 0xb0 && reg <= 0xb8) {
if(!keyregs[currChip][reg - 0xb0][0] && (val & 32))
keyregs[currChip][reg - 0xb0][1] = 1;
else
keyregs[currChip][reg - 0xb0][1] = 0;
keyregs[currChip][reg - 0xb0][0] = val & 32;
}
CRealopl::write(reg, val);
}
int CAnalopl::getcarriervol(unsigned int v, unsigned int c)
{
return (hardvols[c][op_table[v]+3][0] & 63);
}
int CAnalopl::getmodulatorvol(unsigned int v, unsigned int c)
{
return (hardvols[c][op_table[v]][0] & 63);
}
bool CAnalopl::getkeyon(unsigned int v, unsigned int c)
{
if(keyregs[c][v][1]) {
keyregs[c][v][1] = 0;
return true;
} else
return false;
}
adplug-2.2.1+dfsg3/src/mid.cpp 0000644 0001750 0001750 00000104405 11063156602 015334 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2008 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* MIDI & MIDI-like file player - Last Update: 10/15/2005
* by Phil Hassey - www.imitationpickles.org
* philhassey@hotmail.com
*
* Can play the following
* .LAA - a raw save of a Lucas Arts Adlib music
* or
* a raw save of a LucasFilm Adlib music
* .MID - a "midi" save of a Lucas Arts Adlib music
* - or general MIDI files
* .CMF - Creative Music Format
* .SCI - the sierra "midi" format.
* Files must be in the form
* xxxNAME.sci
* So that the loader can load the right patch file:
* xxxPATCH.003 (patch.003 must be saved from the
* sierra resource from each game.)
*
* 6/2/2000: v1.0 relased by phil hassey
* Status: LAA is almost perfect
* - some volumes are a bit off (intrument too quiet)
* MID is fine (who wants to listen to MIDI vid adlib anyway)
* CMF is okay (still needs the adlib rythm mode implemented
* for real)
* 6/6/2000:
* Status: SCI: there are two SCI formats, orginal and advanced.
* original: (Found in SCI/EGA Sierra Adventures)
* played almost perfectly, I believe
* there is one mistake in the instrument
* loader that causes some sounds to
* not be quite right. Most sounds are fine.
* advanced: (Found in SCI/VGA Sierra Adventures)
* These are multi-track files. (Thus the
* player had to be modified to work with
* them.) This works fine.
* There are also multiple tunes in each file.
* I think some of them are supposed to be
* played at the same time, but I'm not sure
* when.
* 8/16/2000:
* Status: LAA: now EGA and VGA lucas games work pretty well
*
* 10/15/2005: Changes by Simon Peter
* Added rhythm mode support for CMF format.
*
* 09/13/2008: Changes by Adam Nielsen (malvineous@shikadi.net)
* Fixed a couple of CMF rhythm mode bugs
* Disabled note velocity for CMF files
* Added support for nonstandard CMF AM+VIB controller (for VGFM CMFs)
*
* Other acknowledgements:
* Allegro - for the midi instruments and the midi volume table
* SCUMM Revisited - for getting the .LAA / .MIDs out of those
* LucasArts files.
* FreeSCI - for some information on the sci music files
* SD - the SCI Decoder (to get all .sci out of the Sierra files)
*/
#include
#include
#include
#include
#include "mid.h"
#include "mididata.h"
/*#define TESTING*/
#ifdef TESTING
#define midiprintf printf
#else
void CmidPlayer::midiprintf(const char *format, ...)
{
}
#endif
#define LUCAS_STYLE 1
#define CMF_STYLE 2
#define MIDI_STYLE 4
#define SIERRA_STYLE 8
// AdLib melodic and rhythm mode defines
#define ADLIB_MELODIC 0
#define ADLIB_RYTHM 1
// File types
#define FILE_LUCAS 1
#define FILE_MIDI 2
#define FILE_CMF 3
#define FILE_SIERRA 4
#define FILE_ADVSIERRA 5
#define FILE_OLDLUCAS 6
// AdLib standard operator table
const unsigned char CmidPlayer::adlib_opadd[] = {0x00 ,0x01 ,0x02 ,0x08 ,0x09 ,0x0A ,0x10 ,0x11 ,0x12};
// map CMF drum channels 12 - 15 to corresponding AdLib drum operators
// bass drum (channel 11) not mapped, cause it's handled like a normal instrument
const int CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 };
// Standard AdLib frequency table
const int CmidPlayer::fnums[] = { 0x16b,0x181,0x198,0x1b0,0x1ca,0x1e5,0x202,0x220,0x241,0x263,0x287,0x2ae };
// Map CMF drum channels 11 - 15 to corresponding AdLib drum channels
const int CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 };
CPlayer *CmidPlayer::factory(Copl *newopl)
{
return new CmidPlayer(newopl);
}
CmidPlayer::CmidPlayer(Copl *newopl)
: CPlayer(newopl), author(&emptystr), title(&emptystr), remarks(&emptystr),
emptystr('\0'), flen(0), data(0)
{
}
unsigned char CmidPlayer::datalook(long pos)
{
if (pos<0 || pos >= flen) return(0);
return(data[pos]);
}
unsigned long CmidPlayer::getnexti(unsigned long num)
{
unsigned long v=0;
unsigned long i;
for (i=0; i= 0; i--)
if(pfilename[i] == '/' || pfilename[i] == '\\') {
j = i+1;
break;
}
sprintf(pfilename+j+3,"patch.003");
f = fp.open(pfilename);
free(pfilename);
if(!f) return false;
f->ignore(2);
stins = 0;
for (i=0; i<2; i++)
{
for (k=0; k<48; k++)
{
l=i*48+k;
midiprintf ("\n%2d: ",l);
for (j=0; j<28; j++)
ins[j] = f->readInt(1);
myinsbank[l][0]=
(ins[9]*0x80) + (ins[10]*0x40) +
(ins[5]*0x20) + (ins[11]*0x10) +
ins[1]; //1=ins5
myinsbank[l][1]=
(ins[22]*0x80) + (ins[23]*0x40) +
(ins[18]*0x20) + (ins[24]*0x10) +
ins[14]; //1=ins18
myinsbank[l][2]=(ins[0]<<6)+ins[8];
myinsbank[l][3]=(ins[13]<<6)+ins[21];
myinsbank[l][4]=(ins[3]<<4)+ins[6];
myinsbank[l][5]=(ins[16]<<4)+ins[19];
myinsbank[l][6]=(ins[4]<<4)+ins[7];
myinsbank[l][7]=(ins[17]<<4)+ins[20];
myinsbank[l][8]=ins[26];
myinsbank[l][9]=ins[27];
myinsbank[l][10]=((ins[2]<<1))+(1-(ins[12]&1));
//(ins[12] ? 0:1)+((ins[2]<<1));
for (j=0; j<11; j++)
midiprintf ("%02X ",myinsbank[l][j]);
stins++;
}
f->ignore(2);
}
fp.close(f);
memcpy(smyinsbank, myinsbank, 128 * 16);
return true;
}
void CmidPlayer::sierra_next_section()
{
int i,j;
for (i=0; i<16; i++)
track[i].on=0;
midiprintf("\n\nnext adv sierra section:\n");
pos=sierra_pos;
i=0;j=0;
while (i!=0xff)
{
getnext(1);
curtrack=j; j++;
track[curtrack].on=1;
track[curtrack].spos = getnext(1);
track[curtrack].spos += (getnext(1) << 8) + 4; //4 best usually +3? not 0,1,2 or 5
// track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4; // dynamite!: doesn't optimize correctly!!
track[curtrack].tend=flen; //0xFC will kill it
track[curtrack].iwait=0;
track[curtrack].pv=0;
midiprintf ("track %d starts at %lx\n",curtrack,track[curtrack].spos);
getnext(2);
i=getnext(1);
}
getnext(2);
deltas=0x20;
sierra_pos=pos;
//getch();
fwait=0;
doing=1;
}
bool CmidPlayer::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
int good;
unsigned char s[6];
f->readString((char *)s, 6);
good=0;
subsongs=0;
switch(s[0])
{
case 'A':
if (s[1]=='D' && s[2]=='L') good=FILE_LUCAS;
break;
case 'M':
if (s[1]=='T' && s[2]=='h' && s[3]=='d') good=FILE_MIDI;
break;
case 'C':
if (s[1]=='T' && s[2]=='M' && s[3]=='F') good=FILE_CMF;
break;
case 0x84:
if (s[1]==0x00 && load_sierra_ins(filename, fp)) {
if (s[2]==0xf0)
good=FILE_ADVSIERRA;
else
good=FILE_SIERRA;
}
break;
default:
if (s[4]=='A' && s[5]=='D') good=FILE_OLDLUCAS;
break;
}
if (good!=0)
subsongs=1;
else {
fp.close(f);
return false;
}
type=good;
f->seek(0);
flen = fp.filesize(f);
data = new unsigned char [flen];
f->readString((char *)data, flen);
fp.close(f);
rewind(0);
return true;
}
void CmidPlayer::midi_write_adlib(unsigned int r, unsigned char v)
{
opl->write(r,v);
adlib_data[r]=v;
}
void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst)
{
if ((adlib_style&SIERRA_STYLE)!=0)
midi_write_adlib(0xbd,0); //just gotta make sure this happens..
//'cause who knows when it'll be
//reset otherwise.
midi_write_adlib(0x20+adlib_opadd[voice],inst[0]);
midi_write_adlib(0x23+adlib_opadd[voice],inst[1]);
if (adlib_style & LUCAS_STYLE) {
midi_write_adlib(0x43+adlib_opadd[voice],0x3f);
if ((inst[10] & 1)==0)
midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
else
midi_write_adlib(0x40+adlib_opadd[voice],0x3f);
} else if ((adlib_style & SIERRA_STYLE) || (adlib_style & CMF_STYLE)) {
midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
} else {
midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
if ((inst[10] & 1)==0)
midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
else
midi_write_adlib(0x43+adlib_opadd[voice],0);
}
midi_write_adlib(0x60+adlib_opadd[voice],inst[4]);
midi_write_adlib(0x63+adlib_opadd[voice],inst[5]);
midi_write_adlib(0x80+adlib_opadd[voice],inst[6]);
midi_write_adlib(0x83+adlib_opadd[voice],inst[7]);
midi_write_adlib(0xe0+adlib_opadd[voice],inst[8]);
midi_write_adlib(0xe3+adlib_opadd[voice],inst[9]);
midi_write_adlib(0xc0+voice,inst[10]);
}
void CmidPlayer::midi_fm_percussion(int ch, unsigned char *inst)
{
int opadd = map_chan[ch - 12];
midi_write_adlib(0x20 + opadd, inst[0]);
midi_write_adlib(0x40 + opadd, inst[2]);
midi_write_adlib(0x60 + opadd, inst[4]);
midi_write_adlib(0x80 + opadd, inst[6]);
midi_write_adlib(0xe0 + opadd, inst[8]);
if (opadd < 0x13) // only output this for the modulator, not the carrier, as it affects the entire channel
midi_write_adlib(0xc0 + percussion_map[ch - 11], inst[10]);
}
void CmidPlayer::midi_fm_volume(int voice, int volume)
{
int vol;
if ((adlib_style&SIERRA_STYLE)==0) //sierra likes it loud!
{
vol=volume>>2;
if ((adlib_style&LUCAS_STYLE)!=0)
{
if ((adlib_data[0xc0+voice]&1)==1)
midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) |
(adlib_data[0x40+adlib_opadd[voice]]&0xc0)));
midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
(adlib_data[0x43+adlib_opadd[voice]]&0xc0)));
}
else
{
if ((adlib_data[0xc0+voice]&1)==1)
midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) |
(adlib_data[0x40+adlib_opadd[voice]]&0xc0)));
midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
(adlib_data[0x43+adlib_opadd[voice]]&0xc0)));
}
}
}
void CmidPlayer::midi_fm_playnote(int voice, int note, int volume)
{
int freq=fnums[note%12];
int oct=note/12;
int c;
midi_fm_volume(voice,volume);
midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff));
c=((freq&0x300) >> 8)+((oct&7)<<2) + (adlib_mode == ADLIB_MELODIC || voice < 6 ? (1<<5) : 0);
midi_write_adlib(0xb0+voice,(unsigned char)c);
}
void CmidPlayer::midi_fm_endnote(int voice)
{
//midi_fm_volume(voice,0);
//midi_write_adlib(0xb0+voice,0);
midi_write_adlib(0xb0+voice,(unsigned char)(adlib_data[0xb0+voice]&(255-32)));
}
void CmidPlayer::midi_fm_reset()
{
int i;
opl->init();
for (i=0; i<256; i++)
midi_write_adlib(i,0);
midi_write_adlib(0x01, 0x20);
midi_write_adlib(0xBD,0xc0);
}
bool CmidPlayer::update()
{
long w,v,note,vel,ctrl,nv,x,l,lnum;
int i=0,j,c;
int on,onl,numchan;
int ret;
if (doing == 1)
{
// just get the first wait and ignore it :>
for (curtrack=0; curtrack<16; curtrack++)
if (track[curtrack].on)
{
pos=track[curtrack].pos;
if (type != FILE_SIERRA && type !=FILE_ADVSIERRA)
track[curtrack].iwait+=getval();
else
track[curtrack].iwait+=getnext(1);
track[curtrack].pos=pos;
}
doing=0;
}
iwait=0;
ret=1;
while (iwait==0 && ret==1)
{
for (curtrack=0; curtrack<16; curtrack++)
if (track[curtrack].on && track[curtrack].iwait==0 &&
track[curtrack].pos < track[curtrack].tend)
{
pos=track[curtrack].pos;
v=getnext(1);
// This is to do implied MIDI events.
if (v<0x80) {v=track[curtrack].pv; pos--;}
track[curtrack].pv=(unsigned char)v;
c=v&0x0f;
midiprintf ("[%2X]",v);
switch(v&0xf0)
{
case 0x80: /*note off*/
note=getnext(1); vel=getnext(1);
for (i=0; i<9; i++)
if (chp[i][0]==c && chp[i][1]==note)
{
midi_fm_endnote(i);
chp[i][0]=-1;
}
break;
case 0x90: /*note on*/
// doing=0;
note=getnext(1); vel=getnext(1);
if(adlib_mode == ADLIB_RYTHM)
numchan = 6;
else
numchan = 9;
if (ch[c].on!=0)
{
for (i=0; i<18; i++)
chp[i][2]++;
if(c < 11 || adlib_mode == ADLIB_MELODIC) {
j=0;
on=-1;onl=0;
for (i=0; ionl)
{ onl=chp[i][2]; on=i; j=1; }
if (on==-1)
{
onl=0;
for (i=0; ionl)
{ onl=chp[i][2]; on=i; }
}
if (j==0)
midi_fm_endnote(on);
} else
on = percussion_map[c - 11];
if (vel!=0 && ch[c].inum>=0 && ch[c].inum<128) {
if (adlib_mode == ADLIB_MELODIC || c < 12) // 11 == bass drum, handled like a normal instrument, on == channel 6 thanks to percussion_map[] above
midi_fm_instrument(on,ch[c].ins);
else
midi_fm_percussion(c, ch[c].ins);
if (adlib_style & MIDI_STYLE) {
nv=((ch[c].vol*vel)/128);
if ((adlib_style&LUCAS_STYLE)!=0) nv*=2;
if (nv>127) nv=127;
nv=my_midi_fm_vol_table[nv];
if ((adlib_style&LUCAS_STYLE)!=0)
nv=(int)((float)sqrt((float)nv)*11);
} else if (adlib_style & CMF_STYLE) {
// CMF doesn't support note velocity (even though some files have them!)
nv = 127;
} else {
nv=vel;
}
midi_fm_playnote(on,note+ch[c].nshift,nv*2); // sets freq in rhythm mode
chp[on][0]=c;
chp[on][1]=note;
chp[on][2]=0;
if(adlib_mode == ADLIB_RYTHM && c >= 11) {
// Still need to turn off the perc instrument before playing it again,
// as not all songs send a noteoff.
midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11)));
// Play the perc instrument
midi_write_adlib(0xbd, adlib_data[0xbd] | (0x10 >> (c - 11)));
}
} else {
if (vel==0) { //same code as end note
if (adlib_mode == ADLIB_RYTHM && c >= 11) {
// Turn off the percussion instrument
midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11)));
//midi_fm_endnote(percussion_map[c]);
chp[percussion_map[c - 11]][0]=-1;
} else {
for (i=0; i<9; i++) {
if (chp[i][0]==c && chp[i][1]==note) {
// midi_fm_volume(i,0); // really end the note
midi_fm_endnote(i);
chp[i][0]=-1;
}
}
}
} else {
// i forget what this is for.
chp[on][0]=-1;
chp[on][2]=0;
}
}
midiprintf(" [%d:%d:%d:%d]\n",c,ch[c].inum,note,vel);
}
else
midiprintf ("off");
break;
case 0xa0: /*key after touch */
note=getnext(1); vel=getnext(1);
/* //this might all be good
for (i=0; i<9; i++)
if (chp[i][0]==c & chp[i][1]==note)
midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2);
*/
break;
case 0xb0: /*control change .. pitch bend? */
ctrl=getnext(1); vel=getnext(1);
switch(ctrl)
{
case 0x07:
midiprintf ("(pb:%d: %d %d)",c,ctrl,vel);
ch[c].vol=vel;
midiprintf("vol");
break;
case 0x63:
if (adlib_style & CMF_STYLE) {
// Custom extension to allow CMF files to switch the
// AM+VIB depth on and off (officially this is on,
// and there's no way to switch it off.) Controller
// values:
// 0 == AM+VIB off
// 1 == VIB on
// 2 == AM on
// 3 == AM+VIB on
midi_write_adlib(0xbd, (adlib_data[0xbd] & ~0xC0) | (vel << 6));
midiprintf(" AM+VIB depth change - AM %s, VIB %s\n",
(adlib_data[0xbd] & 0x80) ? "on" : "off",
(adlib_data[0xbd] & 0x40) ? "on" : "off"
);
}
break;
case 0x67:
midiprintf("Rhythm mode: %d\n", vel);
if ((adlib_style&CMF_STYLE)!=0) {
adlib_mode=vel;
if(adlib_mode == ADLIB_RYTHM)
midi_write_adlib(0xbd, adlib_data[0xbd] | (1 << 5));
else
midi_write_adlib(0xbd, adlib_data[0xbd] & ~(1 << 5));
}
break;
}
break;
case 0xc0: /*patch change*/
x=getnext(1);
ch[c].inum=x;
for (j=0; j<11; j++)
ch[c].ins[j]=myinsbank[ch[c].inum][j];
break;
case 0xd0: /*chanel touch*/
x=getnext(1);
break;
case 0xe0: /*pitch wheel*/
x=getnext(1);
x=getnext(1);
break;
case 0xf0:
switch(v)
{
case 0xf0:
case 0xf7: /*sysex*/
l=getval();
if (datalook(pos+l)==0xf7)
i=1;
midiprintf("{%d}",l);
midiprintf("\n");
if (datalook(pos)==0x7d &&
datalook(pos+1)==0x10 &&
datalook(pos+2)<16)
{
adlib_style=LUCAS_STYLE|MIDI_STYLE;
for (i=0; i",w);
f =
((float)w/(float)deltas)*((float)msqtr/(float)1000000);
if (doing==1) f=0; //not playing yet. don't wait yet
}
*/
}
else
track[curtrack].iwait=0;
track[curtrack].pos=pos;
}
ret=0; //end of song.
iwait=0;
for (curtrack=0; curtrack<16; curtrack++)
if (track[curtrack].on == 1 &&
track[curtrack].pos < track[curtrack].tend)
ret=1; //not yet..
if (ret==1)
{
iwait=0xffffff; // bigger than any wait can be!
for (curtrack=0; curtrack<16; curtrack++)
if (track[curtrack].on == 1 &&
track[curtrack].pos < track[curtrack].tend &&
track[curtrack].iwait < iwait)
iwait=track[curtrack].iwait;
}
}
if (iwait !=0 && ret==1)
{
for (curtrack=0; curtrack<16; curtrack++)
if (track[curtrack].on)
track[curtrack].iwait-=iwait;
fwait=1.0f/(((float)iwait/(float)deltas)*((float)msqtr/(float)1000000));
}
else
fwait=50; // 1/50th of a second
midiprintf ("\n");
for (i=0; i<16; i++)
if (track[i].on) {
if (track[i].pos < track[i].tend)
midiprintf ("<%d>",track[i].iwait);
else
midiprintf("stop");
}
/*
if (ret==0 && type==FILE_ADVSIERRA)
if (datalook(sierra_pos-2)!=0xff)
{
midiprintf ("next sectoin!");
sierra_next_section(p);
fwait=50;
ret=1;
}
*/
if(ret)
return true;
else
return false;
}
float CmidPlayer::getrefresh()
{
return (fwait > 0.01f ? fwait : 0.01f);
}
void CmidPlayer::rewind(int subsong)
{
long i,j,n,m,l;
long o_sierra_pos;
unsigned char ins[16];
pos=0; tins=0;
adlib_style=MIDI_STYLE|CMF_STYLE;
adlib_mode=ADLIB_MELODIC;
for (i=0; i<128; i++)
for (j=0; j<16; j++)
myinsbank[i][j]=midi_fm_instruments[i][j];
for (i=0; i<16; i++)
{
ch[i].inum=0;
for (j=0; j<11; j++)
ch[i].ins[j]=myinsbank[ch[i].inum][j];
ch[i].vol=127;
ch[i].nshift=-25;
ch[i].on=1;
}
/* General init */
for (i=0; i<9; i++)
{
chp[i][0]=-1;
chp[i][2]=0;
}
deltas=250; // just a number, not a standard
msqtr=500000;
fwait=123; // gotta be a small thing.. sorta like nothing
iwait=0;
subsongs=1;
for (i=0; i<16; i++)
{
track[i].tend=0;
track[i].spos=0;
track[i].pos=0;
track[i].iwait=0;
track[i].on=0;
track[i].pv=0;
}
curtrack=0;
/* specific to file-type init */
pos=0;
i=getnext(1);
switch(type)
{
case FILE_LUCAS:
getnext(24); //skip junk and get to the midi.
adlib_style=LUCAS_STYLE|MIDI_STYLE;
//note: no break, we go right into midi headers...
case FILE_MIDI:
if (type != FILE_LUCAS)
tins=128;
getnext(11); /*skip header*/
deltas=getnext(2);
midiprintf ("deltas:%ld\n",deltas);
getnext(4);
curtrack=0;
track[curtrack].on=1;
track[curtrack].tend=getnext(4);
track[curtrack].spos=pos;
midiprintf ("tracklen:%ld\n",track[curtrack].tend);
break;
case FILE_CMF:
getnext(3); // ctmf
getnexti(2); //version
n=getnexti(2); // instrument offset
m=getnexti(2); // music offset
deltas=getnexti(2); //ticks/qtr note
msqtr=1000000/getnexti(2)*deltas;
//the stuff in the cmf is click ticks per second..
i=getnexti(2);
if(i) title = (char *)data+i;
i=getnexti(2);
if(i) author = (char *)data+i;
i=getnexti(2);
if(i) remarks = (char *)data+i;
getnext(16); // channel in use table ..
i=getnexti(2); // num instr
if (i>128) i=128; // to ward of bad numbers...
getnexti(2); //basic tempo
midiprintf("\nioff:%d\nmoff%d\ndeltas:%ld\nmsqtr:%ld\nnumi:%d\n",
n,m,deltas,msqtr,i);
pos=n; // jump to instruments
tins=i;
for (j=0; j= subsongs) subsong=0;
sierra_pos=o_sierra_pos;
sierra_next_section();
i=0;
while (i != subsong)
{
sierra_next_section();
i++;
}
adlib_style=SIERRA_STYLE|MIDI_STYLE; //advanced sierra tunes use volume
break;
case FILE_SIERRA:
memcpy(myinsbank, smyinsbank, 128 * 16);
tins = stins;
getnext(2);
deltas=0x20;
curtrack=0;
track[curtrack].on=1;
track[curtrack].tend=flen; // music until the end of the file
for (i=0; i<16; i++)
{
ch[i].nshift=-13;
ch[i].on=getnext(1);
ch[i].inum=getnext(1);
for (j=0; j<11; j++)
ch[i].ins[j]=myinsbank[ch[i].inum][j];
}
track[curtrack].spos=pos;
adlib_style=SIERRA_STYLE|MIDI_STYLE;
break;
}
/* sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */
for (i=0; i<16; i++)
if (track[i].on)
{
track[i].pos=track[i].spos;
track[i].pv=0;
track[i].iwait=0;
}
doing=1;
midi_fm_reset();
}
std::string CmidPlayer::gettype()
{
switch(type) {
case FILE_LUCAS:
return std::string("LucasArts AdLib MIDI");
case FILE_MIDI:
return std::string("General MIDI");
case FILE_CMF:
return std::string("Creative Music Format (CMF MIDI)");
case FILE_OLDLUCAS:
return std::string("Lucasfilm Adlib MIDI");
case FILE_ADVSIERRA:
return std::string("Sierra On-Line VGA MIDI");
case FILE_SIERRA:
return std::string("Sierra On-Line EGA MIDI");
default:
return std::string("MIDI unknown");
}
}
adplug-2.2.1+dfsg3/src/amd.cpp 0000644 0001750 0001750 00000013057 10606235013 015322 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* amd.cpp - AMD Loader by Simon Peter
*/
#include
#include "amd.h"
#include "debug.h"
CPlayer *CamdLoader::factory(Copl *newopl)
{
return new CamdLoader(newopl);
}
bool CamdLoader::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
struct {
char id[9];
unsigned char version;
} header;
int i, j, k, t, numtrax, maxi = 0;
unsigned char buf, buf2, buf3;
const unsigned char convfx[10] = {0,1,2,9,17,11,13,18,3,14};
const unsigned char convvol[64] = {
0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 0xa, 0xa, 0xb,
0xc, 0xc, 0xd, 0xe, 0xe, 0xf, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21,
0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x35,
0x37, 0x3a, 0x3c, 0x3f
};
// file validation section
if(fp.filesize(f) < 1072) { fp.close(f); return false; }
f->seek(1062); f->readString(header.id, 9);
header.version = f->readInt(1);
if(strncmp(header.id, "seek(0);
f->readString(songname, sizeof(songname));
f->readString(author, sizeof(author));
for(i = 0; i < 26; i++) {
f->readString(instname[i], 23);
for(j = 0; j < 11; j++) inst[i].data[j] = f->readInt(1);
}
length = f->readInt(1); nop = f->readInt(1) + 1;
for(i=0;i<128;i++) order[i] = f->readInt(1);
f->seek(10, binio::Add);
if(header.version == 0x10) { // unpacked module
maxi = nop * 9;
for(i=0;i<64*9;i++)
trackord[i/9][i%9] = i+1;
t = 0;
while(!f->ateof()) {
for(j=0;j<64;j++)
for(i=t;ireadInt(1);
tracks[i][j].param2 = (buf&127) % 10;
tracks[i][j].param1 = (buf&127) / 10;
buf = f->readInt(1);
tracks[i][j].inst = buf >> 4;
tracks[i][j].command = buf & 0x0f;
buf = f->readInt(1);
if(buf >> 4) // fix bug in AMD save routine
tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
else
tracks[i][j].note = 0;
tracks[i][j].inst += (buf & 1) << 4;
}
t += 9;
}
} else { // packed module
for(i=0;ireadInt(2) + 1;
numtrax = f->readInt(2);
for(k=0;kreadInt(2);
if(i > 575) i = 575; // fix corrupted modules
maxi = (i + 1 > maxi ? i + 1 : maxi);
j = 0;
do {
buf = f->readInt(1);
if(buf & 128) {
for(t = j; t < j + (buf & 127) && t < 64; t++) {
tracks[i][t].command = 0;
tracks[i][t].inst = 0;
tracks[i][t].note = 0;
tracks[i][t].param1 = 0;
tracks[i][t].param2 = 0;
}
j += buf & 127;
continue;
}
tracks[i][j].param2 = buf % 10;
tracks[i][j].param1 = buf / 10;
buf = f->readInt(1);
tracks[i][j].inst = buf >> 4;
tracks[i][j].command = buf & 0x0f;
buf = f->readInt(1);
if(buf >> 4) // fix bug in AMD save routine
tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
else
tracks[i][j].note = 0;
tracks[i][j].inst += (buf & 1) << 4;
j++;
} while(j<64);
}
}
fp.close(f);
// convert to protracker replay data
bpm = 50; restartpos = 0; flags = Decimal;
for(i=0;i<26;i++) { // convert instruments
buf = inst[i].data[0];
buf2 = inst[i].data[1];
inst[i].data[0] = inst[i].data[10];
inst[i].data[1] = buf;
buf = inst[i].data[2];
inst[i].data[2] = inst[i].data[5];
buf3 = inst[i].data[3];
inst[i].data[3] = buf;
buf = inst[i].data[4];
inst[i].data[4] = inst[i].data[7];
inst[i].data[5] = buf3;
buf3 = inst[i].data[6];
inst[i].data[6] = inst[i].data[8];
inst[i].data[7] = buf;
inst[i].data[8] = inst[i].data[9];
inst[i].data[9] = buf2;
inst[i].data[10] = buf3;
for(j=0;j<23;j++) // convert names
if(instname[i][j] == '\xff')
instname[i][j] = '\x20';
}
for(i=0;i 63) vol = 63;
tracks[i][j].param1 = vol / 10;
tracks[i][j].param2 = vol % 10;
}
}
rewind(0);
return true;
}
float CamdLoader::getrefresh()
{
if(tempo)
return (float) (tempo);
else
return 18.2f;
}
adplug-2.2.1+dfsg3/src/protrack.cpp 0000644 0001750 0001750 00000053523 11025200504 016401 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* protrack.cpp - Generic Protracker Player
*
* NOTES:
* This is a generic Protracker-based formats player. It offers all Protracker
* features, plus a good set of extensions to be compatible to other Protracker
* derivatives. It is derived from the former SA2 player. If you got a
* Protracker-like format, this is most certainly the player you want to use.
*/
#include
#include "protrack.h"
#include "debug.h"
#define SPECIALARPLEN 256 // Standard length of special arpeggio lists
#define JUMPMARKER 0x80 // Orderlist jump marker
// SA2 compatible adlib note table
const unsigned short CmodPlayer::sa2_notetable[12] =
{340,363,385,408,432,458,485,514,544,577,611,647};
// SA2 compatible vibrato rate table
const unsigned char CmodPlayer::vibratotab[32] =
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
/*** public methods *************************************/
CmodPlayer::CmodPlayer(Copl *newopl)
: CPlayer(newopl), inst(0), order(0), arplist(0), arpcmd(0), initspeed(6),
nop(0), activechan(0xffffffff), flags(Standard), curchip(opl->getchip()),
nrows(0), npats(0), nchans(0)
{
realloc_order(128);
realloc_patterns(64, 64, 9);
realloc_instruments(250);
init_notetable(sa2_notetable);
}
CmodPlayer::~CmodPlayer()
{
dealloc();
}
bool CmodPlayer::update()
{
unsigned char pattbreak=0, donote, pattnr, chan, oplchan, info1,
info2, info, pattern_delay;
unsigned short track;
unsigned long row;
if(!speed) // song full stop
return !songend;
// effect handling (timer dependant)
for(chan = 0; chan < nchans; chan++) {
oplchan = set_opl_chip(chan);
if(arplist && arpcmd && inst[channel[chan].inst].arpstart) { // special arpeggio
if(channel[chan].arpspdcnt)
channel[chan].arpspdcnt--;
else
if(arpcmd[channel[chan].arppos] != 255) {
switch(arpcmd[channel[chan].arppos]) {
case 252: channel[chan].vol1 = arplist[channel[chan].arppos]; // set volume
if(channel[chan].vol1 > 63) // ?????
channel[chan].vol1 = 63;
channel[chan].vol2 = channel[chan].vol1;
setvolume(chan);
break;
case 253: channel[chan].key = 0; setfreq(chan); break; // release sustaining note
case 254: channel[chan].arppos = arplist[channel[chan].arppos]; break; // arpeggio loop
default: if(arpcmd[channel[chan].arppos]) {
if(arpcmd[channel[chan].arppos] / 10)
opl->write(0xe3 + op_table[oplchan], arpcmd[channel[chan].arppos] / 10 - 1);
if(arpcmd[channel[chan].arppos] % 10)
opl->write(0xe0 + op_table[oplchan], (arpcmd[channel[chan].arppos] % 10) - 1);
if(arpcmd[channel[chan].arppos] < 10) // ?????
opl->write(0xe0 + op_table[oplchan], arpcmd[channel[chan].arppos] - 1);
}
}
if(arpcmd[channel[chan].arppos] != 252) {
if(arplist[channel[chan].arppos] <= 96)
setnote(chan,channel[chan].note + arplist[channel[chan].arppos]);
if(arplist[channel[chan].arppos] >= 100)
setnote(chan,arplist[channel[chan].arppos] - 100);
} else
setnote(chan,channel[chan].note);
setfreq(chan);
if(arpcmd[channel[chan].arppos] != 255)
channel[chan].arppos++;
channel[chan].arpspdcnt = inst[channel[chan].inst].arpspeed - 1;
}
}
info1 = channel[chan].info1;
info2 = channel[chan].info2;
if(flags & Decimal)
info = channel[chan].info1 * 10 + channel[chan].info2;
else
info = (channel[chan].info1 << 4) + channel[chan].info2;
switch(channel[chan].fx) {
case 0: if(info) { // arpeggio
if(channel[chan].trigger < 2)
channel[chan].trigger++;
else
channel[chan].trigger = 0;
switch(channel[chan].trigger) {
case 0: setnote(chan,channel[chan].note); break;
case 1: setnote(chan,channel[chan].note + info1); break;
case 2: setnote(chan,channel[chan].note + info2);
}
setfreq(chan);
}
break;
case 1: slide_up(chan,info); setfreq(chan); break; // slide up
case 2: slide_down(chan,info); setfreq(chan); break; // slide down
case 3: tone_portamento(chan,channel[chan].portainfo); break; // tone portamento
case 4: vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2); break; // vibrato
case 5: // tone portamento & volume slide
case 6: if(channel[chan].fx == 5) // vibrato & volume slide
tone_portamento(chan,channel[chan].portainfo);
else
vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2);
case 10: if(del % 4) // SA2 volume slide
break;
if(info1)
vol_up(chan,info1);
else
vol_down(chan,info2);
setvolume(chan);
break;
case 14: if(info1 == 3) // retrig note
if(!(del % (info2+1)))
playnote(chan);
break;
case 16: if(del % 4) // AMD volume slide
break;
if(info1)
vol_up_alt(chan,info1);
else
vol_down_alt(chan,info2);
setvolume(chan);
break;
case 20: // RAD volume slide
if(info < 50)
vol_down_alt(chan,info);
else
vol_up_alt(chan,info - 50);
setvolume(chan);
break;
case 26: // volume slide
if(info1)
vol_up(chan,info1);
else
vol_down(chan,info2);
setvolume(chan);
break;
case 28:
if (info1) {
slide_up(chan,1); channel[chan].info1--;
}
if (info2) {
slide_down(chan,1); channel[chan].info2--;
}
setfreq(chan);
break;
}
}
if(del) { // speed compensation
del--;
return !songend;
}
// arrangement handling
if(!resolve_order()) return !songend;
pattnr = order[ord];
if(!rw) AdPlug_LogWrite("\nCmodPlayer::update(): Pattern: %d, Order: %d\n", pattnr, ord);
AdPlug_LogWrite("CmodPlayer::update():%3d|", rw);
// play row
pattern_delay = 0;
row = rw;
for(chan = 0; chan < nchans; chan++) {
oplchan = set_opl_chip(chan);
if(!(activechan >> (31 - chan)) & 1) { // channel active?
AdPlug_LogWrite("N/A|");
continue;
}
if(!(track = trackord[pattnr][chan])) { // resolve track
AdPlug_LogWrite("------------|");
continue;
} else
track--;
AdPlug_LogWrite("%3d%3d%2X%2X%2X|", tracks[track][row].note,
tracks[track][row].inst, tracks[track][row].command,
tracks[track][row].param1, tracks[track][row].param2);
donote = 0;
if(tracks[track][row].inst) {
channel[chan].inst = tracks[track][row].inst - 1;
if (!(flags & Faust)) {
channel[chan].vol1 = 63 - (inst[channel[chan].inst].data[10] & 63);
channel[chan].vol2 = 63 - (inst[channel[chan].inst].data[9] & 63);
setvolume(chan);
}
}
if(tracks[track][row].note && tracks[track][row].command != 3) { // no tone portamento
channel[chan].note = tracks[track][row].note;
setnote(chan,tracks[track][row].note);
channel[chan].nextfreq = channel[chan].freq;
channel[chan].nextoct = channel[chan].oct;
channel[chan].arppos = inst[channel[chan].inst].arpstart;
channel[chan].arpspdcnt = 0;
if(tracks[track][row].note != 127) // handle key off
donote = 1;
}
channel[chan].fx = tracks[track][row].command;
channel[chan].info1 = tracks[track][row].param1;
channel[chan].info2 = tracks[track][row].param2;
if(donote)
playnote(chan);
// command handling (row dependant)
info1 = channel[chan].info1;
info2 = channel[chan].info2;
if(flags & Decimal)
info = channel[chan].info1 * 10 + channel[chan].info2;
else
info = (channel[chan].info1 << 4) + channel[chan].info2;
switch(channel[chan].fx) {
case 3: // tone portamento
if(tracks[track][row].note) {
if(tracks[track][row].note < 13)
channel[chan].nextfreq = notetable[tracks[track][row].note - 1];
else
if(tracks[track][row].note % 12 > 0)
channel[chan].nextfreq = notetable[(tracks[track][row].note % 12) - 1];
else
channel[chan].nextfreq = notetable[11];
channel[chan].nextoct = (tracks[track][row].note - 1) / 12;
if(tracks[track][row].note == 127) { // handle key off
channel[chan].nextfreq = channel[chan].freq;
channel[chan].nextoct = channel[chan].oct;
}
}
if(info) // remember vars
channel[chan].portainfo = info;
break;
case 4: // vibrato (remember vars)
if(info) {
channel[chan].vibinfo1 = info1;
channel[chan].vibinfo2 = info2;
}
break;
case 7: tempo = info; break; // set tempo
case 8: channel[chan].key = 0; setfreq(chan); break; // release sustaining note
case 9: // set carrier/modulator volume
if(info1)
channel[chan].vol1 = info1 * 7;
else
channel[chan].vol2 = info2 * 7;
setvolume(chan);
break;
case 11: // position jump
pattbreak = 1; rw = 0; if(info < ord) songend = 1; ord = info; break;
case 12: // set volume
channel[chan].vol1 = info;
channel[chan].vol2 = info;
if(channel[chan].vol1 > 63)
channel[chan].vol1 = 63;
if(channel[chan].vol2 > 63)
channel[chan].vol2 = 63;
setvolume(chan);
break;
case 13: // pattern break
if(!pattbreak) { pattbreak = 1; rw = info; ord++; } break;
case 14: // extended command
switch(info1) {
case 0: // define cell-tremolo
if(info2)
regbd |= 128;
else
regbd &= 127;
opl->write(0xbd,regbd);
break;
case 1: // define cell-vibrato
if(info2)
regbd |= 64;
else
regbd &= 191;
opl->write(0xbd,regbd);
break;
case 4: // increase volume fine
vol_up_alt(chan,info2);
setvolume(chan);
break;
case 5: // decrease volume fine
vol_down_alt(chan,info2);
setvolume(chan);
break;
case 6: // manual slide up
slide_up(chan,info2);
setfreq(chan);
break;
case 7: // manual slide down
slide_down(chan,info2);
setfreq(chan);
break;
case 8: // pattern delay (rows)
pattern_delay = info2 * speed;
break;
}
break;
case 15: // SA2 set speed
if(info <= 0x1f)
speed = info;
if(info >= 0x32)
tempo = info;
if(!info)
songend = 1;
break;
case 17: // alternate set volume
channel[chan].vol1 = info;
if(channel[chan].vol1 > 63)
channel[chan].vol1 = 63;
if(inst[channel[chan].inst].data[0] & 1) {
channel[chan].vol2 = info;
if(channel[chan].vol2 > 63)
channel[chan].vol2 = 63;
}
setvolume(chan);
break;
case 18: // AMD set speed
if(info <= 31 && info > 0)
speed = info;
if(info > 31 || !info)
tempo = info;
break;
case 19: // RAD/A2M set speed
speed = (info ? info : info + 1);
break;
case 21: // set modulator volume
if(info <= 63)
channel[chan].vol2 = info;
else
channel[chan].vol2 = 63;
setvolume(chan);
break;
case 22: // set carrier volume
if(info <= 63)
channel[chan].vol1 = info;
else
channel[chan].vol1 = 63;
setvolume(chan);
break;
case 23: // fine frequency slide up
slide_up(chan,info);
setfreq(chan);
break;
case 24: // fine frequency slide down
slide_down(chan,info);
setfreq(chan);
break;
case 25: // set carrier/modulator waveform
if(info1 != 0x0f)
opl->write(0xe3 + op_table[oplchan],info1);
if(info2 != 0x0f)
opl->write(0xe0 + op_table[oplchan],info2);
break;
case 27: // set chip tremolo/vibrato
if(info1)
regbd |= 128;
else
regbd &= 127;
if(info2)
regbd |= 64;
else
regbd &= 191;
opl->write(0xbd,regbd);
break;
case 29: // pattern delay (frames)
pattern_delay = info;
break;
}
}
// speed compensation
del = speed - 1 + pattern_delay;
if(!pattbreak) { // next row (only if no manual advance)
rw++;
if(rw >= nrows) {
rw = 0;
ord++;
}
}
resolve_order(); // so we can report songend right away
AdPlug_LogWrite("\n");
return !songend;
}
unsigned char CmodPlayer::set_opl_chip(unsigned char chan)
/*
* Sets OPL chip according to channel number. Channels 0-8 are on first chip,
* channels 9-17 are on second chip. Returns corresponding OPL channel
* number.
*/
{
int newchip = chan < 9 ? 0 : 1;
if(newchip != curchip) {
opl->setchip(newchip);
curchip = newchip;
}
return chan % 9;
}
bool CmodPlayer::resolve_order()
/*
* Resolves current orderlist entry, checking for jumps and loops.
*
* Returns true on correct processing, false if immediate recursive loop
* has been detected.
*/
{
if(ord < length) {
while(order[ord] >= JUMPMARKER) { // jump to order
unsigned long neword = order[ord] - JUMPMARKER;
if(neword <= ord) songend = 1;
if(neword == ord) return false;
ord = neword;
}
} else {
songend = 1;
ord = restartpos;
}
return true;
}
void CmodPlayer::rewind(int subsong)
{
unsigned long i;
// Reset playing variables
songend = del = ord = rw = regbd = 0;
tempo = bpm; speed = initspeed;
// Reset channel data
memset(channel,0,sizeof(Channel)*nchans);
// Compute number of patterns, if needed
if(!nop)
for(i=0;i nop ? order[i] : nop);
opl->init(); // Reset OPL chip
opl->write(1, 32); // Go to ym3812 mode
// Enable OPL3 extensions if flagged
if(flags & Opl3) {
opl->setchip(1);
opl->write(1, 32);
opl->write(5, 1);
opl->setchip(0);
}
// Enable tremolo/vibrato depth if flagged
if(flags & Tremolo) regbd |= 128;
if(flags & Vibrato) regbd |= 64;
if(regbd) opl->write(0xbd, regbd);
}
float CmodPlayer::getrefresh()
{
return (float) (tempo / 2.5);
}
void CmodPlayer::init_trackord()
{
unsigned long i;
for(i=0;iwrite(0x40 + op_table[oplchan], 63-channel[chan].vol2 + (inst[channel[chan].inst].data[9] & 192));
opl->write(0x43 + op_table[oplchan], 63-channel[chan].vol1 + (inst[channel[chan].inst].data[10] & 192));
}
}
void CmodPlayer::setvolume_alt(unsigned char chan)
{
unsigned char oplchan = set_opl_chip(chan);
unsigned char ivol2 = inst[channel[chan].inst].data[9] & 63;
unsigned char ivol1 = inst[channel[chan].inst].data[10] & 63;
opl->write(0x40 + op_table[oplchan], (((63 - (channel[chan].vol2 & 63)) + ivol2) >> 1) + (inst[channel[chan].inst].data[9] & 192));
opl->write(0x43 + op_table[oplchan], (((63 - (channel[chan].vol1 & 63)) + ivol1) >> 1) + (inst[channel[chan].inst].data[10] & 192));
}
void CmodPlayer::setfreq(unsigned char chan)
{
unsigned char oplchan = set_opl_chip(chan);
opl->write(0xa0 + oplchan, channel[chan].freq & 255);
if(channel[chan].key)
opl->write(0xb0 + oplchan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2) | 32);
else
opl->write(0xb0 + oplchan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
}
void CmodPlayer::playnote(unsigned char chan)
{
unsigned char oplchan = set_opl_chip(chan);
unsigned char op = op_table[oplchan], insnr = channel[chan].inst;
if(!(flags & NoKeyOn))
opl->write(0xb0 + oplchan, 0); // stop old note
// set instrument data
opl->write(0x20 + op, inst[insnr].data[1]);
opl->write(0x23 + op, inst[insnr].data[2]);
opl->write(0x60 + op, inst[insnr].data[3]);
opl->write(0x63 + op, inst[insnr].data[4]);
opl->write(0x80 + op, inst[insnr].data[5]);
opl->write(0x83 + op, inst[insnr].data[6]);
opl->write(0xe0 + op, inst[insnr].data[7]);
opl->write(0xe3 + op, inst[insnr].data[8]);
opl->write(0xc0 + oplchan, inst[insnr].data[0]);
opl->write(0xbd, inst[insnr].misc); // set misc. register
// set frequency, volume & play
channel[chan].key = 1;
setfreq(chan);
if (flags & Faust) {
channel[chan].vol2 = 63;
channel[chan].vol1 = 63;
}
setvolume(chan);
}
void CmodPlayer::setnote(unsigned char chan, int note)
{
if(note > 96) {
if(note == 127) { // key off
channel[chan].key = 0;
setfreq(chan);
return;
} else
note = 96;
}
if(note < 13)
channel[chan].freq = notetable[note - 1];
else
if(note % 12 > 0)
channel[chan].freq = notetable[(note % 12) - 1];
else
channel[chan].freq = notetable[11];
channel[chan].oct = (note - 1) / 12;
channel[chan].freq += inst[channel[chan].inst].slide; // apply pre-slide
}
void CmodPlayer::slide_down(unsigned char chan, int amount)
{
channel[chan].freq -= amount;
if(channel[chan].freq <= 342) {
if(channel[chan].oct) {
channel[chan].oct--;
channel[chan].freq <<= 1;
} else
channel[chan].freq = 342;
}
}
void CmodPlayer::slide_up(unsigned char chan, int amount)
{
channel[chan].freq += amount;
if(channel[chan].freq >= 686) {
if(channel[chan].oct < 7) {
channel[chan].oct++;
channel[chan].freq >>= 1;
} else
channel[chan].freq = 686;
}
}
void CmodPlayer::tone_portamento(unsigned char chan, unsigned char info)
{
if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
(channel[chan].nextoct << 10)) {
slide_up(chan,info);
if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
(channel[chan].nextoct << 10)) {
channel[chan].freq = channel[chan].nextfreq;
channel[chan].oct = channel[chan].nextoct;
}
}
if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
(channel[chan].nextoct << 10)) {
slide_down(chan,info);
if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
(channel[chan].nextoct << 10)) {
channel[chan].freq = channel[chan].nextfreq;
channel[chan].oct = channel[chan].nextoct;
}
}
setfreq(chan);
}
void CmodPlayer::vibrato(unsigned char chan, unsigned char speed, unsigned char depth)
{
int i;
if(!speed || !depth)
return;
if(depth > 14)
depth = 14;
for(i=0;i= 64)
channel[chan].trigger -= 64;
if(channel[chan].trigger >= 16 && channel[chan].trigger < 48)
slide_down(chan,vibratotab[channel[chan].trigger - 16] / (16-depth));
if(channel[chan].trigger < 16)
slide_up(chan,vibratotab[channel[chan].trigger + 16] / (16-depth));
if(channel[chan].trigger >= 48)
slide_up(chan,vibratotab[channel[chan].trigger - 48] / (16-depth));
}
setfreq(chan);
}
void CmodPlayer::vol_up(unsigned char chan, int amount)
{
if(channel[chan].vol1 + amount < 63)
channel[chan].vol1 += amount;
else
channel[chan].vol1 = 63;
if(channel[chan].vol2 + amount < 63)
channel[chan].vol2 += amount;
else
channel[chan].vol2 = 63;
}
void CmodPlayer::vol_down(unsigned char chan, int amount)
{
if(channel[chan].vol1 - amount > 0)
channel[chan].vol1 -= amount;
else
channel[chan].vol1 = 0;
if(channel[chan].vol2 - amount > 0)
channel[chan].vol2 -= amount;
else
channel[chan].vol2 = 0;
}
void CmodPlayer::vol_up_alt(unsigned char chan, int amount)
{
if(channel[chan].vol1 + amount < 63)
channel[chan].vol1 += amount;
else
channel[chan].vol1 = 63;
if(inst[channel[chan].inst].data[0] & 1) {
if(channel[chan].vol2 + amount < 63)
channel[chan].vol2 += amount;
else
channel[chan].vol2 = 63;
}
}
void CmodPlayer::vol_down_alt(unsigned char chan, int amount)
{
if(channel[chan].vol1 - amount > 0)
channel[chan].vol1 -= amount;
else
channel[chan].vol1 = 0;
if(inst[channel[chan].inst].data[0] & 1) {
if(channel[chan].vol2 - amount > 0)
channel[chan].vol2 -= amount;
else
channel[chan].vol2 = 0;
}
}
adplug-2.2.1+dfsg3/src/jbm.cpp 0000644 0001750 0001750 00000020724 10611243112 015323 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Johannes Bjerregaard's JBM Adlib Music Format player for AdPlug
* Written by Dennis Lindroos , February-March 2007
* - Designed and coded from scratch (only frequency-table taken from MUSIC.BIN)
* - The percussion mode is buggy (?) but i'm not good enough to find them
* and honestly i think the melodic-mode tunes are much better ;)
*
* This version doesn't use the binstr.h functions (coded with custom func.)
* This is my first attempt on writing a musicplayer for AdPlug, and i'm not
* coding C++ very often..
*
* Released under the terms of the GNU General Public License.
*/
#include "jbm.h"
static const unsigned short notetable[96] = {
0x0158, 0x016d, 0x0183, 0x019a, 0x01b2, 0x01cc, 0x01e7, 0x0204,
0x0223, 0x0244, 0x0266, 0x028b, 0x0558, 0x056d, 0x0583, 0x059a,
0x05b2, 0x05cc, 0x05e7, 0x0604, 0x0623, 0x0644, 0x0666, 0x068b,
0x0958, 0x096d, 0x0983, 0x099a, 0x09b2, 0x09cc, 0x09e7, 0x0a04,
0x0a23, 0x0a44, 0x0a66, 0x0a8b, 0x0d58, 0x0d6d, 0x0d83, 0x0d9a,
0x0db2, 0x0dcc, 0x0de7, 0x0e04, 0x0e23, 0x0e44, 0x0e66, 0x0e8b,
0x1158, 0x116d, 0x1183, 0x119a, 0x11b2, 0x11cc, 0x11e7, 0x1204,
0x1223, 0x1244, 0x1266, 0x128b, 0x1558, 0x156d, 0x1583, 0x159a,
0x15b2, 0x15cc, 0x15e7, 0x1604, 0x1623, 0x1644, 0x1666, 0x168b,
0x1958, 0x196d, 0x1983, 0x199a, 0x19b2, 0x19cc, 0x19e7, 0x1a04,
0x1a23, 0x1a44, 0x1a66, 0x1a8b, 0x1d58, 0x1d6d, 0x1d83, 0x1d9a,
0x1db2, 0x1dcc, 0x1de7, 0x1e04, 0x1e23, 0x1e44, 0x1e66, 0x1e8b
};
static const unsigned char percmx_tab[4] = { 0x14, 0x12, 0x15, 0x11 };
static const unsigned char perchn_tab[5] = { 6, 7, 8, 8, 7 };
static unsigned char percmaskoff[5] = { 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
static unsigned char percmaskon[5] = { 0x10, 0x08, 0x04, 0x02, 0x01 };
static inline unsigned short GET_WORD(unsigned char *b, int x)
{
return ((unsigned short)(b[x+1] << 8) | b[x]);
}
/*** public methods *************************************/
CPlayer *CjbmPlayer::factory(Copl *newopl)
{
return new CjbmPlayer(newopl);
}
bool CjbmPlayer::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
int filelen = fp.filesize(f);
int i;
if (!filelen || !fp.extension(filename, ".jbm")) goto loaderr;
// Allocate memory buffer m[] and read entire file into it
m = new unsigned char[filelen];
if (f->readString((char *)m, filelen) != filelen) goto loaderr;
fp.close(f);
// The known .jbm files always seem to start with the number 0x0002
if (GET_WORD(m, 0) != 0x0002)
return false;
// Song tempo
i = GET_WORD(m, 2);
timer = 1193810.0 / (i ? i : 0xffff);
seqtable = GET_WORD(m, 4);
instable = GET_WORD(m, 6);
// The flags word has atleast 1 bit, the Adlib's rhythm mode, but
// currently we don't support that :(
flags = GET_WORD(m, 8);
// Instrument datas are directly addressed with m[]
inscount = (filelen - instable) >> 4;
// Voice' and sequence pointers
seqcount = 0xffff;
for (i = 0; i < 11; i++) {
voice[i].trkpos = voice[i].trkstart = GET_WORD(m, 10 + (i<<1));
if (voice[i].trkpos && voice[i].trkpos < seqcount)
seqcount = voice[i].trkpos;
}
seqcount = (seqcount - seqtable) >> 1;
sequences = new unsigned short[seqcount];
for (i = 0; i < seqcount; i++)
sequences[i] = GET_WORD(m, seqtable + (i<<1));
rewind(0);
return true;
loaderr:
fp.close(f);
return false;
}
bool CjbmPlayer::update()
{
short c, spos, frq;
for (c = 0; c < 11; c++) {
if (!voice[c].trkpos) // Unused channel
continue;
if (--voice[c].delay)
continue;
// Turn current note/percussion off
if (voice[c].note&0x7f)
opl_noteonoff(c, &voice[c], 0);
// Process events until we have a note
spos = voice[c].seqpos;
while(!voice[c].delay) {
switch(m[spos]) {
case 0xFD: // Set Instrument
voice[c].instr = m[spos+1];
set_opl_instrument(c, &voice[c]);
spos+=2;
break;
case 0xFF: // End of Sequence
voice[c].seqno = m[++voice[c].trkpos];
if (voice[c].seqno == 0xff) {
voice[c].trkpos = voice[c].trkstart;
voice[c].seqno = m[voice[c].trkpos];
//voicemask &= 0x7ff-(1< 95)
return 0;
voice[c].note = m[spos];
voice[c].vol = m[spos+1];
voice[c].delay =
(m[spos+2] + (m[spos+3]<<8)) + 1;
frq = notetable[voice[c].note&127];
voice[c].frq[0] = (unsigned char)frq;
voice[c].frq[1] = frq >> 8;
spos+=4;
}
}
voice[c].seqpos = spos;
// Write new volume to the carrier operator, or percussion
if (flags&1 && c > 6)
opl->write(0x40 + percmx_tab[c-7], voice[c].vol ^ 0x3f);
else
opl->write(0x43 + op_table[c], voice[c].vol ^ 0x3f);
// Write new frequencies and Gate bit
opl_noteonoff(c, &voice[c], !(voice[c].note & 0x80));
}
return (voicemask);
}
void CjbmPlayer::rewind(int subsong)
{
int c;
voicemask = 0;
for (c = 0; c < 11; c++) {
voice[c].trkpos = voice[c].trkstart;
if (!voice[c].trkpos) continue;
voicemask |= (1<init();
opl->write(0x01, 32);
// Set rhythm mode if flags bit #0 is set
// AM and Vibrato are full depths (taken from DosBox RAW output)
bdreg = 0xC0 | (flags&1)<<5;
opl->write(0xbd, bdreg);
#if 0
if (flags&1) {
voice[7].frq[0] = 0x58; voice[7].frq[1] = 0x09; // XXX
voice[8].frq[0] = 0x04; voice[8].frq[1] = 0x0a; // XXX
opl_noteonoff(7, &voice[7], 0);
opl_noteonoff(8, &voice[8], 0);
}
#endif
return;
}
/*** private methods ************************************/
void CjbmPlayer::opl_noteonoff(int channel, JBMVoice *v, bool state)
{
if (flags&1 && channel > 5) {
// Percussion
opl->write(0xa0 + perchn_tab[channel-6], voice[channel].frq[0]);
opl->write(0xb0 + perchn_tab[channel-6], voice[channel].frq[1]);
opl->write(0xbd,
state ? bdreg | percmaskon[channel-6] :
bdreg & percmaskoff[channel-6]);
} else {
// Melodic mode or Rhythm mode melodic channels
opl->write(0xa0 + channel, voice[channel].frq[0]);
opl->write(0xb0 + channel,
state ? voice[channel].frq[1] | 0x20 :
voice[channel].frq[1] & 0x1f);
}
return;
}
void CjbmPlayer::set_opl_instrument(int channel, JBMVoice *v)
{
short i = instable + (v->instr << 4);
// Sanity check on instr number - or we'll be reading outside m[] !
if (v->instr >= inscount)
return;
// For rhythm mode, multiplexed drums. I don't care about waveforms!
if ((flags&1) & (channel > 6)) {
opl->write(0x20 + percmx_tab[channel-7], m[i+0]);
opl->write(0x40 + percmx_tab[channel-7], m[i+1] ^ 0x3f);
opl->write(0x60 + percmx_tab[channel-7], m[i+2]);
opl->write(0x80 + percmx_tab[channel-7], m[i+3]);
opl->write(0xc0 + perchn_tab[channel-6], m[i+8]&15);
return;
}
// AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 1st operator
opl->write(0x20 + op_table[channel], m[i+0]);
opl->write(0x40 + op_table[channel], m[i+1] ^ 0x3f);
opl->write(0x60 + op_table[channel], m[i+2]);
opl->write(0x80 + op_table[channel], m[i+3]);
// AM/VIB/EG/KSR/FRQMUL, KSL/OUTPUT, ADSR for 2nd operator
opl->write(0x23 + op_table[channel], m[i+4]);
opl->write(0x43 + op_table[channel], m[i+5] ^ 0x3f);
opl->write(0x63 + op_table[channel], m[i+6]);
opl->write(0x83 + op_table[channel], m[i+7]);
// WAVEFORM for operators
opl->write(0xe0 + op_table[channel], (m[i+8]>>4)&3);
opl->write(0xe3 + op_table[channel], (m[i+8]>>6)&3);
// FEEDBACK/FM mode
opl->write(0xc0 + channel, m[i+8]&15);
return;
}
adplug-2.2.1+dfsg3/src/flash.cpp 0000644 0001750 0001750 00000017063 07615503352 015671 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2003 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* [xad] FLASH player, by Riven the Mage
*/
/*
- discovery -
file(s) : LA-INTRO.EXE
type : Lunatic Asylum BBStro
tune : by Rogue [Logic Design]
player : by Flash [Logic Design]
*/
#include "flash.h"
#include "debug.h"
const unsigned char CxadflashPlayer::flash_adlib_registers[99] =
{
0x23, 0x20, 0x43, 0x40, 0x63, 0x60, 0x83, 0x80, 0xC0, 0xE3, 0xE0,
0x24, 0x21, 0x44, 0x41, 0x64, 0x61, 0x84, 0x81, 0xC1, 0xE4, 0xE1,
0x25, 0x22, 0x45, 0x42, 0x65, 0x62, 0x85, 0x82, 0xC2, 0xE5, 0xE2,
0x2B, 0x28, 0x4B, 0x48, 0x6B, 0x68, 0x8B, 0x88, 0xC3, 0xEB, 0xE8,
0x2C, 0x29, 0x4C, 0x49, 0x6C, 0x69, 0x8C, 0x89, 0xC4, 0xEC, 0xE9,
0x2D, 0x2A, 0x4D, 0x4A, 0x6D, 0x6A, 0x8D, 0x8A, 0xC5, 0xED, 0xEA,
0x33, 0x30, 0x53, 0x50, 0x73, 0x70, 0x93, 0x90, 0xC6, 0xF3, 0xF0,
0x34, 0x31, 0x54, 0x51, 0x74, 0x71, 0x94, 0x91, 0xC7, 0xF4, 0xF1,
0x35, 0x32, 0x55, 0x52, 0x75, 0x72, 0x95, 0x92, 0xC8, 0xF5, 0xF2
};
const unsigned short CxadflashPlayer::flash_notes_encoded[268] =
{
0x000,
0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800, 0x900, 0xA00, 0xB00, 0xC00,
0x101, 0x201, 0x301, 0x401, 0x501, 0x601, 0x701, 0x801, 0x901, 0xA01, 0xB01, 0xC01,
0x102, 0x202, 0x302, 0x402, 0x502, 0x602, 0x702, 0x802, 0x902, 0xA02, 0xB02, 0xC02,
0x103, 0x203, 0x303, 0x403, 0x503, 0x603, 0x703, 0x803, 0x903, 0xA03, 0xB03, 0xC03,
0x104, 0x204, 0x304, 0x404, 0x504, 0x604, 0x704, 0x804, 0x904, 0xA04, 0xB04, 0xC04,
0x105, 0x205, 0x305, 0x405, 0x505, 0x605, 0x705, 0x805, 0x905, 0xA05, 0xB05, 0xC05,
0x106, 0x206, 0x306, 0x406, 0x506, 0x606, 0x706, 0x806, 0x906, 0xA06, 0xB06, 0xC06,
0x107, 0x207, 0x307, 0x407, 0x507, 0x607, 0x707, 0x807, 0x907, 0xA07, 0xB07, 0xC07,
0x108, 0x208, 0x308, 0x408, 0x508, 0x608, 0x708, 0x808, 0x908, 0xA08, 0xB08, 0xC08,
0x109, 0x209, 0x309, 0x409, 0x509, 0x609, 0x709, 0x809, 0x909, 0xA09, 0xB09, 0xC09,
0x10A, 0x20A, 0x30A, 0x40A, 0x50A, 0x60A, 0x70A, 0x80A, 0x90A, 0xA0A, 0xB0A, 0xC0A,
0x10B, 0x20B, 0x30B, 0x40B, 0x50B, 0x60B, 0x70B, 0x80B, 0x90B, 0xA0B, 0xB0B, 0xC0B,
0x10C, 0x20C, 0x30C, 0x40C, 0x50C, 0x60C, 0x70C, 0x80C, 0x90C, 0xA0C, 0xB0C, 0xC0C,
0x10D, 0x20D, 0x30D, 0x40D, 0x50D, 0x60D, 0x70D, 0x80D, 0x90D, 0xA0D, 0xB0D, 0xC0D,
0x10E, 0x20E, 0x30E, 0x40E, 0x50E, 0x60E, 0x70E, 0x80E, 0x90E, 0xA0E, 0xB0E, 0xC0E,
0x10F, 0x20F, 0x30F, 0x40F, 0x50F, 0x60F, 0x70F, 0x80F, 0x90F, 0xA0F, 0xB0F, 0xC0F,
0x110, 0x210, 0x310, 0x410, 0x510, 0x610, 0x710, 0x810, 0x910, 0xA10, 0xB10, 0xC10,
0x111, 0x211, 0x311, 0x411, 0x511, 0x611, 0x711, 0x811, 0x911, 0xA11, 0xB11, 0xC11,
0x112, 0x212, 0x312, 0x412, 0x512, 0x612, 0x712, 0x812, 0x912, 0xA12, 0xB12, 0xC12,
0x113, 0x213, 0x313, 0x413, 0x513, 0x613, 0x713, 0x813, 0x913, 0xA13, 0xB13, 0xC13,
0x114, 0x214, 0x314, 0x414, 0x514, 0x614, 0x714, 0x814, 0x914, 0xA14, 0xB14, 0xC14,
0x115, 0x215, 0x315
};
const unsigned short CxadflashPlayer::flash_notes[12] =
{
0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287
};
const unsigned char CxadflashPlayer::flash_default_instrument[8] =
{
0x00, 0x00, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF
};
CPlayer *CxadflashPlayer::factory(Copl *newopl)
{
return new CxadflashPlayer(newopl);
}
void CxadflashPlayer::xadplayer_rewind(int subsong)
{
int i;
plr.speed = xad.speed;
flash.order_pos = 0;
flash.pattern_pos = 0;
opl_write(0x08, 0x00);
opl_write(0xBD, 0x00);
// assign default instrument
for(i=0; i<9; i++)
{
opl_write(0xA0+i, 0x00);
opl_write(0xB0+i, 0x00);
}
// assign instruments
for(i=0; i<9; i++)
for(int j=0; j<11; j++)
opl_write(flash_adlib_registers[i*11+j], tune[i*12+j]);
}
void CxadflashPlayer::xadplayer_update()
{
unsigned short event_pos = (tune[0x600+flash.order_pos]*1152) + \
(flash.pattern_pos*18) + \
0x633;
for (int i=0; i<9; i++)
{
unsigned short flash_channel_freq = (adlib[0xB0+i] << 8) + adlib[0xA0+i];
unsigned char event_b0 = tune[event_pos++];
unsigned char event_b1 = tune[event_pos++];
#ifdef DEBUG
AdPlug_LogWrite("channel %02X, event %02X %02X:\n",i+1,event_b0,event_b1);
#endif
if (event_b0 == 0x80) // 0.0x80: Set Instrument
{
for(int j=0; j<11; j++)
opl_write(flash_adlib_registers[i*11+j], tune[event_b1*12+j]);
}
else
{
if (event_b1 == 0x01)
flash.pattern_pos = 0x3F; // 1.0x01: Pattern Break
unsigned char fx = (event_b1 >> 4);
unsigned char fx_p = (event_b1 & 0x0F);
switch(fx)
{
case 0x0A: // 1.0xAy: Set Carrier volume
opl_write(flash_adlib_registers[11*i+2], fx_p << 2);
break;
case 0x0B: // 1.0xBy: Set Modulator volume
opl_write(flash_adlib_registers[11*i+3], fx_p << 2);
break;
case 0x0C: // 1.0xCy: Set both operators volume
opl_write(flash_adlib_registers[11*i+2], fx_p << 2);
opl_write(flash_adlib_registers[11*i+3], fx_p << 2);
break;
// case 0x0E: // 1.0xEy: ? (increase some value)
case 0x0F: // 1.0xFy: Set Speed
plr.speed = (fx_p + 1);
break;
}
if (event_b0)
{
// mute channel
opl_write(0xA0+i, adlib[0xA0+i]);
opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
// is note ?
if (event_b0 != 0x7F)
{
unsigned short note_encoded = flash_notes_encoded[event_b0];
unsigned short freq = flash_notes[(note_encoded >> 8) - 1];
flash_channel_freq = freq | ((note_encoded & 0xFF) << 10) | 0x2000;
opl_write(0xA0+i, flash_channel_freq & 0xFF);
opl_write(0xB0+i, flash_channel_freq >> 8);
}
}
if (fx == 0x01) // 1.0x1y: Fine Frequency Slide Up
{
flash_channel_freq += (fx_p << 1);
opl_write(0xA0+i, flash_channel_freq & 0xFF);
opl_write(0xB0+i, flash_channel_freq >> 8);
}
else if (fx == 0x02) // 1.0x2y: Fine Frequency Slide Down
{
flash_channel_freq -= (fx_p << 1);
opl_write(0xA0+i, flash_channel_freq & 0xFF);
opl_write(0xB0+i, flash_channel_freq >> 8);
}
}
}
// next row
flash.pattern_pos++;
// end of pattern ?
if (flash.pattern_pos >= 0x40)
{
flash.pattern_pos = 0;
flash.order_pos++;
// end of module ?
if (tune[0x600+flash.order_pos] == 0xFF)
{
flash.order_pos = 0;
plr.looping = 1;
}
}
}
float CxadflashPlayer::xadplayer_getrefresh()
{
return 17.5f;
}
std::string CxadflashPlayer::xadplayer_gettype()
{
return std::string("xad: flash player");
}
unsigned int CxadflashPlayer::xadplayer_getinstruments()
{
return 32;
}
adplug-2.2.1+dfsg3/src/temuopl.h 0000644 0001750 0001750 00000002602 10166060676 015721 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2004 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* temuopl.h - Tatsuyuki Satoh's OPL2 emulator, by Simon Peter
*/
#ifndef H_ADPLUG_TEMUOPL
#define H_ADPLUG_TEMUOPL
#include "opl.h"
extern "C" {
#include "fmopl.h"
}
class CTemuopl: public Copl
{
public:
CTemuopl(int rate, bool bit16, bool usestereo); // rate = sample rate
virtual ~CTemuopl();
void update(short *buf, int samples); // fill buffer
// template methods
void write(int reg, int val);
void init();
private:
bool use16bit,stereo;
FM_OPL *opl; // holds emulator data
};
#endif
adplug-2.2.1+dfsg3/src/s3m.cpp 0000644 0001750 0001750 00000042541 11025200504 015254 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2006 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* s3m.c - S3M Player by Simon Peter
*
* BUGS:
* Extra Fine Slides (EEx, FEx) & Fine Vibrato (Uxy) are inaccurate
*/
#include
#include "s3m.h"
const char Cs3mPlayer::chnresolv[] = // S3M -> adlib channel conversion
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,-1,-1,-1,-1,-1,-1,-1};
const unsigned short Cs3mPlayer::notetable[12] = // S3M adlib note table
{340,363,385,408,432,458,485,514,544,577,611,647};
const unsigned char Cs3mPlayer::vibratotab[32] = // vibrato rate table
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
/*** public methods *************************************/
CPlayer *Cs3mPlayer::factory(Copl *newopl)
{
return new Cs3mPlayer(newopl);
}
Cs3mPlayer::Cs3mPlayer(Copl *newopl): CPlayer(newopl)
{
int i,j,k;
memset(pattern,255,sizeof(pattern));
memset(orders,255,sizeof(orders));
for(i=0;i<99;i++) // setup pattern
for(j=0;j<64;j++)
for(k=0;k<32;k++) {
pattern[i][j][k].instrument = 0;
pattern[i][j][k].info = 0;
}
}
bool Cs3mPlayer::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
unsigned short insptr[99],pattptr[99];
int i,row;
unsigned char bufval,bufval2;
unsigned short ppatlen;
s3mheader *checkhead;
bool adlibins=false;
// file validation section
checkhead = new s3mheader;
load_header(f, checkhead);
if(checkhead->kennung != 0x1a || checkhead->typ != 16
|| checkhead->insnum > 99) {
delete checkhead; fp.close(f); return false;
} else
if(strncmp(checkhead->scrm,"SCRM",4)) {
delete checkhead; fp.close(f); return false;
} else { // is an adlib module?
f->seek(checkhead->ordnum, binio::Add);
for(i = 0; i < checkhead->insnum; i++)
insptr[i] = f->readInt(2);
for(i=0;iinsnum;i++) {
f->seek(insptr[i]*16);
if(f->readInt(1) >= 2) {
adlibins = true;
break;
}
}
delete checkhead;
if(!adlibins) { fp.close(f); return false; }
}
// load section
f->seek(0); // rewind for load
load_header(f, &header); // read header
// security check
if(header.ordnum > 256 || header.insnum > 99 || header.patnum > 99) {
fp.close(f);
return false;
}
for(i = 0; i < header.ordnum; i++) orders[i] = f->readInt(1); // read orders
for(i = 0; i < header.insnum; i++) insptr[i] = f->readInt(2); // instrument parapointers
for(i = 0; i < header.patnum; i++) pattptr[i] = f->readInt(2); // pattern parapointers
for(i=0;iseek(insptr[i]*16);
inst[i].type = f->readInt(1);
f->readString(inst[i].filename, 15);
inst[i].d00 = f->readInt(1); inst[i].d01 = f->readInt(1);
inst[i].d02 = f->readInt(1); inst[i].d03 = f->readInt(1);
inst[i].d04 = f->readInt(1); inst[i].d05 = f->readInt(1);
inst[i].d06 = f->readInt(1); inst[i].d07 = f->readInt(1);
inst[i].d08 = f->readInt(1); inst[i].d09 = f->readInt(1);
inst[i].d0a = f->readInt(1); inst[i].d0b = f->readInt(1);
inst[i].volume = f->readInt(1); inst[i].dsk = f->readInt(1);
f->ignore(2);
inst[i].c2spd = f->readInt(4);
f->ignore(12);
f->readString(inst[i].name, 28);
f->readString(inst[i].scri, 4);
}
for(i=0;iseek(pattptr[i]*16);
ppatlen = f->readInt(2);
unsigned long pattpos = f->pos();
for(row=0;(row<64) && (pattpos-pattptr[i]*16<=ppatlen);row++)
do {
bufval = f->readInt(1);
if(bufval & 32) {
bufval2 = f->readInt(1);
pattern[i][row][bufval & 31].note = bufval2 & 15;
pattern[i][row][bufval & 31].oct = (bufval2 & 240) >> 4;
pattern[i][row][bufval & 31].instrument = f->readInt(1);
}
if(bufval & 64)
pattern[i][row][bufval & 31].volume = f->readInt(1);
if(bufval & 128) {
pattern[i][row][bufval & 31].command = f->readInt(1);
pattern[i][row][bufval & 31].info = f->readInt(1);
}
} while(bufval);
}
fp.close(f);
rewind(0);
return true; // done
}
bool Cs3mPlayer::update()
{
unsigned char pattbreak=0,donote; // remember vars
unsigned char pattnr,chan,row,info; // cache vars
signed char realchan;
// effect handling (timer dependant)
for(realchan=0; realchan<9; realchan++) {
info = channel[realchan].info; // fill infobyte cache
switch(channel[realchan].fx) {
case 11:
case 12: if(channel[realchan].fx == 11) // dual command: H00 and Dxy
vibrato(realchan,channel[realchan].dualinfo);
else // dual command: G00 and Dxy
tone_portamento(realchan,channel[realchan].dualinfo);
case 4: if(info <= 0x0f) { // volume slide down
if(channel[realchan].vol - info >= 0)
channel[realchan].vol -= info;
else
channel[realchan].vol = 0;
}
if((info & 0x0f) == 0) { // volume slide up
if(channel[realchan].vol + (info >> 4) <= 63)
channel[realchan].vol += info >> 4;
else
channel[realchan].vol = 63;
}
setvolume(realchan);
break;
case 5: if(info == 0xf0 || info <= 0xe0) { // slide down
slide_down(realchan,info);
setfreq(realchan);
}
break;
case 6: if(info == 0xf0 || info <= 0xe0) { // slide up
slide_up(realchan,info);
setfreq(realchan);
}
break;
case 7: tone_portamento(realchan,channel[realchan].dualinfo); break; // tone portamento
case 8: vibrato(realchan,channel[realchan].dualinfo); break; // vibrato
case 10: channel[realchan].nextfreq = channel[realchan].freq; // arpeggio
channel[realchan].nextoct = channel[realchan].oct;
switch(channel[realchan].trigger) {
case 0: channel[realchan].freq = notetable[channel[realchan].note]; break;
case 1: if(channel[realchan].note + ((info & 0xf0) >> 4) < 12)
channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4)];
else {
channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4) - 12];
channel[realchan].oct++;
}
break;
case 2: if(channel[realchan].note + (info & 0x0f) < 12)
channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f)];
else {
channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f) - 12];
channel[realchan].oct++;
}
break;
}
if(channel[realchan].trigger < 2)
channel[realchan].trigger++;
else
channel[realchan].trigger = 0;
setfreq(realchan);
channel[realchan].freq = channel[realchan].nextfreq;
channel[realchan].oct = channel[realchan].nextoct;
break;
case 21: vibrato(realchan,(unsigned char) (info / 4)); break; // fine vibrato
}
}
if(del) { // speed compensation
del--;
return !songend;
}
// arrangement handling
pattnr = orders[ord];
if(pattnr == 0xff || ord > header.ordnum) { // "--" end of song
songend = 1; // set end-flag
ord = 0;
pattnr = orders[ord];
if(pattnr == 0xff)
return !songend;
}
if(pattnr == 0xfe) { // "++" skip marker
ord++; pattnr = orders[ord];
}
// play row
row = crow; // fill row cache
for(chan=0;chan<32;chan++) {
if(!(header.chanset[chan] & 128)) // resolve S3M -> AdLib channels
realchan = chnresolv[header.chanset[chan] & 127];
else
realchan = -1; // channel disabled
if(realchan != -1) { // channel playable?
// set channel values
donote = 0;
if(pattern[pattnr][row][chan].note < 14) {
// tone portamento
if(pattern[pattnr][row][chan].command == 7 || pattern[pattnr][row][chan].command == 12) {
channel[realchan].nextfreq = notetable[pattern[pattnr][row][chan].note];
channel[realchan].nextoct = pattern[pattnr][row][chan].oct;
} else { // normal note
channel[realchan].note = pattern[pattnr][row][chan].note;
channel[realchan].freq = notetable[pattern[pattnr][row][chan].note];
channel[realchan].oct = pattern[pattnr][row][chan].oct;
channel[realchan].key = 1;
donote = 1;
}
}
if(pattern[pattnr][row][chan].note == 14) { // key off (is 14 here, cause note is only first 4 bits)
channel[realchan].key = 0;
setfreq(realchan);
}
if((channel[realchan].fx != 8 && channel[realchan].fx != 11) && // vibrato begins
(pattern[pattnr][row][chan].command == 8 || pattern[pattnr][row][chan].command == 11)) {
channel[realchan].nextfreq = channel[realchan].freq;
channel[realchan].nextoct = channel[realchan].oct;
}
if(pattern[pattnr][row][chan].note >= 14)
if((channel[realchan].fx == 8 || channel[realchan].fx == 11) && // vibrato ends
(pattern[pattnr][row][chan].command != 8 && pattern[pattnr][row][chan].command != 11)) {
channel[realchan].freq = channel[realchan].nextfreq;
channel[realchan].oct = channel[realchan].nextoct;
setfreq(realchan);
}
if(pattern[pattnr][row][chan].instrument) { // set instrument
channel[realchan].inst = pattern[pattnr][row][chan].instrument - 1;
if(inst[channel[realchan].inst].volume < 64)
channel[realchan].vol = inst[channel[realchan].inst].volume;
else
channel[realchan].vol = 63;
if(pattern[pattnr][row][chan].command != 7)
donote = 1;
}
if(pattern[pattnr][row][chan].volume != 255) {
if(pattern[pattnr][row][chan].volume < 64) // set volume
channel[realchan].vol = pattern[pattnr][row][chan].volume;
else
channel[realchan].vol = 63;
}
channel[realchan].fx = pattern[pattnr][row][chan].command; // set command
if(pattern[pattnr][row][chan].info) // set infobyte
channel[realchan].info = pattern[pattnr][row][chan].info;
// some commands reset the infobyte memory
switch(channel[realchan].fx) {
case 1:
case 2:
case 3:
case 20:
channel[realchan].info = pattern[pattnr][row][chan].info;
break;
}
// play note
if(donote)
playnote(realchan);
if(pattern[pattnr][row][chan].volume != 255) // set volume
setvolume(realchan);
// command handling (row dependant)
info = channel[realchan].info; // fill infobyte cache
switch(channel[realchan].fx) {
case 1: speed = info; break; // set speed
case 2: if(info <= ord) songend = 1; ord = info; crow = 0; pattbreak = 1; break; // jump to order
case 3: if(!pattbreak) { crow = info; ord++; pattbreak = 1; } break; // pattern break
case 4: if(info > 0xf0) { // fine volume down
if(channel[realchan].vol - (info & 0x0f) >= 0)
channel[realchan].vol -= info & 0x0f;
else
channel[realchan].vol = 0;
}
if((info & 0x0f) == 0x0f && info >= 0x1f) { // fine volume up
if(channel[realchan].vol + ((info & 0xf0) >> 4) <= 63)
channel[realchan].vol += (info & 0xf0) >> 4;
else
channel[realchan].vol = 63;
}
setvolume(realchan);
break;
case 5: if(info > 0xf0) { // fine slide down
slide_down(realchan,(unsigned char) (info & 0x0f));
setfreq(realchan);
}
if(info > 0xe0 && info < 0xf0) { // extra fine slide down
slide_down(realchan,(unsigned char) ((info & 0x0f) / 4));
setfreq(realchan);
}
break;
case 6: if(info > 0xf0) { // fine slide up
slide_up(realchan,(unsigned char) (info & 0x0f));
setfreq(realchan);
}
if(info > 0xe0 && info < 0xf0) { // extra fine slide up
slide_up(realchan,(unsigned char) ((info & 0x0f) / 4));
setfreq(realchan);
}
break;
case 7: // tone portamento
case 8: if((channel[realchan].fx == 7 || // vibrato (remember info for dual commands)
channel[realchan].fx == 8) && pattern[pattnr][row][chan].info)
channel[realchan].dualinfo = info;
break;
case 10: channel[realchan].trigger = 0; break; // arpeggio (set trigger)
case 19: if(info == 0xb0) // set loop start
loopstart = row;
if(info > 0xb0 && info <= 0xbf) { // pattern loop
if(!loopcnt) {
loopcnt = info & 0x0f;
crow = loopstart;
pattbreak = 1;
} else
if(--loopcnt > 0) {
crow = loopstart;
pattbreak = 1;
}
}
if((info & 0xf0) == 0xe0) // patterndelay
del = speed * (info & 0x0f) - 1;
break;
case 20: tempo = info; break; // set tempo
}
}
}
if(!del)
del = speed - 1; // speed compensation
if(!pattbreak) { // next row (only if no manual advance)
crow++;
if(crow > 63) {
crow = 0;
ord++;
loopstart = 0;
}
}
return !songend; // still playing
}
void Cs3mPlayer::rewind(int subsong)
{
// set basic variables
songend = 0; ord = 0; crow = 0; tempo = header.it;
speed = header.is; del = 0; loopstart = 0; loopcnt = 0;
memset(channel,0,sizeof(channel));
opl->init(); // reset OPL chip
opl->write(1,32); // Go to ym3812 mode
}
std::string Cs3mPlayer::gettype()
{
char filever[5];
switch(header.cwtv) { // determine version number
case 0x1300: strcpy(filever,"3.00"); break;
case 0x1301: strcpy(filever,"3.01"); break;
case 0x1303: strcpy(filever,"3.03"); break;
case 0x1320: strcpy(filever,"3.20"); break;
default: strcpy(filever,"3.??");
}
return (std::string("Scream Tracker ") + filever);
}
float Cs3mPlayer::getrefresh()
{
return (float) (tempo / 2.5);
}
/*** private methods *************************************/
void Cs3mPlayer::load_header(binistream *f, s3mheader *h)
{
int i;
f->readString(h->name, 28);
h->kennung = f->readInt(1); h->typ = f->readInt(1);
f->ignore(2);
h->ordnum = f->readInt(2); h->insnum = f->readInt(2);
h->patnum = f->readInt(2); h->flags = f->readInt(2);
h->cwtv = f->readInt(2); h->ffi = f->readInt(2);
f->readString(h->scrm, 4);
h->gv = f->readInt(1); h->is = f->readInt(1); h->it = f->readInt(1);
h->mv = f->readInt(1); h->uc = f->readInt(1); h->dp = f->readInt(1);
f->ignore(8);
h->special = f->readInt(2);
for(i = 0; i < 32; i++) h->chanset[i] = f->readInt(1);
}
void Cs3mPlayer::setvolume(unsigned char chan)
{
unsigned char op = op_table[chan], insnr = channel[chan].inst;
opl->write(0x43 + op,(int)(63-((63-(inst[insnr].d03 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d03 & 192));
if(inst[insnr].d0a & 1)
opl->write(0x40 + op,(int)(63-((63-(inst[insnr].d02 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d02 & 192));
}
void Cs3mPlayer::setfreq(unsigned char chan)
{
opl->write(0xa0 + chan, channel[chan].freq & 255);
if(channel[chan].key)
opl->write(0xb0 + chan, (((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2)) | 32);
else
opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
}
void Cs3mPlayer::playnote(unsigned char chan)
{
unsigned char op = op_table[chan], insnr = channel[chan].inst;
opl->write(0xb0 + chan, 0); // stop old note
// set instrument data
opl->write(0x20 + op, inst[insnr].d00);
opl->write(0x23 + op, inst[insnr].d01);
opl->write(0x40 + op, inst[insnr].d02);
opl->write(0x43 + op, inst[insnr].d03);
opl->write(0x60 + op, inst[insnr].d04);
opl->write(0x63 + op, inst[insnr].d05);
opl->write(0x80 + op, inst[insnr].d06);
opl->write(0x83 + op, inst[insnr].d07);
opl->write(0xe0 + op, inst[insnr].d08);
opl->write(0xe3 + op, inst[insnr].d09);
opl->write(0xc0 + chan, inst[insnr].d0a);
// set frequency & play
channel[chan].key = 1;
setfreq(chan);
}
void Cs3mPlayer::slide_down(unsigned char chan, unsigned char amount)
{
if(channel[chan].freq - amount > 340)
channel[chan].freq -= amount;
else
if(channel[chan].oct > 0) {
channel[chan].oct--;
channel[chan].freq = 684;
} else
channel[chan].freq = 340;
}
void Cs3mPlayer::slide_up(unsigned char chan, unsigned char amount)
{
if(channel[chan].freq + amount < 686)
channel[chan].freq += amount;
else
if(channel[chan].oct < 7) {
channel[chan].oct++;
channel[chan].freq = 341;
} else
channel[chan].freq = 686;
}
void Cs3mPlayer::vibrato(unsigned char chan, unsigned char info)
{
unsigned char i,speed,depth;
speed = info >> 4;
depth = (info & 0x0f) / 2;
for(i=0;i= 64)
channel[chan].trigger -= 64;
if(channel[chan].trigger >= 16 && channel[chan].trigger < 48)
slide_down(chan,(unsigned char) (vibratotab[channel[chan].trigger - 16] / (16-depth)));
if(channel[chan].trigger < 16)
slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger + 16] / (16-depth)));
if(channel[chan].trigger >= 48)
slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger - 48] / (16-depth)));
}
setfreq(chan);
}
void Cs3mPlayer::tone_portamento(unsigned char chan, unsigned char info)
{
if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
(channel[chan].nextoct << 10))
slide_up(chan,info);
if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
(channel[chan].nextoct << 10))
slide_down(chan,info);
setfreq(chan);
}
adplug-2.2.1+dfsg3/src/hsp.cpp 0000644 0001750 0001750 00000004340 10127013771 015351 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2004 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* hsp.cpp - HSP Loader by Simon Peter
*/
#include
#include "hsp.h"
CPlayer *ChspLoader::factory(Copl *newopl)
{
return new ChspLoader(newopl);
}
bool ChspLoader::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
unsigned long i, j, orgsize, filesize;
unsigned char *cmp, *org;
// file validation section
if(!fp.extension(filename, ".hsp")) { fp.close(f); return false; }
filesize = fp.filesize(f);
orgsize = f->readInt(2);
if(orgsize > 59187) { fp.close(f); return false; }
// load section
cmp = new unsigned char[filesize];
for(i = 0; i < filesize; i++) cmp[i] = f->readInt(1);
fp.close(f);
org = new unsigned char[orgsize];
for(i = 0, j = 0; i < filesize; j += cmp[i], i += 2) { // RLE decompress
if(j >= orgsize) break; // memory boundary check
memset(org + j, cmp[i + 1], j + cmp[i] < orgsize ? cmp[i] : orgsize - j - 1);
}
delete [] cmp;
memcpy(instr, org, 128 * 12); // instruments
for(i = 0; i < 128; i++) { // correct instruments
instr[i][2] ^= (instr[i][2] & 0x40) << 1;
instr[i][3] ^= (instr[i][3] & 0x40) << 1;
instr[i][11] >>= 4; // slide
}
memcpy(song, org + 128 * 12, 51); // tracklist
memcpy(patterns, org + 128 * 12 + 51, orgsize - 128 * 12 - 51); // patterns
delete [] org;
rewind(0);
return true;
}
adplug-2.2.1+dfsg3/src/psi.cpp 0000644 0001750 0001750 00000011204 10326707537 015362 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2003 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* [xad] PSI player, by Riven the Mage
*/
/*
- discovery -
file(s) : 4BIDDEN.COM, PGRID.EXE
type : Forbidden Dreams BBStro
Power Grid BBStro
tune : by Friar Tuck [Shadow Faction/ICE]
player : by Psi [Future Crew]
comment : seems to me what 4bidden tune & player was ripped from pgrid
file(s) : MYSTRUNE.COM
type : Mystical Runes BBStro
tune : by ?
player : by Psi [Future Crew]
*/
#include "psi.h"
#include "debug.h"
const unsigned char CxadpsiPlayer::psi_adlib_registers[99] =
{
0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0xC0,
0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xE1, 0xE4, 0xC1,
0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xE2, 0xE5, 0xC2,
0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xE8, 0xEB, 0xC3,
0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xE9, 0xEC, 0xC4,
0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xEA, 0xED, 0xC5,
0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xF0, 0xF3, 0xC6,
0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xF1, 0xF4, 0xC7,
0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xF2, 0xF5, 0xC8
};
const unsigned short CxadpsiPlayer::psi_notes[16] =
{
0x216B, 0x2181, 0x2198, 0x21B0, 0x21CA, 0x21E5, 0x2202, 0x2220,
0x2241, 0x2263, 0x2287, 0x2364,
0x0000, 0x0000, 0x0000, 0x0000 // by riven
};
CPlayer *CxadpsiPlayer::factory(Copl *newopl)
{
return new CxadpsiPlayer(newopl);
}
void CxadpsiPlayer::xadplayer_rewind(int subsong)
{
opl_write(0x01, 0x20);
opl_write(0x08, 0x00);
opl_write(0xBD, 0x00);
// get header
header.instr_ptr = (tune[1] << 8) + tune[0];
header.seq_ptr = (tune[3] << 8) + tune[2];
// define instruments
psi.instr_table = &tune[header.instr_ptr];
for(int i=0; i<8; i++)
{
for(int j=0; j<11; j++) {
unsigned short inspos = (psi.instr_table[i * 2 + 1] << 8) + psi.instr_table[i * 2];
opl_write(psi_adlib_registers[i*11 + j],tune[inspos + j]);
}
opl_write(0xA0+i, 0x00);
opl_write(0xB0+i, 0x00);
psi.note_delay[i] = 1;
psi.note_curdelay[i] = 1;
psi.looping[i] = 0;
}
// calculate sequence pointer
psi.seq_table = &tune[header.seq_ptr];
}
void CxadpsiPlayer::xadplayer_update()
{
unsigned short ptr;
for(int i=0; i<8; i++)
{
ptr = (psi.seq_table[(i<<1) * 2 + 1] << 8) + psi.seq_table[(i<<1) * 2];
psi.note_curdelay[i]--;
if (!psi.note_curdelay[i])
{
opl_write(0xA0+i, 0x00);
opl_write(0xB0+i, 0x00);
unsigned char event = tune[ptr++];
#ifdef DEBUG
AdPlug_LogWrite("channel %02X, event %02X:\n",i+1,event);
#endif
// end of sequence ?
if (!event)
{
ptr = (psi.seq_table[(i<<1) * 2 + 3] << 8) + psi.seq_table[(i<<1) * 2 + 2];
event = tune[ptr++];
#ifdef DEBUG
AdPlug_LogWrite(" channel %02X, event %02X:\n",i+1,event);
#endif
// set sequence loop flag
psi.looping[i] = 1;
// module loop ?
plr.looping = 1;
for(int j=0; j<8; j++)
plr.looping &= psi.looping[j];
}
// new note delay ?
if (event & 0x80)
{
psi.note_delay[i] = (event & 0x7F);
event = tune[ptr++];
#ifdef DEBUG
AdPlug_LogWrite(" channel %02X, event %02X:\n",i+1,event);
#endif
}
psi.note_curdelay[i] = psi.note_delay[i];
// play note
unsigned short note = psi_notes[event & 0x0F];
opl_write(0xA0+i, note & 0xFF);
opl_write(0xB0+i, (note >> 8) + ((event >> 2) & 0xFC));
// save position
psi.seq_table[(i<<1) * 2] = ptr & 0xff;
psi.seq_table[(i<<1) * 2 + 1] = ptr >> 8;
}
}
}
float CxadpsiPlayer::xadplayer_getrefresh()
{
return 70.0f;
}
std::string CxadpsiPlayer::xadplayer_gettype()
{
return std::string("xad: psi player");
}
unsigned int CxadpsiPlayer::xadplayer_getinstruments()
{
return 8;
}
adplug-2.2.1+dfsg3/src/a2m.h 0000644 0001750 0001750 00000005705 10606235013 014706 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* a2m.h - A2M Loader by Simon Peter
*/
#ifndef H_ADPLUG_A2MLOADER
#define H_ADPLUG_A2MLOADER
#include "protrack.h"
class Ca2mLoader: public CmodPlayer
{
public:
static CPlayer *factory(Copl *newopl);
Ca2mLoader(Copl *newopl): CmodPlayer(newopl)
{ }
bool load(const std::string &filename, const CFileProvider &fp);
float getrefresh();
std::string gettype()
{ return std::string("AdLib Tracker 2"); }
std::string gettitle()
{ if(*songname) return std::string(songname,1,*songname); else return std::string(); }
std::string getauthor()
{ if(*author) return std::string(author,1,*author); else return std::string(); }
unsigned int getinstruments()
{ return 250; }
std::string getinstrument(unsigned int n)
{ return std::string(instname[n],1,*instname[n]); }
private:
#define ADPLUG_A2M_COPYRANGES 6
#define ADPLUG_A2M_FIRSTCODE 257
#define ADPLUG_A2M_MINCOPY 3
#define ADPLUG_A2M_MAXCOPY 255
#define ADPLUG_A2M_CODESPERRANGE (ADPLUG_A2M_MAXCOPY - ADPLUG_A2M_MINCOPY + 1)
#define ADPLUG_A2M_MAXCHAR (ADPLUG_A2M_FIRSTCODE + ADPLUG_A2M_COPYRANGES * ADPLUG_A2M_CODESPERRANGE - 1)
#define ADPLUG_A2M_TWICEMAX (2 * ADPLUG_A2M_MAXCHAR + 1)
static const unsigned int MAXFREQ, MINCOPY, MAXCOPY, COPYRANGES,
CODESPERRANGE, TERMINATE, FIRSTCODE, MAXCHAR, SUCCMAX, TWICEMAX, ROOT,
MAXBUF, MAXDISTANCE, MAXSIZE;
static const unsigned short bitvalue[14];
static const signed short copybits[ADPLUG_A2M_COPYRANGES],
copymin[ADPLUG_A2M_COPYRANGES];
void inittree();
void updatefreq(unsigned short a,unsigned short b);
void updatemodel(unsigned short code);
unsigned short inputcode(unsigned short bits);
unsigned short uncompress();
void decode();
unsigned short sixdepak(unsigned short *source,unsigned char *dest,unsigned short size);
char songname[43], author[43], instname[250][33];
unsigned short ibitcount, ibitbuffer, ibufcount, obufcount, input_size,
output_size, leftc[ADPLUG_A2M_MAXCHAR+1], rghtc[ADPLUG_A2M_MAXCHAR+1],
dad[ADPLUG_A2M_TWICEMAX+1], freq[ADPLUG_A2M_TWICEMAX+1], *wdbuf;
unsigned char *obuf, *buf;
};
#endif
adplug-2.2.1+dfsg3/src/mad.cpp 0000644 0001750 0001750 00000006045 10754126625 015335 0 ustar gregoa gregoa /*
Adplug - Replayer for many OPL2/OPL3 audio file formats.
Copyright (C) 1999 - 2003 Simon Peter, , et al.
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.1 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 Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
mad.cpp - MAD loader by Riven the Mage
*/
#include
#include "mad.h"
/* -------- Public Methods -------------------------------- */
CPlayer *CmadLoader::factory(Copl *newopl)
{
return new CmadLoader(newopl);
}
bool CmadLoader::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
const unsigned char conv_inst[10] = { 2,1,10,9,4,3,6,5,8,7 };
unsigned int i, j, k, t = 0;
// 'MAD+' - signed ?
char id[4]; f->readString(id, 4);
if (strncmp(id,"MAD+",4)) { fp.close(f); return false; }
// load instruments
for(i = 0; i < 9; i++) {
f->readString(instruments[i].name, 8);
for(j = 0; j < 12; j++) instruments[i].data[j] = f->readInt(1);
}
f->ignore(1);
// data for Protracker
length = f->readInt(1); nop = f->readInt(1); timer = f->readInt(1);
// init CmodPlayer
realloc_instruments(9);
realloc_order(length);
realloc_patterns(nop,32,9);
init_trackord();
// load tracks
for(i = 0; i < nop; i++)
for(k = 0; k < 32; k++)
for(j = 0; j < 9; j++) {
t = i * 9 + j;
// read event
unsigned char event = f->readInt(1);
// convert event
if (event < 0x61)
tracks[t][k].note = event;
if (event == 0xFF) // 0xFF: Release note
tracks[t][k].command = 8;
if (event == 0xFE) // 0xFE: Pattern Break
tracks[t][k].command = 13;
}
// load order
for(i = 0; i < length; i++) order[i] = f->readInt(1) - 1;
fp.close(f);
// convert instruments
for(i = 0; i < 9; i++)
for(j = 0; j < 10; j++)
inst[i].data[conv_inst[j]] = instruments[i].data[j];
// data for Protracker
restartpos = 0;
initspeed = 1;
rewind(0);
return true;
}
void CmadLoader::rewind(int subsong)
{
CmodPlayer::rewind(subsong);
// default instruments
for (int i=0;i<9;i++)
{
channel[i].inst = i;
channel[i].vol1 = 63 - (inst[i].data[10] & 63);
channel[i].vol2 = 63 - (inst[i].data[9] & 63);
}
}
float CmadLoader::getrefresh()
{
return (float)timer;
}
std::string CmadLoader::gettype()
{
return std::string("Mlat Adlib Tracker");
}
std::string CmadLoader::getinstrument(unsigned int n)
{
return std::string(instruments[n].name,8);
}
unsigned int CmadLoader::getinstruments()
{
return 9;
}
adplug-2.2.1+dfsg3/src/silentopl.h 0000644 0001750 0001750 00000002042 10323445316 016234 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* silentopl.h - Silent OPL device, by Simon Peter (dn.tlp@gmx.net)
*/
#include "opl.h"
class CSilentopl: public Copl
{
public:
void write(int reg, int val) {}
void init() {}
};
adplug-2.2.1+dfsg3/src/fprovide.cpp 0000644 0001750 0001750 00000004034 07624210412 016374 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2002 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* fprovide.cpp - File provider class framework, by Simon Peter
*/
#include
#include
#include
#include "fprovide.h"
/***** CFileProvider *****/
bool CFileProvider::extension(const std::string &filename,
const std::string &extension)
{
const char *fname = filename.c_str(), *ext = extension.c_str();
if(strlen(fname) < strlen(ext) ||
stricmp(fname + strlen(fname) - strlen(ext), ext))
return false;
else
return true;
}
unsigned long CFileProvider::filesize(binistream *f)
{
unsigned long oldpos = f->pos(), size;
f->seek(0, binio::End);
size = f->pos();
f->seek(oldpos, binio::Set);
return size;
}
/***** CProvider_Filesystem *****/
binistream *CProvider_Filesystem::open(std::string filename) const
{
binifstream *f = new binifstream(filename);
if(!f) return 0;
if(f->error()) { delete f; return 0; }
// Open all files as little endian with IEEE floats by default
f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE);
return f;
}
void CProvider_Filesystem::close(binistream *f) const
{
binifstream *ff = (binifstream *)f;
if(f) {
ff->close();
delete ff;
}
}
adplug-2.2.1+dfsg3/src/rad.cpp 0000644 0001750 0001750 00000007426 10754126627 015350 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* rad.cpp - RAD Loader by Simon Peter
*
* BUGS:
* some volumes are dropped out
*/
#include
#include "rad.h"
CPlayer *CradLoader::factory(Copl *newopl)
{
return new CradLoader(newopl);
}
bool CradLoader::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename); if(!f) return false;
char id[16];
unsigned char buf,ch,c,b,inp;
char bufstr[2] = "\0";
unsigned int i,j;
unsigned short patofs[32];
const unsigned char convfx[16] = {255,1,2,3,255,5,255,255,255,255,20,255,17,0xd,255,19};
// file validation section
f->readString(id, 16); version = f->readInt(1);
if(strncmp(id,"RAD by REALiTY!!",16) || version != 0x10)
{ fp.close(f); return false; }
// load section
radflags = f->readInt(1);
if(radflags & 128) { // description
memset(desc,0,80*22);
while((buf = f->readInt(1)))
if(buf == 1)
strcat(desc,"\n");
else
if(buf >= 2 && buf <= 0x1f)
for(i=0;ireadInt(1))) { // instruments
buf--;
inst[buf].data[2] = f->readInt(1); inst[buf].data[1] = f->readInt(1);
inst[buf].data[10] = f->readInt(1); inst[buf].data[9] = f->readInt(1);
inst[buf].data[4] = f->readInt(1); inst[buf].data[3] = f->readInt(1);
inst[buf].data[6] = f->readInt(1); inst[buf].data[5] = f->readInt(1);
inst[buf].data[0] = f->readInt(1);
inst[buf].data[8] = f->readInt(1); inst[buf].data[7] = f->readInt(1);
}
length = f->readInt(1);
for(i = 0; i < length; i++) order[i] = f->readInt(1); // orderlist
for(i = 0; i < 32; i++) patofs[i] = f->readInt(2); // pattern offset table
init_trackord(); // patterns
for(i=0;i<32;i++)
if(patofs[i]) {
f->seek(patofs[i]);
do {
buf = f->readInt(1); b = buf & 127;
do {
ch = f->readInt(1); c = ch & 127;
inp = f->readInt(1);
tracks[i*9+c][b].note = inp & 127;
tracks[i*9+c][b].inst = (inp & 128) >> 3;
inp = f->readInt(1);
tracks[i*9+c][b].inst += inp >> 4;
tracks[i*9+c][b].command = inp & 15;
if(inp & 15) {
inp = f->readInt(1);
tracks[i*9+c][b].param1 = inp / 10;
tracks[i*9+c][b].param2 = inp % 10;
}
} while(!(ch & 128));
} while(!(buf & 128));
} else
memset(trackord[i],0,9*2);
fp.close(f);
// convert replay data
for(i=0;i<32*9;i++) // convert patterns
for(j=0;j<64;j++) {
if(tracks[i][j].note == 15)
tracks[i][j].note = 127;
if(tracks[i][j].note > 16 && tracks[i][j].note < 127)
tracks[i][j].note -= 4 * (tracks[i][j].note >> 4);
if(tracks[i][j].note && tracks[i][j].note < 126)
tracks[i][j].note++;
tracks[i][j].command = convfx[tracks[i][j].command];
}
restartpos = 0; initspeed = radflags & 31;
bpm = radflags & 64 ? 0 : 50; flags = Decimal;
rewind(0);
return true;
}
float CradLoader::getrefresh()
{
if(tempo)
return (float) (tempo);
else
return 18.2f;
}
adplug-2.2.1+dfsg3/src/jbm.h 0000644 0001750 0001750 00000004202 10611243112 014761 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* jbm.h - JBM Player by Dennis Lindroos
*/
#ifndef H_ADPLUG_JBMPLAYER
#define H_ADPLUG_JBMPLAYER
#include "player.h"
class CjbmPlayer: public CPlayer
{
public:
static CPlayer *factory(Copl *newopl);
CjbmPlayer(Copl *newopl) : CPlayer(newopl), m(0)
{ }
~CjbmPlayer()
{ if(m != NULL) delete [] m; }
bool load(const std::string &filename, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh()
{ return timer; }
std::string gettype()
{
return std::string(flags&1 ? "JBM Adlib Music [rhythm mode]" :
"JBM Adlib Music");
}
std::string getauthor()
{ return std::string("Johannes Bjerregaard"); }
protected:
unsigned char *m;
float timer;
unsigned short flags, voicemask;
unsigned short seqtable, seqcount;
unsigned short instable, inscount;
unsigned short *sequences;
unsigned char bdreg;
typedef struct {
unsigned short trkpos, trkstart, seqpos;
unsigned char seqno, note;
short vol;
short delay;
short instr;
unsigned char frq[2];
unsigned char ivol, dummy;
} JBMVoice;
JBMVoice voice[11];
private:
//void calc_opl_frequency(JBMVoice *);
void set_opl_instrument(int, JBMVoice *);
void opl_noteonoff(int, JBMVoice *, bool);
};
#endif
adplug-2.2.1+dfsg3/src/raw.h 0000644 0001750 0001750 00000002747 10323445316 015030 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2005 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* raw.h - RAW Player by Simon Peter
*/
#include "player.h"
class CrawPlayer: public CPlayer
{
public:
static CPlayer *factory(Copl *newopl);
CrawPlayer(Copl *newopl)
: CPlayer(newopl), data(0)
{ };
~CrawPlayer()
{ if(data) delete [] data; };
bool load(const std::string &filename, const CFileProvider &fp);
bool update();
void rewind(int subsong);
float getrefresh();
std::string gettype()
{ return std::string("RdosPlay RAW"); };
protected:
struct Tdata {
unsigned char param, command;
} *data;
unsigned long pos, length;
unsigned short clock, speed;
unsigned char del;
bool songend;
};
adplug-2.2.1+dfsg3/src/bmf.cpp 0000644 0001750 0001750 00000034216 10754126624 015340 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2003, 2006 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* [xad] BMF player, by Riven the Mage
*/
/*
- discovery -
file(s) : GAMESNET.COM
type : GamesNet advertising intro
tune : by (?)The Brain [Razor 1911]
player : ver.0.9b by Hammer
file(s) : 2FAST4U.COM
type : Ford Knox BBStro
tune : by The Brain [Razor 1911]
player : ver.1.1 by ?
comment : in original player at 9th channel the feedback adlib register is not C8 but C6.
file(s) : DATURA.COM
type : Datura BBStro
tune : by The Brain [Razor 1911]
player : ver.1.2 by ?
comment : inaccurate replaying, because constant outport; in original player it can be 380 or 382.
*/
#include
#include "bmf.h"
#include "debug.h"
const unsigned char CxadbmfPlayer::bmf_adlib_registers[117] =
{
0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0, 0xE0, 0xE3,
0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1, 0xE1, 0xE4,
0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2, 0xE2, 0xE5,
0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3, 0xE8, 0xEB,
0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4, 0xE9, 0xEC,
0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5, 0xEA, 0xED,
0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6, 0xF0, 0xF3,
0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7, 0xF1, 0xF4,
0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8, 0xF2, 0xF5
};
const unsigned short CxadbmfPlayer::bmf_notes[12] =
{
0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287
};
/* for 1.1 */
const unsigned short CxadbmfPlayer::bmf_notes_2[12] =
{
0x159, 0x16D, 0x183, 0x19A, 0x1B2, 0x1CC, 0x1E8, 0x205, 0x223, 0x244, 0x267, 0x28B
};
const unsigned char CxadbmfPlayer::bmf_default_instrument[13] =
{
0x01, 0x01, 0x3F, 0x3F, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00
};
CPlayer *CxadbmfPlayer::factory(Copl *newopl)
{
return new CxadbmfPlayer(newopl);
}
bool CxadbmfPlayer::xadplayer_load()
{
unsigned short ptr = 0;
int i;
if(xad.fmt != BMF)
return false;
#ifdef DEBUG
AdPlug_LogWrite("\nbmf_load():\n\n");
#endif
if (!strncmp((char *)&tune[0],"BMF1.2",6))
{
bmf.version = BMF1_2;
bmf.timer = 70.0f;
}
else if (!strncmp((char *)&tune[0],"BMF1.1",6))
{
bmf.version = BMF1_1;
bmf.timer = 60.0f;
}
else
{
bmf.version = BMF0_9B;
bmf.timer = 18.2f;
}
// copy title & author
if (bmf.version > BMF0_9B)
{
ptr = 6;
strncpy(bmf.title,(char *)&tune[ptr],36);
while (tune[ptr]) { ptr++; }
ptr++;
strncpy(bmf.author,(char *)&tune[ptr],36);
while (tune[ptr]) { ptr++; }
ptr++;
}
else
{
strncpy(bmf.title,xad.title,36);
strncpy(bmf.author,xad.author,36);
}
// speed
if (bmf.version > BMF0_9B)
bmf.speed = tune[ptr++];
else
bmf.speed = ((tune[ptr++] << 8) / 3) >> 8; // strange, yeh ?
// load instruments
if (bmf.version > BMF0_9B)
{
unsigned long iflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3];
ptr+=4;
for(i=0;i<32;i++)
if (iflags & (1 << (31-i)))
{
strcpy(bmf.instruments[i].name, (char *)&tune[ptr]);
memcpy(bmf.instruments[i].data, &tune[ptr+11], 13);
ptr += 24;
}
else
{
bmf.instruments[i].name[0] = 0;
if (bmf.version == BMF1_1)
for(int j=0;j<13;j++)
bmf.instruments[i].data[j] = bmf_default_instrument[j];
else
for(int j=0;j<13;j++)
bmf.instruments[i].data[j] = 0;
}
}
else
{
ptr = 6;
for(i=0;i<32;i++)
{
bmf.instruments[i].name[0] = 0;
memcpy(bmf.instruments[tune[ptr]].data, &tune[ptr+2],13); // bug no.1 (no instrument-table-end detection)
ptr+=15;
}
}
// load streams
if (bmf.version > BMF0_9B)
{
unsigned long sflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3];
ptr+=4;
for(i=0;i<9;i++)
if (sflags & (1 << (31-i)))
ptr+=__bmf_convert_stream(&tune[ptr],i);
else
bmf.streams[i][0].cmd = 0xFF;
}
else
{
for(i=0;i BMF0_9B)
{
opl_write(0x01, 0x20);
/* 1.1 */
if (bmf.version == BMF1_1)
for(i=0;i<9;i++)
for(j=0;j<13;j++)
opl_write(bmf_adlib_registers[13*i+j], bmf_default_instrument[j]);
/* 1.2 */
else if (bmf.version == BMF1_2)
for(i=0x20; i<0x100; i++)
opl_write(i,0xFF); // very interesting, really!
}
/* ALL */
opl_write(0x08, 0x00);
opl_write(0xBD, 0xC0);
}
void CxadbmfPlayer::xadplayer_update()
{
for(int i=0;i<9;i++)
if (bmf.channel[i].stream_position != 0xFFFF)
if (bmf.channel[i].delay)
bmf.channel[i].delay--;
else
{
#ifdef DEBUG
AdPlug_LogWrite("channel %02X:\n", i);
#endif
bmf_event event;
// process so-called cross-events
while (true)
{
memcpy(&event, &bmf.streams[i][bmf.channel[i].stream_position], sizeof(bmf_event));
#ifdef DEBUG
AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X\n",
event.note,event.delay,event.volume,event.instrument,
event.cmd,event.cmd_data);
#endif
if (event.cmd == 0xFF)
{
bmf.channel[i].stream_position = 0xFFFF;
bmf.active_streams--;
break;
}
else if (event.cmd == 0xFE)
{
bmf.channel[i].loop_position = bmf.channel[i].stream_position+1;
bmf.channel[i].loop_counter = event.cmd_data;
}
else if (event.cmd == 0xFD)
{
if (bmf.channel[i].loop_counter)
{
bmf.channel[i].stream_position = bmf.channel[i].loop_position-1;
bmf.channel[i].loop_counter--;
}
}
else
break;
bmf.channel[i].stream_position++;
} // while (true)
// process normal event
unsigned short pos = bmf.channel[i].stream_position;
if (pos != 0xFFFF)
{
bmf.channel[i].delay = bmf.streams[i][pos].delay;
// command ?
if (bmf.streams[i][pos].cmd)
{
unsigned char cmd = bmf.streams[i][pos].cmd;
// 0x01: Set Modulator Volume
if (cmd == 0x01)
{
unsigned char reg = bmf_adlib_registers[13*i+2];
opl_write(reg, (adlib[reg] | 0x3F) - bmf.streams[i][pos].cmd_data);
}
// 0x10: Set Speed
else if (cmd == 0x10)
{
plr.speed = bmf.streams[i][pos].cmd_data;
plr.speed_counter = plr.speed;
}
} // if (bmf.streams[i][pos].cmd)
// instrument ?
if (bmf.streams[i][pos].instrument)
{
unsigned char ins = bmf.streams[i][pos].instrument-1;
if (bmf.version != BMF1_1)
opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
for(int j=0;j<13;j++)
opl_write(bmf_adlib_registers[i*13+j], bmf.instruments[ins].data[j]);
} // if (bmf.streams[i][pos].instrument)
// volume ?
if (bmf.streams[i][pos].volume)
{
unsigned char vol = bmf.streams[i][pos].volume-1;
unsigned char reg = bmf_adlib_registers[13*i+3];
opl_write(reg, (adlib[reg] | 0x3F) - vol);
} // if (bmf.streams[i][pos].volume)
// note ?
if (bmf.streams[i][pos].note)
{
unsigned short note = bmf.streams[i][pos].note;
unsigned short freq = 0;
// mute channel
opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
// get frequency
if (bmf.version == BMF1_1)
{
if (note <= 0x60)
freq = bmf_notes_2[--note % 12];
}
else
{
if (note != 0x7F)
freq = bmf_notes[--note % 12];
}
// play note
if (freq)
{
opl_write(0xB0+i, (freq >> 8) | ((note / 12) << 2) | 0x20);
opl_write(0xA0+i, freq & 0xFF);
}
} // if (bmf.streams[i][pos].note)
bmf.channel[i].stream_position++;
} // if (pos != 0xFFFF)
} // if (!bmf.channel[i].delay)
// is module loop ?
if (!bmf.active_streams)
{
for(int j=0;j<9;j++)
bmf.channel[j].stream_position = 0;
bmf.active_streams = 9;
plr.looping = 1;
}
}
float CxadbmfPlayer::xadplayer_getrefresh()
{
return bmf.timer;
}
std::string CxadbmfPlayer::xadplayer_gettype()
{
return std::string("xad: BMF Adlib Tracker");
}
std::string CxadbmfPlayer::xadplayer_gettitle()
{
return std::string(bmf.title);
}
std::string CxadbmfPlayer::xadplayer_getauthor()
{
return std::string(bmf.author);
}
unsigned int CxadbmfPlayer::xadplayer_getinstruments()
{
return 32;
}
std::string CxadbmfPlayer::xadplayer_getinstrument(unsigned int i)
{
return std::string(bmf.instruments[i].name);
}
/* -------- Internal Functions ---------------------------- */
int CxadbmfPlayer::__bmf_convert_stream(unsigned char *stream, int channel)
{
#ifdef DEBUG
AdPlug_LogWrite("channel %02X (note,delay,volume,instrument,command,command_data):\n",channel);
unsigned char *last = stream;
#endif
unsigned char *stream_start = stream;
int pos = 0;
while (true)
{
memset(&bmf.streams[channel][pos], 0, sizeof(bmf_event));
bool is_cmd = false;
if (*stream == 0xFE)
{
// 0xFE -> 0xFF: End of Stream
bmf.streams[channel][pos].cmd = 0xFF;
stream++;
break;
}
else if (*stream == 0xFC)
{
// 0xFC -> 0xFE xx: Save Loop Position
bmf.streams[channel][pos].cmd = 0xFE;
bmf.streams[channel][pos].cmd_data = (*(stream+1) & ((bmf.version == BMF0_9B) ? 0x7F : 0x3F)) - 1;
stream+=2;
}
else if (*stream == 0x7D)
{
// 0x7D -> 0xFD: Loop Saved Position
bmf.streams[channel][pos].cmd = 0xFD;
stream++;
}
else
{
if (*stream & 0x80)
{
if (*(stream+1) & 0x80)
{
if (*(stream+1) & 0x40)
{
// byte0: 1aaaaaaa = NOTE
bmf.streams[channel][pos].note = *stream & 0x7F;
// byte1: 11bbbbbb = DELAY
bmf.streams[channel][pos].delay = *(stream+1) & 0x3F;
// byte2: cccccccc = COMMAND
stream+=2;
is_cmd = true;
}
else
{
// byte0: 1aaaaaaa = NOTE
bmf.streams[channel][pos].note = *stream & 0x7F;
// byte1: 11bbbbbb = DELAY
bmf.streams[channel][pos].delay = *(stream+1) & 0x3F;
stream+=2;
} // if (*(stream+1) & 0x40)
}
else
{
// byte0: 1aaaaaaa = NOTE
bmf.streams[channel][pos].note = *stream & 0x7F;
// byte1: 0bbbbbbb = COMMAND
stream++;
is_cmd = true;
} // if (*(stream+1) & 0x80)
}
else
{
// byte0: 0aaaaaaa = NOTE
bmf.streams[channel][pos].note = *stream & 0x7F;
stream++;
} // if (*stream & 0x80)
} // if (*stream == 0xFE)
// is command ?
if (is_cmd)
{
/* ALL */
if ((0x20 <= *stream) && (*stream <= 0x3F))
{
// 0x20 or higher; 0x3F or lower: Set Instrument
bmf.streams[channel][pos].instrument = *stream - 0x20 + 1;
stream++;
}
else if (0x40 <= *stream)
{
// 0x40 or higher: Set Volume
bmf.streams[channel][pos].volume = *stream - 0x40 + 1;
stream++;
}
else
{
/* 0.9b */
if (bmf.version == BMF0_9B)
if (*stream < 0x20)
{
// 0x1F or lower: ?
stream++;
}
/* 1.2 */
if (bmf.version == BMF1_2)
if (*stream == 0x01)
{
// 0x01: Set Modulator Volume -> 0x01
bmf.streams[channel][pos].cmd = 0x01;
bmf.streams[channel][pos].cmd_data = *(stream+1);
stream+=2;
}
else if (*stream == 0x02)
{
// 0x02: ?
stream+=2;
}
else if (*stream == 0x03)
{
// 0x03: ?
stream+=2;
}
else if (*stream == 0x04)
{
// 0x04: Set Speed -> 0x10
bmf.streams[channel][pos].cmd = 0x10;
bmf.streams[channel][pos].cmd_data = *(stream+1);
stream+=2;
}
else if (*stream == 0x05)
{
// 0x05: Set Carrier Volume (port 380)
bmf.streams[channel][pos].volume = *(stream+1) + 1;
stream+=2;
}
else if (*stream == 0x06)
{
// 0x06: Set Carrier Volume (port 382)
bmf.streams[channel][pos].volume = *(stream+1) + 1;
stream+=2;
} // if (bmf.version == BMF1_2)
} // if ((0x20 <= *stream) && (*stream <= 0x3F))
} // if (is_cmd)
#ifdef DEBUG
AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X <---- ",
bmf.streams[channel][pos].note,
bmf.streams[channel][pos].delay,
bmf.streams[channel][pos].volume,
bmf.streams[channel][pos].instrument,
bmf.streams[channel][pos].cmd,
bmf.streams[channel][pos].cmd_data
);
for(int zz=0;zz<(stream-last);zz++)
AdPlug_LogWrite("%02X ",last[zz]);
AdPlug_LogWrite("\n");
last=stream;
#endif
pos++;
} // while (true)
return (stream - stream_start);
}
adplug-2.2.1+dfsg3/src/dro2.cpp 0000644 0001750 0001750 00000006730 11317301320 015422 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2007 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* dro2.cpp - DOSBox Raw OPL v2.0 player by Adam Nielsen
*/
#include
#include
#include "dro2.h"
CPlayer *Cdro2Player::factory(Copl *newopl)
{
return new Cdro2Player(newopl);
}
Cdro2Player::Cdro2Player(Copl *newopl) :
CPlayer(newopl),
piConvTable(NULL),
data(0)
{
}
Cdro2Player::~Cdro2Player()
{
if (this->data) delete[] this->data;
if (this->piConvTable) delete[] this->piConvTable;
}
bool Cdro2Player::load(const std::string &filename, const CFileProvider &fp)
{
binistream *f = fp.open(filename);
if (!f) return false;
char id[8];
f->readString(id, 8);
if (strncmp(id, "DBRAWOPL", 8)) {
fp.close(f);
return false;
}
int version = f->readInt(4);
if (version != 0x2) {
fp.close(f);
return false;
}
this->iLength = f->readInt(4) * 2; // stored in file as number of byte pairs
f->ignore(4); // Length in milliseconds
f->ignore(1); /// OPL type (0 == OPL2, 1 == Dual OPL2, 2 == OPL3)
int iFormat = f->readInt(1);
if (iFormat != 0) {
fp.close(f);
return false;
}
int iCompression = f->readInt(1);
if (iCompression != 0) {
fp.close(f);
return false;
}
this->iCmdDelayS = f->readInt(1);
this->iCmdDelayL = f->readInt(1);
this->iConvTableLen = f->readInt(1);
this->piConvTable = new uint8_t[this->iConvTableLen];
f->readString((char *)this->piConvTable, this->iConvTableLen);
this->data = new uint8_t[this->iLength];
f->readString((char *)this->data, this->iLength);
fp.close(f);
rewind(0);
return true;
}
bool Cdro2Player::update()
{
while (this->iPos < this->iLength) {
int iIndex = this->data[this->iPos++];
int iValue = this->data[this->iPos++];
// Short delay
if (iIndex == this->iCmdDelayS) {
this->iDelay = iValue + 1;
return true;
// Long delay
} else if (iIndex == this->iCmdDelayL) {
this->iDelay = (iValue + 1) << 8;
return true;
// Normal write
} else {
if (iIndex & 0x80) {
// High bit means use second chip in dual-OPL2 config
this->opl->setchip(1);
iIndex &= 0x7F;
} else {
this->opl->setchip(0);
}
if (iIndex > this->iConvTableLen) {
printf("DRO2: Error - index beyond end of codemap table! Corrupted .dro?\n");
return false; // EOF
}
int iReg = this->piConvTable[iIndex];
this->opl->write(iReg, iValue);
}
}
// This won't result in endless-play using Adplay, but IMHO that code belongs
// in Adplay itself, not here.
return this->iPos < this->iLength;
}
void Cdro2Player::rewind(int subsong)
{
this->iDelay = 0;
this->iPos = 0;
opl->init();
}
float Cdro2Player::getrefresh()
{
if (this->iDelay > 0) return 1000.0 / this->iDelay;
else return 1000.0;
}
adplug-2.2.1+dfsg3/src/msc.cpp 0000644 0001750 0001750 00000015056 10754126626 015361 0 ustar gregoa gregoa /*
* Adplug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2006 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* msc.c - MSC Player by Lubomir Bulej (pallas@kadan.cz)
*/
#include
#include
#include "msc.h"
#include "debug.h"
const unsigned char CmscPlayer::msc_signature [MSC_SIGN_LEN] = {
'C', 'e', 'r', 'e', 's', ' ', '\x13', ' ',
'M', 'S', 'C', 'p', 'l', 'a', 'y', ' ' };
/*** public methods *************************************/
CPlayer *CmscPlayer::factory (Copl * newopl)
{
return new CmscPlayer (newopl);
}
CmscPlayer::CmscPlayer(Copl * newopl) : CPlayer (newopl)
{
desc = NULL;
msc_data = NULL;
raw_data = NULL;
nr_blocks = 0;
}
CmscPlayer::~CmscPlayer()
{
if (raw_data != NULL)
delete [] raw_data;
if (msc_data != NULL) {
// free compressed blocks
for (int blk_num = 0; blk_num < nr_blocks; blk_num++) {
if (msc_data [blk_num].mb_data != NULL)
delete [] msc_data [blk_num].mb_data;
}
delete [] msc_data;
}
if (desc != NULL)
delete [] desc;
}
bool CmscPlayer::load(const std::string & filename, const CFileProvider & fp)
{
binistream * bf;
msc_header hdr;
// open and validate the file
bf = fp.open (filename);
if (! bf)
return false;
if (! load_header (bf, & hdr)) {
fp.close (bf);
return false;
}
// get stuff from the header
version = hdr.mh_ver;
timer_div = hdr.mh_timer;
nr_blocks = hdr.mh_nr_blocks;
block_len = hdr.mh_block_len;
if (! nr_blocks) {
fp.close (bf);
return false;
}
// load compressed data blocks
msc_data = new msc_block [nr_blocks];
raw_data = new u8 [block_len];
for (int blk_num = 0; blk_num < nr_blocks; blk_num++) {
msc_block blk;
blk.mb_length = bf->readInt (2);
blk.mb_data = new u8 [blk.mb_length];
for (int oct_num = 0; oct_num < blk.mb_length; oct_num++) {
blk.mb_data [oct_num] = bf->readInt (1);
}
msc_data [blk_num] = blk;
}
// clean up & initialize
fp.close (bf);
rewind (0);
return true;
}
bool CmscPlayer::update()
{
// output data
while (! delay) {
u8 cmnd;
u8 data;
// decode data
if (! decode_octet (& cmnd))
return false;
if (! decode_octet (& data))
return false;
// check for special commands
switch (cmnd) {
// delay
case 0xff:
delay = 1 + (u8) (data - 1);
break;
// play command & data
default:
opl->write (cmnd, data);
} // command switch
} // play pass
// count delays
if (delay)
delay--;
// advance player position
play_pos++;
return true;
}
void CmscPlayer::rewind(int subsong)
{
// reset state
dec_prefix = 0;
block_num = 0;
block_pos = 0;
play_pos = 0;
raw_pos = 0;
delay = 0;
// init the OPL chip and go to OPL2 mode
opl->init();
opl->write(1, 32);
}
float CmscPlayer::getrefresh()
{
// PC timer oscillator frequency / wait register
return 1193180 / (float) (timer_div ? timer_div : 0xffff);
}
std::string CmscPlayer::gettype()
{
char vstr [40];
sprintf(vstr, "AdLib MSCplay (version %d)", version);
return std::string (vstr);
}
/*** private methods *************************************/
bool CmscPlayer::load_header(binistream * bf, msc_header * hdr)
{
// check signature
bf->readString ((char *) hdr->mh_sign, sizeof (hdr->mh_sign));
if (memcmp (msc_signature, hdr->mh_sign, MSC_SIGN_LEN) != 0)
return false;
// check version
hdr->mh_ver = bf->readInt (2);
if (hdr->mh_ver != 0)
return false;
bf->readString ((char *) hdr->mh_desc, sizeof (hdr->mh_desc));
hdr->mh_timer = bf->readInt (2);
hdr->mh_nr_blocks = bf->readInt (2);
hdr->mh_block_len = bf->readInt (2);
return true;
}
bool CmscPlayer::decode_octet(u8 * output)
{
msc_block blk; // compressed data block
if (block_num >= nr_blocks)
return false;
blk = msc_data [block_num];
while (1) {
u8 octet; // decoded octet
u8 len_corr; // length correction
// advance to next block if necessary
if (block_pos >= blk.mb_length && dec_len == 0) {
block_num++;
if (block_num >= nr_blocks)
return false;
blk = msc_data [block_num];
block_pos = 0;
raw_pos = 0;
}
// decode the compressed music data
switch (dec_prefix) {
// decode prefix
case 155:
case 175:
octet = blk.mb_data [block_pos++];
if (octet == 0) {
// invalid prefix, output original
octet = dec_prefix;
dec_prefix = 0;
break;
}
// isolate length and distance
dec_len = (octet & 0x0F);
len_corr = 2;
dec_dist = (octet & 0xF0) >> 4;
if (dec_prefix == 155)
dec_dist++;
// next decode step for respective prefix type
dec_prefix++;
continue;
// check for extended length
case 156:
if (dec_len == 15)
dec_len += blk.mb_data [block_pos++];
// add length correction and go for copy mode
dec_len += len_corr;
dec_prefix = 255;
continue;
// get extended distance
case 176:
dec_dist += 17 + 16 * blk.mb_data [block_pos++];
len_corr = 3;
// check for extended length
dec_prefix = 156;
continue;
// prefix copy mode
case 255:
if((int)raw_pos >= dec_dist)
octet = raw_data [raw_pos - dec_dist];
else {
AdPlug_LogWrite("error! read before raw_data buffer.\n");
octet = 0;
}
dec_len--;
if (dec_len == 0) {
// back to normal mode
dec_prefix = 0;
}
break;
// normal mode
default:
octet = blk.mb_data [block_pos++];
if (octet == 155 || octet == 175) {
// it's a prefix, restart
dec_prefix = octet;
continue;
}
} // prefix switch
// output the octet
if (output != NULL)
*output = octet;
raw_data [raw_pos++] = octet;
break;
}; // decode pass
return true;
}
adplug-2.2.1+dfsg3/src/adplug.h 0000644 0001750 0001750 00000003216 07623712626 015515 0 ustar gregoa gregoa /*
* AdPlug - Replayer for many OPL2/OPL3 audio file formats.
* Copyright (C) 1999 - 2003 Simon Peter, , et al.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* adplug.h - AdPlug main header file, by Simon Peter
*/
#ifndef H_ADPLUG_ADPLUG
#define H_ADPLUG_ADPLUG
#include
#include "player.h"
#include "opl.h"
#include "fprovide.h"
#include "players.h"
#include "database.h"
class CAdPlug
{
friend CPlayer::CPlayer(Copl *newopl);
public:
static const CPlayers players;
static CPlayer *factory(const std::string &fn, Copl *opl,
const CPlayers &pl = players,
const CFileProvider &fp = CProvider_Filesystem());
static void set_database(CAdPlugDatabase *db);
static std::string get_version();
static void debug_output(const std::string &filename);
private:
static CAdPlugDatabase *database;
static const CPlayerDesc allplayers[];
static const CPlayers &init_players(const CPlayerDesc pd[]);
};
#endif
adplug-2.2.1+dfsg3/src/fmopl.c 0000644 0001750 0001750 00000106045 07751473455 015363 0 ustar gregoa gregoa /*
**
** File: fmopl.c -- software implementation of FM sound generator
**
** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmurator development
**
** Version 0.37a
**
*/
/*
preliminary :
Problem :
note:
*/
/* This version of fmopl.c is a fork of the MAME one, relicensed under the LGPL.
*
* 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.1 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 Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define INLINE __inline
#define HAS_YM3812 1
#include
#include
#include
#include
#include
//#include "driver.h" /* use M.A.M.E. */
#include "fmopl.h"
#ifndef PI
#define PI 3.14159265358979323846
#endif
/* -------------------- for debug --------------------- */
/* #define OPL_OUTPUT_LOG */
#ifdef OPL_OUTPUT_LOG
static FILE *opl_dbg_fp = NULL;
static FM_OPL *opl_dbg_opl[16];
static int opl_dbg_maxchip,opl_dbg_chip;
#endif
/* -------------------- preliminary define section --------------------- */
/* attack/decay rate time rate */
#define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */
#define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */
#define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */
#define FREQ_BITS 24 /* frequency turn */
/* counter bits = 20 , octerve 7 */
#define FREQ_RATE (1<<(FREQ_BITS-20))
#define TL_BITS (FREQ_BITS+2)
/* final output shift , limit minimum and maximum */
#define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */
#define OPL_MAXOUT (0x7fff<=LOG_LEVEL ) logerror x
#define LOG(n,x)
/* --------------------- subroutines --------------------- */
INLINE int Limit( int val, int max, int min ) {
if ( val > max )
val = max;
else if ( val < min )
val = min;
return val;
}
/* status set and IRQ handling */
INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag)
{
/* set status flag */
OPL->status |= flag;
if(!(OPL->status & 0x80))
{
if(OPL->status & OPL->statusmask)
{ /* IRQ on */
OPL->status |= 0x80;
/* callback user interrupt handler (IRQ is OFF to ON) */
if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1);
}
}
}
/* status reset and IRQ handling */
INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag)
{
/* reset status flag */
OPL->status &=~flag;
if((OPL->status & 0x80))
{
if (!(OPL->status & OPL->statusmask) )
{
OPL->status &= 0x7f;
/* callback user interrupt handler (IRQ is ON to OFF) */
if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0);
}
}
}
/* IRQ mask set */
INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag)
{
OPL->statusmask = flag;
/* IRQ handling check */
OPL_STATUS_SET(OPL,0);
OPL_STATUS_RESET(OPL,0);
}
/* ----- key on ----- */
INLINE void OPL_KEYON(OPL_SLOT *SLOT)
{
/* sin wave restart */
SLOT->Cnt = 0;
/* set attack */
SLOT->evm = ENV_MOD_AR;
SLOT->evs = SLOT->evsa;
SLOT->evc = EG_AST;
SLOT->eve = EG_AED;
}
/* ----- key off ----- */
INLINE void OPL_KEYOFF(OPL_SLOT *SLOT)
{
if( SLOT->evm > ENV_MOD_RR)
{
/* set envelope counter from envleope output */
SLOT->evm = ENV_MOD_RR;
if( !(SLOT->evc&EG_DST) )
//SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<evc = EG_DST;
SLOT->eve = EG_DED;
SLOT->evs = SLOT->evsr;
}
}
/* ---------- calcrate Envelope Generator & Phase Generator ---------- */
/* return : envelope output */
INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT )
{
/* calcrate envelope generator */
if( (SLOT->evc+=SLOT->evs) >= SLOT->eve )
{
switch( SLOT->evm ){
case ENV_MOD_AR: /* ATTACK -> DECAY1 */
/* next DR */
SLOT->evm = ENV_MOD_DR;
SLOT->evc = EG_DST;
SLOT->eve = SLOT->SL;
SLOT->evs = SLOT->evsd;
break;
case ENV_MOD_DR: /* DECAY -> SL or RR */
SLOT->evc = SLOT->SL;
SLOT->eve = EG_DED;
if(SLOT->eg_typ)
{
SLOT->evs = 0;
}
else
{
SLOT->evm = ENV_MOD_RR;
SLOT->evs = SLOT->evsr;
}
break;
case ENV_MOD_RR: /* RR -> OFF */
SLOT->evc = EG_OFF;
SLOT->eve = EG_OFF+1;
SLOT->evs = 0;
break;
}
}
/* calcrate envelope */
return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0);
}
/* set algorythm connection */
static void set_algorythm( OPL_CH *CH)
{
INT32 *carrier = &outd[0];
CH->connect1 = CH->CON ? carrier : &feedback2;
CH->connect2 = carrier;
}
/* ---------- frequency counter for operater update ---------- */
INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT)
{
int ksr;
/* frequency step counter */
SLOT->Incr = CH->fc * SLOT->mul;
ksr = CH->kcode >> SLOT->KSR;
if( SLOT->ksr != ksr )
{
SLOT->ksr = ksr;
/* attack , decay rate recalcration */
SLOT->evsa = SLOT->AR[ksr];
SLOT->evsd = SLOT->DR[ksr];
SLOT->evsr = SLOT->RR[ksr];
}
SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
}
/* set multi,am,vib,EG-TYP,KSR,mul */
INLINE void set_mul(FM_OPL *OPL,int slot,int v)
{
OPL_CH *CH = &OPL->P_CH[slot/2];
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
SLOT->mul = MUL_TABLE[v&0x0f];
SLOT->KSR = (v&0x10) ? 0 : 2;
SLOT->eg_typ = (v&0x20)>>5;
SLOT->vib = (v&0x40);
SLOT->ams = (v&0x80);
CALC_FCSLOT(CH,SLOT);
}
/* set ksl & tl */
INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v)
{
OPL_CH *CH = &OPL->P_CH[slot/2];
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */
SLOT->ksl = ksl ? 3-ksl : 31;
SLOT->TL = (v&0x3f)*(0.75/EG_STEP); /* 0.75db step */
if( !(OPL->mode&0x80) )
{ /* not CSM latch total level */
SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl);
}
}
/* set attack rate & decay rate */
INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v)
{
OPL_CH *CH = &OPL->P_CH[slot/2];
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
int ar = v>>4;
int dr = v&0x0f;
SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0;
SLOT->evsa = SLOT->AR[SLOT->ksr];
if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa;
SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0;
SLOT->evsd = SLOT->DR[SLOT->ksr];
if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd;
}
/* set sustain level & release rate */
INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v)
{
OPL_CH *CH = &OPL->P_CH[slot/2];
OPL_SLOT *SLOT = &CH->SLOT[slot&1];
int sl = v>>4;
int rr = v & 0x0f;
SLOT->SL = SL_TABLE[sl];
if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL;
SLOT->RR = &OPL->DR_TABLE[rr<<2];
SLOT->evsr = SLOT->RR[SLOT->ksr];
if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr;
}
/* operator output calcrator */
#define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env]
/* ---------- calcrate one of channel ---------- */
INLINE void OPL_CALC_CH( OPL_CH *CH )
{
UINT32 env_out;
OPL_SLOT *SLOT;
feedback2 = 0;
/* SLOT 1 */
SLOT = &CH->SLOT[SLOT1];
env_out=OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 )
{
/* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
else SLOT->Cnt += SLOT->Incr;
/* connectoion */
if(CH->FB)
{
int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB;
CH->op1_out[1] = CH->op1_out[0];
*CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
}
else
{
*CH->connect1 += OP_OUT(SLOT,env_out,0);
}
}else
{
CH->op1_out[1] = CH->op1_out[0];
CH->op1_out[0] = 0;
}
/* SLOT 2 */
SLOT = &CH->SLOT[SLOT2];
env_out=OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 )
{
/* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
else SLOT->Cnt += SLOT->Incr;
/* connectoion */
outd[0] += OP_OUT(SLOT,env_out, feedback2);
}
}
/* ---------- calcrate rythm block ---------- */
#define WHITE_NOISE_db 6.0
INLINE void OPL_CALC_RH( OPL_CH *CH )
{
UINT32 env_tam,env_sd,env_top,env_hh;
int whitenoise = (rand()&1)*(WHITE_NOISE_db/EG_STEP);
INT32 tone8;
OPL_SLOT *SLOT;
int env_out;
/* BD : same as FM serial mode and output level is large */
feedback2 = 0;
/* SLOT 1 */
SLOT = &CH[6].SLOT[SLOT1];
env_out=OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 )
{
/* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
else SLOT->Cnt += SLOT->Incr;
/* connectoion */
if(CH[6].FB)
{
int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB;
CH[6].op1_out[1] = CH[6].op1_out[0];
feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1);
}
else
{
feedback2 = OP_OUT(SLOT,env_out,0);
}
}else
{
feedback2 = 0;
CH[6].op1_out[1] = CH[6].op1_out[0];
CH[6].op1_out[0] = 0;
}
/* SLOT 2 */
SLOT = &CH[6].SLOT[SLOT2];
env_out=OPL_CALC_SLOT(SLOT);
if( env_out < EG_ENT-1 )
{
/* PG */
if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE);
else SLOT->Cnt += SLOT->Incr;
/* connectoion */
outd[0] += OP_OUT(SLOT,env_out, feedback2)*2;
}
// SD (17) = mul14[fnum7] + white noise
// TAM (15) = mul15[fnum8]
// TOP (18) = fnum6(mul18[fnum8]+whitenoise)
// HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise
env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise;
env_tam=OPL_CALC_SLOT(SLOT8_1);
env_top=OPL_CALC_SLOT(SLOT8_2);
env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise;
/* PG */
if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE);
else SLOT7_1->Cnt += 2*SLOT7_1->Incr;
if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE);
else SLOT7_2->Cnt += (CH[7].fc*8);
if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE);
else SLOT8_1->Cnt += SLOT8_1->Incr;
if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE);
else SLOT8_2->Cnt += (CH[8].fc*48);
tone8 = OP_OUT(SLOT8_2,whitenoise,0 );
/* SD */
if( env_sd < EG_ENT-1 )
outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8;
/* TAM */
if( env_tam < EG_ENT-1 )
outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2;
/* TOP-CY */
if( env_top < EG_ENT-1 )
outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2;
/* HH */
if( env_hh < EG_ENT-1 )
outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2;
}
/* ----------- initialize time tabls ----------- */
static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )
{
int i;
double rate;
/* make attack rate & decay rate tables */
for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;
for (i = 4;i <= 60;i++){
rate = OPL->freqbase; /* frequency rate */
if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */
rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */
rate *= (double)(EG_ENT<AR_TABLE[i] = rate / ARRATE;
OPL->DR_TABLE[i] = rate / DRRATE;
}
for (i = 60;i < 76;i++)
{
OPL->AR_TABLE[i] = EG_AED-1;
OPL->DR_TABLE[i] = OPL->DR_TABLE[60];
}
#if 0
for (i = 0;i < 64 ;i++){ /* make for overflow area */
LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,
((double)(EG_ENT<AR_TABLE[i]) * (1000.0 / OPL->rate),
((double)(EG_ENT<DR_TABLE[i]) * (1000.0 / OPL->rate) ));
}
#endif
}
/* ---------- generic table initialize ---------- */
static int OPLOpenTable( void )
{
int s,t;
double rate;
int i,j;
double pom;
/* allocate dynamic tables */
if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL)
return 0;
if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL)
{
free(TL_TABLE);
return 0;
}
if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL)
{
free(TL_TABLE);
free(SIN_TABLE);
return 0;
}
if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL)
{
free(TL_TABLE);
free(SIN_TABLE);
free(AMS_TABLE);
return 0;
}
/* make total level table */
for (t = 0;t < EG_ENT-1 ;t++){
rate = ((1< voltage */
TL_TABLE[ t] = (int)rate;
TL_TABLE[TL_MAX+t] = -TL_TABLE[t];
/* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/
}
/* fill volume off area */
for ( t = EG_ENT-1; t < TL_MAX ;t++){
TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0;
}
/* make sinwave table (total level offet) */
/* degree 0 = degree 180 = off */
SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1];
for (s = 1;s <= SIN_ENT/4;s++){
pom = sin(2*PI*s/SIN_ENT); /* sin */
pom = 20*log10(1/pom); /* decibel */
j = pom / EG_STEP; /* TL_TABLE steps */
/* degree 0 - 90 , degree 180 - 90 : plus section */
SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j];
/* degree 180 - 270 , degree 360 - 270 : minus section */
SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j];
/* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/
}
for (s = 0;s < SIN_ENT;s++)
{
SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT];
SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)];
SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s];
}
/* envelope counter -> envelope output table */
for (i=0; i= EG_ENT ) pom = EG_ENT-1; */
ENV_CURVE[i] = (int)pom;
/* DECAY ,RELEASE curve */
ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i;
}
/* off */
ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1;
/* make LFO ams table */
for (i=0; iSLOT[SLOT1];
OPL_SLOT *slot2 = &CH->SLOT[SLOT2];
/* all key off */
OPL_KEYOFF(slot1);
OPL_KEYOFF(slot2);
/* total level latch */
slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl);
/* key on */
CH->op1_out[0] = CH->op1_out[1] = 0;
OPL_KEYON(slot1);
OPL_KEYON(slot2);
}
/* ---------- opl initialize ---------- */
static void OPL_initalize(FM_OPL *OPL)
{
int fn;
/* frequency base */
OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0;
/* Timer base time */
OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 );
/* make time tables */
init_timetables( OPL , OPL_ARRATE , OPL_DRRATE );
/* make fnumber -> increment counter table */
for( fn=0 ; fn < 1024 ; fn++ )
{
OPL->FN_TABLE[fn] = OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2;
}
/* LFO freq.table */
OPL->amsIncr = OPL->rate ? (double)AMS_ENT*(1<rate * 3.7 * ((double)OPL->clock/3600000) : 0;
OPL->vibIncr = OPL->rate ? (double)VIB_ENT*(1<rate * 6.4 * ((double)OPL->clock/3600000) : 0;
}
/* ---------- write a OPL registers ---------- */
static void OPLWriteReg(FM_OPL *OPL, int r, int v)
{
OPL_CH *CH;
int slot;
int block_fnum;
switch(r&0xe0)
{
case 0x00: /* 00-1f:controll */
switch(r&0x1f)
{
case 0x01:
/* wave selector enable */
if(OPL->type&OPL_TYPE_WAVESEL)
{
OPL->wavesel = v&0x20;
if(!OPL->wavesel)
{
/* preset compatible mode */
int c;
for(c=0;cmax_ch;c++)
{
OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0];
OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0];
}
}
}
return;
case 0x02: /* Timer 1 */
OPL->T[0] = (256-v)*4;
break;
case 0x03: /* Timer 2 */
OPL->T[1] = (256-v)*16;
return;
case 0x04: /* IRQ clear / mask and Timer enable */
if(v&0x80)
{ /* IRQ flag clear */
OPL_STATUS_RESET(OPL,0x7f);
}
else
{ /* set IRQ mask ,timer enable*/
UINT8 st1 = v&1;
UINT8 st2 = (v>>1)&1;
/* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */
OPL_STATUS_RESET(OPL,v&0x78);
OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01);
/* timer 2 */
if(OPL->st[1] != st2)
{
double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0;
OPL->st[1] = st2;
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval);
}
/* timer 1 */
if(OPL->st[0] != st1)
{
double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0;
OPL->st[0] = st1;
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval);
}
}
return;
#if BUILD_Y8950
case 0x06: /* Key Board OUT */
if(OPL->type&OPL_TYPE_KEYBOARD)
{
if(OPL->keyboardhandler_w)
OPL->keyboardhandler_w(OPL->keyboard_param,v);
else
LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n"));
}
return;
case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */
if(OPL->type&OPL_TYPE_ADPCM)
YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
return;
case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */
OPL->mode = v;
v&=0x1f; /* for DELTA-T unit */
case 0x09: /* START ADD */
case 0x0a:
case 0x0b: /* STOP ADD */
case 0x0c:
case 0x0d: /* PRESCALE */
case 0x0e:
case 0x0f: /* ADPCM data */
case 0x10: /* DELTA-N */
case 0x11: /* DELTA-N */
case 0x12: /* EG-CTRL */
if(OPL->type&OPL_TYPE_ADPCM)
YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v);
return;
#if 0
case 0x15: /* DAC data */
case 0x16:
case 0x17: /* SHIFT */
return;
case 0x18: /* I/O CTRL (Direction) */
if(OPL->type&OPL_TYPE_IO)
OPL->portDirection = v&0x0f;
return;
case 0x19: /* I/O DATA */
if(OPL->type&OPL_TYPE_IO)
{
OPL->portLatch = v;
if(OPL->porthandler_w)
OPL->porthandler_w(OPL->port_param,v&OPL->portDirection);
}
return;
case 0x1a: /* PCM data */
return;
#endif
#endif
}
break;
case 0x20: /* am,vib,ksr,eg type,mul */
slot = slot_array[r&0x1f];
if(slot == -1) return;
set_mul(OPL,slot,v);
return;
case 0x40:
slot = slot_array[r&0x1f];
if(slot == -1) return;
set_ksl_tl(OPL,slot,v);
return;
case 0x60:
slot = slot_array[r&0x1f];
if(slot == -1) return;
set_ar_dr(OPL,slot,v);
return;
case 0x80:
slot = slot_array[r&0x1f];
if(slot == -1) return;
set_sl_rr(OPL,slot,v);
return;
case 0xa0:
switch(r)
{
case 0xbd:
/* amsep,vibdep,r,bd,sd,tom,tc,hh */
{
UINT8 rkey = OPL->rythm^v;
OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0];
OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0];
OPL->rythm = v&0x3f;
if(OPL->rythm&0x20)
{
#if 0
usrintf_showmessage("OPL Rythm mode select");
#endif
/* BD key on/off */
if(rkey&0x10)
{
if(v&0x10)
{
OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0;
OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]);
OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]);
}
else
{
OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]);
OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]);
}
}
/* SD key on/off */
if(rkey&0x08)
{
if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]);
else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]);
}/* TAM key on/off */
if(rkey&0x04)
{
if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]);
else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]);
}
/* TOP-CY key on/off */
if(rkey&0x02)
{
if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]);
else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]);
}
/* HH key on/off */
if(rkey&0x01)
{
if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]);
else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]);
}
}
}
return;
}
/* keyon,block,fnum */
if( (r&0x0f) > 8) return;
CH = &OPL->P_CH[r&0x0f];
if(!(r&0x10))
{ /* a0-a8 */
block_fnum = (CH->block_fnum&0x1f00) | v;
}
else
{ /* b0-b8 */
int keyon = (v>>5)&1;
block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff);
if(CH->keyon != keyon)
{
if( (CH->keyon=keyon) )
{
CH->op1_out[0] = CH->op1_out[1] = 0;
OPL_KEYON(&CH->SLOT[SLOT1]);
OPL_KEYON(&CH->SLOT[SLOT2]);
}
else
{
OPL_KEYOFF(&CH->SLOT[SLOT1]);
OPL_KEYOFF(&CH->SLOT[SLOT2]);
}
}
}
/* update */
if(CH->block_fnum != block_fnum)
{
int blockRv = 7-(block_fnum>>10);
int fnum = block_fnum&0x3ff;
CH->block_fnum = block_fnum;
CH->ksl_base = KSL_TABLE[block_fnum>>6];
CH->fc = OPL->FN_TABLE[fnum]>>blockRv;
CH->kcode = CH->block_fnum>>9;
if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1;
CALC_FCSLOT(CH,&CH->SLOT[SLOT1]);
CALC_FCSLOT(CH,&CH->SLOT[SLOT2]);
}
return;
case 0xc0:
/* FB,C */
if( (r&0x0f) > 8) return;
CH = &OPL->P_CH[r&0x0f];
{
int feedback = (v>>1)&7;
CH->FB = feedback ? (8+1) - feedback : 0;
CH->CON = v&1;
set_algorythm(CH);
}
return;
case 0xe0: /* wave type */
slot = slot_array[r&0x1f];
if(slot == -1) return;
CH = &OPL->P_CH[slot/2];
if(OPL->wavesel)
{
/* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */
CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT];
}
return;
}
}
/* lock/unlock for common table */
static int OPL_LockTable(void)
{
num_lock++;
if(num_lock>1) return 0;
/* first time */
cur_chip = NULL;
/* allocate total level table (128kb space) */
if( !OPLOpenTable() )
{
num_lock--;
return -1;
}
return 0;
}
static void OPL_UnLockTable(void)
{
if(num_lock) num_lock--;
if(num_lock) return;
/* last time */
cur_chip = NULL;
OPLCloseTable();
}
#if (BUILD_YM3812 || BUILD_YM3526)
/*******************************************************************************/
/* YM3812 local section */
/*******************************************************************************/
/* ---------- update one of chip ----------- */
void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length)
{
int i;
int data;
OPLSAMPLE *buf = buffer;
UINT32 amsCnt = OPL->amsCnt;
UINT32 vibCnt = OPL->vibCnt;
UINT8 rythm = OPL->rythm&0x20;
OPL_CH *CH,*R_CH;
if( (void *)OPL != cur_chip ){
cur_chip = (void *)OPL;
/* channel pointers */
S_CH = OPL->P_CH;
E_CH = &S_CH[9];
/* rythm slot */
SLOT7_1 = &S_CH[7].SLOT[SLOT1];
SLOT7_2 = &S_CH[7].SLOT[SLOT2];
SLOT8_1 = &S_CH[8].SLOT[SLOT1];
SLOT8_2 = &S_CH[8].SLOT[SLOT2];
/* LFO state */
amsIncr = OPL->amsIncr;
vibIncr = OPL->vibIncr;
ams_table = OPL->ams_table;
vib_table = OPL->vib_table;
}
R_CH = rythm ? &S_CH[6] : E_CH;
for( i=0; i < length ; i++ )
{
/* channel A channel B channel C */
/* LFO */
ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
outd[0] = 0;
/* FM part */
for(CH=S_CH ; CH < R_CH ; CH++)
OPL_CALC_CH(CH);
/* Rythn part */
if(rythm)
OPL_CALC_RH(S_CH);
/* limit check */
data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
/* store to sound buffer */
buf[i] = data >> OPL_OUTSB;
}
OPL->amsCnt = amsCnt;
OPL->vibCnt = vibCnt;
#ifdef OPL_OUTPUT_LOG
if(opl_dbg_fp)
{
for(opl_dbg_chip=0;opl_dbg_chipamsCnt;
UINT32 vibCnt = OPL->vibCnt;
UINT8 rythm = OPL->rythm&0x20;
OPL_CH *CH,*R_CH;
YM_DELTAT *DELTAT = OPL->deltat;
/* setup DELTA-T unit */
YM_DELTAT_DECODE_PRESET(DELTAT);
if( (void *)OPL != cur_chip ){
cur_chip = (void *)OPL;
/* channel pointers */
S_CH = OPL->P_CH;
E_CH = &S_CH[9];
/* rythm slot */
SLOT7_1 = &S_CH[7].SLOT[SLOT1];
SLOT7_2 = &S_CH[7].SLOT[SLOT2];
SLOT8_1 = &S_CH[8].SLOT[SLOT1];
SLOT8_2 = &S_CH[8].SLOT[SLOT2];
/* LFO state */
amsIncr = OPL->amsIncr;
vibIncr = OPL->vibIncr;
ams_table = OPL->ams_table;
vib_table = OPL->vib_table;
}
R_CH = rythm ? &S_CH[6] : E_CH;
for( i=0; i < length ; i++ )
{
/* channel A channel B channel C */
/* LFO */
ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT];
vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT];
outd[0] = 0;
/* deltaT ADPCM */
if( DELTAT->portstate )
YM_DELTAT_ADPCM_CALC(DELTAT);
/* FM part */
for(CH=S_CH ; CH < R_CH ; CH++)
OPL_CALC_CH(CH);
/* Rythn part */
if(rythm)
OPL_CALC_RH(S_CH);
/* limit check */
data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT );
/* store to sound buffer */
buf[i] = data >> OPL_OUTSB;
}
OPL->amsCnt = amsCnt;
OPL->vibCnt = vibCnt;
/* deltaT START flag */
if( !DELTAT->portstate )
OPL->status &= 0xfe;
}
#endif
/* ---------- reset one of chip ---------- */
void OPLResetChip(FM_OPL *OPL)
{
int c,s;
int i;
/* reset chip */
OPL->mode = 0; /* normal mode */
OPL_STATUS_RESET(OPL,0x7f);
/* reset with register write */
OPLWriteReg(OPL,0x01,0); /* wabesel disable */
OPLWriteReg(OPL,0x02,0); /* Timer1 */
OPLWriteReg(OPL,0x03,0); /* Timer2 */
OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */
for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0);
/* reset OPerator paramater */
for( c = 0 ; c < OPL->max_ch ; c++ )
{
OPL_CH *CH = &OPL->P_CH[c];
/* OPL->P_CH[c].PAN = OPN_CENTER; */
for(s = 0 ; s < 2 ; s++ )
{
/* wave table */
CH->SLOT[s].wavetable = &SIN_TABLE[0];
/* CH->SLOT[s].evm = ENV_MOD_RR; */
CH->SLOT[s].evc = EG_OFF;
CH->SLOT[s].eve = EG_OFF+1;
CH->SLOT[s].evs = 0;
}
}
#if BUILD_Y8950
if(OPL->type&OPL_TYPE_ADPCM)
{
YM_DELTAT *DELTAT = OPL->deltat;
DELTAT->freqbase = OPL->freqbase;
DELTAT->output_pointer = outd;
DELTAT->portshift = 5;
DELTAT->output_range = DELTAT_MIXING_LEVEL<P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch;
#if BUILD_Y8950
if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT);
#endif
/* set channel state pointer */
OPL->type = type;
OPL->clock = clock;
OPL->rate = rate;
OPL->max_ch = max_ch;
/* init grobal tables */
OPL_initalize(OPL);
/* reset chip */
OPLResetChip(OPL);
#ifdef OPL_OUTPUT_LOG
if(!opl_dbg_fp)
{
opl_dbg_fp = fopen("opllog.opl","wb");
opl_dbg_maxchip = 0;
}
if(opl_dbg_fp)
{
opl_dbg_opl[opl_dbg_maxchip] = OPL;
fprintf(opl_dbg_fp,"%c%c%c%c%c%c",0x00+opl_dbg_maxchip,
type,
clock&0xff,
(clock/0x100)&0xff,
(clock/0x10000)&0xff,
(clock/0x1000000)&0xff);
opl_dbg_maxchip++;
}
#endif
return OPL;
}
/* ---------- Destroy one of vietual YM3812 ---------- */
void OPLDestroy(FM_OPL *OPL)
{
#ifdef OPL_OUTPUT_LOG
if(opl_dbg_fp)
{
fclose(opl_dbg_fp);
opl_dbg_fp = NULL;
}
#endif
OPL_UnLockTable();
free(OPL);
}
/* ---------- Option handlers ---------- */
void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset)
{
OPL->TimerHandler = TimerHandler;
OPL->TimerParam = channelOffset;
}
void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param)
{
OPL->IRQHandler = IRQHandler;
OPL->IRQParam = param;
}
void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param)
{
OPL->UpdateHandler = UpdateHandler;
OPL->UpdateParam = param;
}
#if BUILD_Y8950
void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param)
{
OPL->porthandler_w = PortHandler_w;
OPL->porthandler_r = PortHandler_r;
OPL->port_param = param;
}
void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param)
{
OPL->keyboardhandler_w = KeyboardHandler_w;
OPL->keyboardhandler_r = KeyboardHandler_r;
OPL->keyboard_param = param;
}
#endif
/* ---------- YM3812 I/O interface ---------- */
int OPLWrite(FM_OPL *OPL,int a,int v)
{
if( !(a&1) )
{ /* address port */
OPL->address = v & 0xff;
}
else
{ /* data port */
if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
#ifdef OPL_OUTPUT_LOG
if(opl_dbg_fp)
{
for(opl_dbg_chip=0;opl_dbg_chipaddress,v);
}
#endif
OPLWriteReg(OPL,OPL->address,v);
}
return OPL->status>>7;
}
unsigned char OPLRead(FM_OPL *OPL,int a)
{
if( !(a&1) )
{ /* status port */
return OPL->status & (OPL->statusmask|0x80);
}
/* data port */
switch(OPL->address)
{
case 0x05: /* KeyBoard IN */
if(OPL->type&OPL_TYPE_KEYBOARD)
{
if(OPL->keyboardhandler_r)
return OPL->keyboardhandler_r(OPL->keyboard_param);
else
LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n"));
}
return 0;
#if 0
case 0x0f: /* ADPCM-DATA */
return 0;
#endif
case 0x19: /* I/O DATA */
if(OPL->type&OPL_TYPE_IO)
{
if(OPL->porthandler_r)
return OPL->porthandler_r(OPL->port_param);
else
LOG(LOG_WAR,("OPL:read unmapped I/O port\n"));
}
return 0;
case 0x1a: /* PCM-DATA */
return 0;
}
return 0;
}
int OPLTimerOver(FM_OPL *OPL,int c)
{
if( c )
{ /* Timer B */
OPL_STATUS_SET(OPL,0x20);
}
else
{ /* Timer A */
OPL_STATUS_SET(OPL,0x40);
/* CSM mode key,TL controll */
if( OPL->mode & 0x80 )
{ /* CSM mode total level latch and auto key on */
int ch;
if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0);
for(ch=0;ch<9;ch++)
CSMKeyControll( &OPL->P_CH[ch] );
}
}
/* reload timer */
if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase);
return OPL->status>>7;
}
adplug-2.2.1+dfsg3/src/dmo.cpp 0000644 0001750 0001750 00000021777 10453035754 015362 0 ustar gregoa gregoa /*
Adplug - Replayer for many OPL2/OPL3 audio file formats.
Copyright (C) 1999 - 2004, 2006 Simon Peter, , et al.
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.1 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 Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
dmo.cpp - TwinTeam loader by Riven the Mage
*/
/*
NOTES:
Panning is ignored.
A WORD ist 16 bits, a DWORD is 32 bits and a BYTE is 8 bits in this context.
*/
#include
#include
#include "dmo.h"
#include "debug.h"
#define LOWORD(l) ((l) & 0xffff)
#define HIWORD(l) ((l) >> 16)
#define LOBYTE(w) ((w) & 0xff)
#define HIBYTE(w) ((w) >> 8)
#define ARRAY_AS_DWORD(a, i) \
((a[i + 3] << 24) + (a[i + 2] << 16) + (a[i + 1] << 8) + a[i])
#define ARRAY_AS_WORD(a, i) ((a[i + 1] << 8) + a[i])
#define CHARP_AS_WORD(p) (((*(p + 1)) << 8) + (*p))
/* -------- Public Methods -------------------------------- */
CPlayer *CdmoLoader::factory(Copl *newopl)
{
return new CdmoLoader(newopl);
}
bool CdmoLoader::load(const std::string &filename, const CFileProvider &fp)
{
int i,j;
binistream *f;
// check header
dmo_unpacker *unpacker = new dmo_unpacker;
unsigned char chkhdr[16];
if(!fp.extension(filename, ".dmo")) return false;
f = fp.open(filename); if(!f) return false;
f->readString((char *)chkhdr, 16);
if (!unpacker->decrypt(chkhdr, 16))
{
delete unpacker;
fp.close(f);
return false;
}
// get file size
long packed_length = fp.filesize(f);
f->seek(0);
unsigned char *packed_module = new unsigned char [packed_length];
// load file
f->readString((char *)packed_module, packed_length);
fp.close(f);
// decrypt
unpacker->decrypt(packed_module,packed_length);
long unpacked_length = 0x2000 * ARRAY_AS_WORD(packed_module, 12);
unsigned char *module = new unsigned char [unpacked_length];
// unpack
if (!unpacker->unpack(packed_module+12,module,unpacked_length))
{
delete unpacker;
delete [] packed_module;
delete [] module;
return false;
}
delete unpacker;
delete [] packed_module;
// "TwinTeam" - signed ?
if (memcmp(module,"TwinTeam Module File""\x0D\x0A",22))
{
delete module;
return false;
}
// load header
binisstream uf(module, unpacked_length);
uf.setFlag(binio::BigEndian, false); uf.setFlag(binio::FloatIEEE);
memset(&header,0,sizeof(s3mheader));
uf.ignore(22); // ignore DMO header ID string
uf.readString(header.name, 28);
uf.ignore(2); // _unk_1
header.ordnum = uf.readInt(2);
header.insnum = uf.readInt(2);
header.patnum = uf.readInt(2);
uf.ignore(2); // _unk_2
header.is = uf.readInt(2);
header.it = uf.readInt(2);
memset(header.chanset,0xFF,32);
for (i=0;i<9;i++)
header.chanset[i] = 0x10 + i;
uf.ignore(32); // ignore panning settings for all 32 channels
// load orders
for(i = 0; i < 256; i++) orders[i] = uf.readInt(1);
orders[header.ordnum] = 0xFF;
// load pattern lengths
unsigned short my_patlen[100];
for(i = 0; i < 100; i++) my_patlen[i] = uf.readInt(2);
// load instruments
for (i = 0; i < header.insnum; i++)
{
memset(&inst[i],0,sizeof(s3minst));
uf.readString(inst[i].name, 28);
inst[i].volume = uf.readInt(1);
inst[i].dsk = uf.readInt(1);
inst[i].c2spd = uf.readInt(4);
inst[i].type = uf.readInt(1);
inst[i].d00 = uf.readInt(1);
inst[i].d01 = uf.readInt(1);
inst[i].d02 = uf.readInt(1);
inst[i].d03 = uf.readInt(1);
inst[i].d04 = uf.readInt(1);
inst[i].d05 = uf.readInt(1);
inst[i].d06 = uf.readInt(1);
inst[i].d07 = uf.readInt(1);
inst[i].d08 = uf.readInt(1);
inst[i].d09 = uf.readInt(1);
inst[i].d0a = uf.readInt(1);
/*
* Originally, riven sets d0b = d0a and ignores 1 byte in the
* stream, but i guess this was a typo, so i read it here.
*/
inst[i].d0b = uf.readInt(1);
}
// load patterns
for (i = 0; i < header.patnum; i++) {
long cur_pos = uf.pos();
for (j = 0; j < 64; j++) {
while (1) {
unsigned char token = uf.readInt(1);
if (!token)
break;
unsigned char chan = token & 31;
// note + instrument ?
if (token & 32) {
unsigned char bufbyte = uf.readInt(1);
pattern[i][j][chan].note = bufbyte & 15;
pattern[i][j][chan].oct = bufbyte >> 4;
pattern[i][j][chan].instrument = uf.readInt(1);
}
// volume ?
if (token & 64)
pattern[i][j][chan].volume = uf.readInt(1);
// command ?
if (token & 128) {
pattern[i][j][chan].command = uf.readInt(1);
pattern[i][j][chan].info = uf.readInt(1);
}
}
}
uf.seek(cur_pos + my_patlen[i]);
}
delete [] module;
rewind(0);
return true;
}
std::string CdmoLoader::gettype()
{
return std::string("TwinTeam (packed S3M)");
}
std::string CdmoLoader::getauthor()
{
/*
All available .DMO modules written by one composer. And because all .DMO
stuff was lost due to hd crash (TwinTeam guys said this), there are
never(?) be another.
*/
return std::string("Benjamin GERARDIN");
}
/* -------- Private Methods ------------------------------- */
unsigned short CdmoLoader::dmo_unpacker::brand(unsigned short range)
{
unsigned short ax,bx,cx,dx;
ax = LOWORD(bseed);
bx = HIWORD(bseed);
cx = ax;
ax = LOWORD(cx * 0x8405);
dx = HIWORD(cx * 0x8405);
cx <<= 3;
cx = (((HIBYTE(cx) + LOBYTE(cx)) & 0xFF) << 8) + LOBYTE(cx);
dx += cx;
dx += bx;
bx <<= 2;
dx += bx;
dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx);
bx <<= 5;
dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx);
ax += 1;
if (!ax) dx += 1;
// leave it that way or amd64 might get it wrong
bseed = dx;
bseed <<= 16;
bseed += ax;
return HIWORD(HIWORD(LOWORD(bseed) * range) + HIWORD(bseed) * range);
}
bool CdmoLoader::dmo_unpacker::decrypt(unsigned char *buf, long len)
{
unsigned long seed = 0;
int i;
bseed = ARRAY_AS_DWORD(buf, 0);
for (i=0; i < ARRAY_AS_WORD(buf, 4) + 1; i++)
seed += brand(0xffff);
bseed = seed ^ ARRAY_AS_DWORD(buf, 6);
if (ARRAY_AS_WORD(buf, 10) != brand(0xffff))
return false;
for (i=0;i<(len-12);i++)
buf[12+i] ^= brand(0x100);
buf[len - 2] = buf[len - 1] = 0;
return true;
}
short CdmoLoader::dmo_unpacker::unpack_block(unsigned char *ibuf, long ilen, unsigned char *obuf)
{
unsigned char code,par1,par2;
unsigned short ax,bx,cx;
unsigned char *ipos = ibuf;
unsigned char *opos = obuf;
// LZ77 child
while (ipos - ibuf < ilen)
{
code = *ipos++;
// 00xxxxxx: copy (xxxxxx + 1) bytes
if ((code >> 6) == 0)
{
cx = (code & 0x3F) + 1;
if(opos + cx >= oend)
return -1;
for (int i=0;i> 6) == 1)
{
par1 = *ipos++;
ax = ((code & 0x3F) << 3) + ((par1 & 0xE0) >> 5) + 1;
cx = (par1 & 0x1F) + 3;
if(opos + cx >= oend)
return -1;
for(int i=0;i> 6) == 2)
{
int i;
par1 = *ipos++;
ax = ((code & 0x3F) << 1) + (par1 >> 7) + 1;
cx = ((par1 & 0x70) >> 4) + 3;
bx = par1 & 0x0F;
if(opos + bx + cx >= oend)
return -1;
for(i=0;i> 6) == 3)
{
int i;
par1 = *ipos++;
par2 = *ipos++;
bx = ((code & 0x3F) << 7) + (par1 >> 1);
cx = ((par1 & 0x01) << 4) + (par2 >> 4) + 4;
ax = par2 & 0x0F;
if(opos + ax + cx >= oend)
return -1;
for(i=0;i